# stefanscheidt's solution

## to Diamond in the PureScript Track

Published at May 27 2019 · 0 comments
Instructions
Test suite
Solution

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····
``````

## Submitting Incomplete Solutions

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

### Main.purs

``````module Test.Main where

import Prelude

import Effect (Effect)
import Test.Unit.Assert as Assert
import Test.Unit (TestSuite, suite, test)
import Test.Unit.Main (runTest)
import Diamond (rows)

main :: Effect Unit
main = runTest suites

suites :: TestSuite
suites = do
suite "Diamond.rows" do

test "Degenerate case with a single 'A' row" \$
Assert.equal   [ "A"
]
(rows 'A')

test "Degenerate case with no row containing 3 distinct groups of spaces" \$
Assert.equal   [ " A "
, "B B"
, " A "
]
(rows 'B')

test "Smallest non-degenerate case with odd diamond side length" \$
Assert.equal   [ "  A  "
, " B B "
, "C   C"
, " B B "
, "  A  "
]
(rows 'C')

test "Smallest non-degenerate case with even diamond side length" \$
Assert.equal   [ "   A   "
, "  B B  "
, " C   C "
, "D     D"
, " C   C "
, "  B B  "
, "   A   "
]
(rows 'D')

test "Largest possible diamond" \$
Assert.equal   [ "                         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                         "
]
(rows 'Z')``````
``````module Diamond where

import Prelude

import Data.Array as A
import Data.Char as Ch
import Data.Enum (enumFromTo)
import Data.String.CodeUnits as CU

rows :: Char -> Array String
rows c =
let
chars = enumFromTo 'A' c :: Array Char
count = A.length chars
upper = map (row count) chars
lower = A.reverse \$ A.take (count - 1) upper
in
A.concat [upper, lower]

row :: Int -> Char -> String
where
position = pos c
padding = spaces (n - 1 - position)
inner = case position of
0 -> CU.singleton c
_ ->  CU.singleton c <> spaces (2 * position - 1) <> CU.singleton c

pos :: Char -> Int
pos c = Ch.toCharCode c - Ch.toCharCode 'A'

spaces :: Int -> String
spaces n = CU.fromCharArray \$ A.replicate n ' '``````