 # ozan's solution

## to Diamond in the C Track

Published at Jan 09 2019 · 0 comments
Instructions
Test suite
Solution

#### Note:

This exercise has changed since this solution was written.

The diamond kata takes as its input a letter, and outputs it in a diamond shape. Given a letter, it prints a diamond starting with 'A', with the supplied letter at the widest point.

## Requirements

• The first row contains one 'A'.
• The last row contains one 'A'.
• All rows, except the first and last, have exactly two identical letters.
• All rows have as many trailing spaces as leading spaces. (This might be 0).
• The diamond is horizontally symmetric.
• The diamond is vertically symmetric.
• The diamond has a square shape (width equals height).
• The letters form a diamond shape.
• The top half has the letters in ascending order.
• The bottom half has the letters in descending order.
• The four corners (containing the spaces) are triangles.

## Examples

In the following examples, spaces are indicated by `·` characters.

Diamond for letter 'A':

``````A
``````

Diamond for letter 'C':

``````··A··
·B·B·
C···C
·B·B·
··A··
``````

Diamond for letter 'E':

``````····A····
···B·B···
··C···C··
·D·····D·
E·······E
·D·····D·
··C···C··
···B·B···
····A····
``````

## Getting Started

Make sure you have read the C page on the Exercism site. This covers the basic information on setting up the development environment expected by the exercises.

## Passing the Tests

Get the first test compiling, linking and passing by following the three rules of test-driven development.

The included makefile can be used to create and run the tests using the `test` task.

``````make test
``````

Create just the functions you need to satisfy any compiler errors and get the test to fail. Then write just enough code to get the test to pass. Once you've done that, move onto the next test.

As you progress through the tests, take the time to refactor your implementation for readability and expressiveness and then go on to the next test.

Try to use standard C99 facilities in preference to writing your own low-level algorithms or facilities by hand.

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### test_diamond.c

``````#include "vendor/unity.h"
#include "../src/diamond.h"
#include <stdlib.h>

#define ARRAY_SIZE(arr) (sizeof(arr)/sizeof(arr))

void setUp(void)
{
}

void tearDown(void)
{
}

static void free_all(char **diamond)
{
free(diamond);
free(diamond);
}

void test_rows_degenerate_case_with_a_single_a_row(void)
{
const char letter = 'A';
const char *expected[] = {
"A"
};
char **diamond = make_diamond(letter);
TEST_ASSERT_EQUAL_STRING_ARRAY(expected, diamond, ARRAY_SIZE(expected));
free_all(diamond);
}

void
test_rows_degenerate_case_with_no_row_with_3_distinct_groups_of_spaces(void)
{
TEST_IGNORE();               // delete this line to run test
const char letter = 'B';
const char *expected[] = {
" A ",
"B B",
" A "
};
char **diamond = make_diamond(letter);
TEST_ASSERT_EQUAL_STRING_ARRAY(expected, diamond, ARRAY_SIZE(expected));
free_all(diamond);
}

void test_rows_smallest_non_degenerate_case_with_odd_diamond_side_length(void)
{
TEST_IGNORE();
const char letter = 'C';
const char *expected[] = {
"  A  ",
" B B ",
"C   C",
" B B ",
"  A  "
};
char **diamond = make_diamond(letter);
TEST_ASSERT_EQUAL_STRING_ARRAY(expected, diamond, ARRAY_SIZE(expected));
free_all(diamond);
}

void test_rows_smallest_non_degenerate_case_with_even_diamond_side_length(void)
{
TEST_IGNORE();
const char letter = 'D';
const char *expected[] = {
"   A   ",
"  B B  ",
" C   C ",
"D     D",
" C   C ",
"  B B  ",
"   A   "
};
char **diamond = make_diamond(letter);
TEST_ASSERT_EQUAL_STRING_ARRAY(expected, diamond, ARRAY_SIZE(expected));
free_all(diamond);
}

void test_rows_largest_possible_diamond(void)
{
TEST_IGNORE();
const char letter = 'Z';
const char *expected[] = {
"                         A                         ",
"                        B B                        ",
"                       C   C                       ",
"                      D     D                      ",
"                     E       E                     ",
"                    F         F                    ",
"                   G           G                   ",
"                  H             H                  ",
"                 I               I                 ",
"                J                 J                ",
"               K                   K               ",
"              L                     L              ",
"             M                       M             ",
"            N                         N            ",
"           O                           O           ",
"          P                             P          ",
"         Q                               Q         ",
"        R                                 R        ",
"       S                                   S       ",
"      T                                     T      ",
"     U                                       U     ",
"    V                                         V    ",
"   W                                           W   ",
"  X                                             X  ",
" Y                                               Y ",
"Z                                                 Z",
" Y                                               Y ",
"  X                                             X  ",
"   W                                           W   ",
"    V                                         V    ",
"     U                                       U     ",
"      T                                     T      ",
"       S                                   S       ",
"        R                                 R        ",
"         Q                               Q         ",
"          P                             P          ",
"           O                           O           ",
"            N                         N            ",
"             M                       M             ",
"              L                     L              ",
"               K                   K               ",
"                J                 J                ",
"                 I               I                 ",
"                  H             H                  ",
"                   G           G                   ",
"                    F         F                    ",
"                     E       E                     ",
"                      D     D                      ",
"                       C   C                       ",
"                        B B                        ",
"                         A                         "
};
char **diamond = make_diamond(letter);
TEST_ASSERT_EQUAL_STRING_ARRAY(expected, diamond, ARRAY_SIZE(expected));
free_all(diamond);
}

int main(void)
{
UnityBegin("test/test_diamond.c");

RUN_TEST(test_rows_degenerate_case_with_a_single_a_row);
RUN_TEST
(test_rows_degenerate_case_with_no_row_with_3_distinct_groups_of_spaces);
RUN_TEST
(test_rows_smallest_non_degenerate_case_with_odd_diamond_side_length);
RUN_TEST
(test_rows_smallest_non_degenerate_case_with_even_diamond_side_length);
RUN_TEST(test_rows_largest_possible_diamond);

UnityEnd();
return 0;
}``````

### src/diamond.c

``````#include <stdlib.h>
#include "diamond.h"

char **make_diamond(char letter) {
int n = letter - 'A', nn = 2 * n, i, j;
char c;
char **diamond = malloc((nn + 1) * sizeof(char *));

// Allocate all of the strings
for (i = 0; i <= nn; i++) {
diamond[i] = malloc(nn + 2);
diamond[i][nn + 1] = '\0';
}

// Iterate over the top left quarter of the diamond, and set as many as
// 4 identical values, by horizontal and vertical symmetry
for (i = 0; i <= n; i++) {
for (j = 0; j <= n; j++) {
c = i + j == n ? 'A' + i : ' ';
diamond[i][j] = c;
diamond[i][nn - j] = c;
diamond[nn - i][j] = c;
diamond[nn - i][nn - j] = c;
}
}
return diamond;
}``````

### src/diamond.h

``char** make_diamond(char letter);``