Skip to content

Commit 0103dbb

Browse files
authored
Add diamond exercise (exercism#103)
1 parent a3cfa63 commit 0103dbb

14 files changed

Lines changed: 579 additions & 0 deletions

File tree

config.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -331,6 +331,14 @@
331331
"prerequisites": [],
332332
"difficulty": 4
333333
},
334+
{
335+
"slug": "diamond",
336+
"name": "Diamond",
337+
"uuid": "6e39ef52-ecfe-4ce4-8ed9-4c66bb613fe3",
338+
"practices": [],
339+
"prerequisites": [],
340+
"difficulty": 4
341+
},
334342
{
335343
"slug": "house",
336344
"name": "House",
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Instructions
2+
3+
The diamond kata takes as its input a letter, and outputs it in a diamond shape.
4+
Given a letter, it prints a diamond starting with 'A', with the supplied letter at the widest point.
5+
6+
## Requirements
7+
8+
- The first row contains one 'A'.
9+
- The last row contains one 'A'.
10+
- All rows, except the first and last, have exactly two identical letters.
11+
- All rows have as many trailing spaces as leading spaces. (This might be 0).
12+
- The diamond is horizontally symmetric.
13+
- The diamond is vertically symmetric.
14+
- The diamond has a square shape (width equals height).
15+
- The letters form a diamond shape.
16+
- The top half has the letters in ascending order.
17+
- The bottom half has the letters in descending order.
18+
- The four corners (containing the spaces) are triangles.
19+
20+
## Examples
21+
22+
In the following examples, spaces are indicated by `·` characters.
23+
24+
Diamond for letter 'A':
25+
26+
```text
27+
A
28+
```
29+
30+
Diamond for letter 'C':
31+
32+
```text
33+
··A··
34+
·B·B·
35+
C···C
36+
·B·B·
37+
··A··
38+
```
39+
40+
Diamond for letter 'E':
41+
42+
```text
43+
····A····
44+
···B·B···
45+
··C···C··
46+
·D·····D·
47+
E·······E
48+
·D·····D·
49+
··C···C··
50+
···B·B···
51+
····A····
52+
```
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
namespace Diamond
2+
3+
def row (distance : Nat) : Nat -> String
4+
| 0 => "".pushn ' ' distance ++ "A".pushn ' ' distance --total of 2*distance + 1 for letter
5+
| n + 1 =>
6+
let midPad := 2*n + 1 -- mid padding is 1 for 'B', increasing by 2 for each letter after that
7+
let sidePad := distance - (n + 1) -- each letter reduces side pad by 1
8+
let letter := Char.ofNat $ 'A'.toNat + n + 1
9+
let letterStr := String.singleton letter
10+
"".pushn ' ' sidePad ++ letterStr.pushn ' ' midPad ++ letterStr.pushn ' ' sidePad
11+
12+
def rows (letter : Char) : List String :=
13+
let distance := letter.toNat - 'A'.toNat
14+
--all rows have the same size: 2*distance + 1
15+
if distance = 0
16+
then ["A"]
17+
else
18+
let top := (List.range distance).map (row distance)
19+
let mid := (String.singleton letter).pushn ' ' (2*distance - 1) |>.push letter
20+
top ++ mid :: top.reverse
21+
22+
end Diamond
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"authors": [
3+
"oxe-i"
4+
],
5+
"files": {
6+
"solution": [
7+
"Diamond.lean"
8+
],
9+
"test": [
10+
"DiamondTest.lean"
11+
],
12+
"example": [
13+
".meta/Example.lean"
14+
]
15+
},
16+
"blurb": "Given a letter, print a diamond starting with 'A' with the supplied letter at the widest point.",
17+
"source": "Seb Rose",
18+
"source_url": "https://web.archive.org/web/20220807163751/http://claysnow.co.uk/recycling-tests-in-tdd/"
19+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# This is an auto-generated file.
2+
#
3+
# Regenerating this file via `configlet sync` will:
4+
# - Recreate every `description` key/value pair
5+
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
6+
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
7+
# - Preserve any other key/value pair
8+
#
9+
# As user-added comments (using the # character) will be removed when this file
10+
# is regenerated, comments can be added via a `comment` key.
11+
12+
[202fb4cc-6a38-4883-9193-a29d5cb92076]
13+
description = "Degenerate case with a single 'A' row"
14+
15+
[bd6a6d78-9302-42e9-8f60-ac1461e9abae]
16+
description = "Degenerate case with no row containing 3 distinct groups of spaces"
17+
18+
[af8efb49-14ed-447f-8944-4cc59ce3fd76]
19+
description = "Smallest non-degenerate case with odd diamond side length"
20+
21+
[e0c19a95-9888-4d05-86a0-fa81b9e70d1d]
22+
description = "Smallest non-degenerate case with even diamond side length"
23+
24+
[82ea9aa9-4c0e-442a-b07e-40204e925944]
25+
description = "Largest possible diamond"
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
namespace Diamond
2+
3+
def rows (letter : Char) : List String :=
4+
sorry
5+
6+
end Diamond
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
import LeanTest
2+
import Diamond
3+
4+
open LeanTest
5+
6+
def diamondTests : TestSuite :=
7+
(TestSuite.empty "Diamond")
8+
|>.addTest "Degenerate case with a single 'A' row" (do
9+
return assertEqual [
10+
"A"
11+
] (Diamond.rows 'A'))
12+
|>.addTest "Degenerate case with no row containing 3 distinct groups of spaces" (do
13+
return assertEqual [
14+
" A ",
15+
"B B",
16+
" A "
17+
] (Diamond.rows 'B'))
18+
|>.addTest "Smallest non-degenerate case with odd diamond side length" (do
19+
return assertEqual [
20+
" A ",
21+
" B B ",
22+
"C C",
23+
" B B ",
24+
" A "
25+
] (Diamond.rows 'C'))
26+
|>.addTest "Smallest non-degenerate case with even diamond side length" (do
27+
return assertEqual [
28+
" A ",
29+
" B B ",
30+
" C C ",
31+
"D D",
32+
" C C ",
33+
" B B ",
34+
" A "
35+
] (Diamond.rows 'D'))
36+
|>.addTest "Largest possible diamond" (do
37+
return assertEqual [
38+
" A ",
39+
" B B ",
40+
" C C ",
41+
" D D ",
42+
" E E ",
43+
" F F ",
44+
" G G ",
45+
" H H ",
46+
" I I ",
47+
" J J ",
48+
" K K ",
49+
" L L ",
50+
" M M ",
51+
" N N ",
52+
" O O ",
53+
" P P ",
54+
" Q Q ",
55+
" R R ",
56+
" S S ",
57+
" T T ",
58+
" U U ",
59+
" V V ",
60+
" W W ",
61+
" X X ",
62+
" Y Y ",
63+
"Z Z",
64+
" Y Y ",
65+
" X X ",
66+
" W W ",
67+
" V V ",
68+
" U U ",
69+
" T T ",
70+
" S S ",
71+
" R R ",
72+
" Q Q ",
73+
" P P ",
74+
" O O ",
75+
" N N ",
76+
" M M ",
77+
" L L ",
78+
" K K ",
79+
" J J ",
80+
" I I ",
81+
" H H ",
82+
" G G ",
83+
" F F ",
84+
" E E ",
85+
" D D ",
86+
" C C ",
87+
" B B ",
88+
" A "
89+
] (Diamond.rows 'Z'))
90+
91+
def main : IO UInt32 := do
92+
runTestSuitesWithExitCode [diamondTests]
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name = "diamond"
2+
version = "0.1.0"
3+
defaultTargets = ["DiamondTest"]
4+
testDriver = "DiamondTest"
5+
6+
[[lean_lib]]
7+
name = "LeanTest"
8+
srcDir = "vendor/LeanTest"
9+
10+
[[lean_lib]]
11+
name = "Diamond"
12+
13+
[[lean_exe]]
14+
name = "DiamondTest"
15+
root = "DiamondTest"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
leanprover/lean4:v4.25.2
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-- This module serves as the root of the `LeanTest` library.
2+
-- Import modules here that should be built as part of the library.
3+
import LeanTest.Assertions
4+
import LeanTest.Test

0 commit comments

Comments
 (0)