From 22e7d4a30e6ed1b1f2ebd2544ff5155a91d5b35b Mon Sep 17 00:00:00 2001 From: Erik Schierboom Date: Sun, 10 Mar 2024 18:21:52 +0100 Subject: [PATCH] Add `diamond` exercise (#339) --- config.json | 8 ++ .../practice/diamond/.docs/instructions.md | 52 ++++++++++ exercises/practice/diamond/.meta/config.json | 19 ++++ .../practice/diamond/.meta/diamond.example.pl | 27 +++++ exercises/practice/diamond/.meta/tests.toml | 25 +++++ exercises/practice/diamond/diamond.pl | 1 + exercises/practice/diamond/diamond_tests.plt | 99 +++++++++++++++++++ 7 files changed, 231 insertions(+) create mode 100644 exercises/practice/diamond/.docs/instructions.md create mode 100644 exercises/practice/diamond/.meta/config.json create mode 100644 exercises/practice/diamond/.meta/diamond.example.pl create mode 100644 exercises/practice/diamond/.meta/tests.toml create mode 100644 exercises/practice/diamond/diamond.pl create mode 100644 exercises/practice/diamond/diamond_tests.plt diff --git a/config.json b/config.json index e0164402..de0c45d8 100644 --- a/config.json +++ b/config.json @@ -437,6 +437,14 @@ "practices": [], "prerequisites": [], "difficulty": 1 + }, + { + "slug": "diamond", + "name": "Diamond", + "uuid": "da84b979-4cba-494c-8f45-52f1c756a96c", + "practices": [], + "prerequisites": [], + "difficulty": 1 } ] }, diff --git a/exercises/practice/diamond/.docs/instructions.md b/exercises/practice/diamond/.docs/instructions.md new file mode 100644 index 00000000..3034802f --- /dev/null +++ b/exercises/practice/diamond/.docs/instructions.md @@ -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···· +``` diff --git a/exercises/practice/diamond/.meta/config.json b/exercises/practice/diamond/.meta/config.json new file mode 100644 index 00000000..91bc2dfe --- /dev/null +++ b/exercises/practice/diamond/.meta/config.json @@ -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/" +} diff --git a/exercises/practice/diamond/.meta/diamond.example.pl b/exercises/practice/diamond/.meta/diamond.example.pl new file mode 100644 index 00000000..ed34eeeb --- /dev/null +++ b/exercises/practice/diamond/.meta/diamond.example.pl @@ -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). diff --git a/exercises/practice/diamond/.meta/tests.toml b/exercises/practice/diamond/.meta/tests.toml new file mode 100644 index 00000000..4e7802ec --- /dev/null +++ b/exercises/practice/diamond/.meta/tests.toml @@ -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" diff --git a/exercises/practice/diamond/diamond.pl b/exercises/practice/diamond/diamond.pl new file mode 100644 index 00000000..8b6c131d --- /dev/null +++ b/exercises/practice/diamond/diamond.pl @@ -0,0 +1 @@ +diamond(Letter, Rows). diff --git a/exercises/practice/diamond/diamond_tests.plt b/exercises/practice/diamond/diamond_tests.plt new file mode 100644 index 00000000..1d5b8f36 --- /dev/null +++ b/exercises/practice/diamond/diamond_tests.plt @@ -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).