Skip to content

Commit

Permalink
Add diamond exercise (#339)
Browse files Browse the repository at this point in the history
  • Loading branch information
ErikSchierboom authored Mar 10, 2024
1 parent a841791 commit 22e7d4a
Show file tree
Hide file tree
Showing 7 changed files with 231 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,14 @@
"practices": [],
"prerequisites": [],
"difficulty": 1
},
{
"slug": "diamond",
"name": "Diamond",
"uuid": "da84b979-4cba-494c-8f45-52f1c756a96c",
"practices": [],
"prerequisites": [],
"difficulty": 1
}
]
},
Expand Down
52 changes: 52 additions & 0 deletions exercises/practice/diamond/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Instructions

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':

```text
A
```

Diamond for letter 'C':

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

Diamond for letter 'E':

```text
····A····
···B·B···
··C···C··
·D·····D·
E·······E
·D·····D·
··C···C··
···B·B···
····A····
```
19 changes: 19 additions & 0 deletions exercises/practice/diamond/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"erikschierboom"
],
"files": {
"solution": [
"diamond.pl"
],
"test": [
"diamond_tests.plt"
],
"example": [
".meta/diamond.example.pl"
]
},
"blurb": "Given a letter, print a diamond starting with 'A' with the supplied letter at the widest point.",
"source": "Seb Rose",
"source_url": "https://web.archive.org/web/20220807163751/http://claysnow.co.uk/recycling-tests-in-tdd/"
}
27 changes: 27 additions & 0 deletions exercises/practice/diamond/.meta/diamond.example.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
:- use_module(library(clpfd)).

letters(Letters) :- string_chars("ABCDEFGHIJKLMNOPQRSTUVWXYZ", Letters).

letter_index(Letter, Index) :-
letters(Letters),
nth1(Index, Letters, Letter), !.

diamond(Letter, Rows) :-
top_half(Letter, TopHalf),
reverse(TopHalf, [_|BottomHalf]),
append(TopHalf, BottomHalf, Rows).

top_half(Letter, TopHalf) :-
letters(Letters),
letter_index(Letter, NumberOfLetters),
append(TopHalfLetters, _, Letters),
length(TopHalfLetters, NumberOfLetters),
maplist(top_row(NumberOfLetters), TopHalfLetters, TopHalf), !.

top_row(NumberOfLetters, Letter, Row) :-
letter_index(Letter, LetterIdx),
Width #= NumberOfLetters * 2 - 1,
FirstLetterIdx #= NumberOfLetters - LetterIdx + 1,
SecondLetterIdx #= NumberOfLetters + LetterIdx - 1,
findall(C, (between(1, Width, I), (I == FirstLetterIdx -> C = Letter; I == SecondLetterIdx -> C = Letter; C = ' ')), Chars),
string_chars(Row, Chars).
25 changes: 25 additions & 0 deletions exercises/practice/diamond/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[202fb4cc-6a38-4883-9193-a29d5cb92076]
description = "Degenerate case with a single 'A' row"

[bd6a6d78-9302-42e9-8f60-ac1461e9abae]
description = "Degenerate case with no row containing 3 distinct groups of spaces"

[af8efb49-14ed-447f-8944-4cc59ce3fd76]
description = "Smallest non-degenerate case with odd diamond side length"

[e0c19a95-9888-4d05-86a0-fa81b9e70d1d]
description = "Smallest non-degenerate case with even diamond side length"

[82ea9aa9-4c0e-442a-b07e-40204e925944]
description = "Largest possible diamond"
1 change: 1 addition & 0 deletions exercises/practice/diamond/diamond.pl
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
diamond(Letter, Rows).
99 changes: 99 additions & 0 deletions exercises/practice/diamond/diamond_tests.plt
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
pending :-
current_prolog_flag(argv, ['--all'|_]).
pending :-
write('\nA TEST IS PENDING!\n'),
fail.

:- begin_tests(diamond).

test(degenerate_case_with_a_single_a_row, condition(true)) :-
diamond('A', Rows),
Rows == ["A"].

test(degenerate_case_with_no_row_containing_3_distinct_groups_of_spaces, condition(pending)) :-
diamond('B', Rows),
Rows == [
" A ",
"B B",
" A "
].

test(smallest_non_degenerate_case_with_odd_diamond_side_length, condition(pending)) :-
diamond('C', Rows),
Rows == [
" A ",
" B B ",
"C C",
" B B ",
" A "
].

test(smallest_non_degenerate_case_with_even_diamond_side_length, condition(pending)) :-
diamond('D', Rows),
Rows == [
" A ",
" B B ",
" C C ",
"D D",
" C C ",
" B B ",
" A "
].

test(largest_possible_diamond, condition(pending)) :-
diamond('Z', Rows),
Rows == [
" 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 "
].

:- end_tests(diamond).

0 comments on commit 22e7d4a

Please sign in to comment.