1
exercism fetch haskell alphametics

test/Tests.hs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
{-# LANGUAGE RecordWildCards #-}

import Data.Foldable     (for_)
import Data.Function     (on)
import Data.List         (sort)
import Test.Hspec        (Spec, describe, it, shouldBe)
import Test.Hspec.Runner (configFastFail, defaultConfig, hspecWith)

import Alphametics (solve)

main :: IO ()
main = hspecWith defaultConfig {configFastFail = True} specs

specs :: Spec
specs = describe "solve" $ for_ cases test
  where

    test Case{..} = it description assertion
      where
        shouldMatchSolution = shouldBe `on` fmap sort
        assertion = solve puzzle `shouldMatchSolution` expected

data Case = Case { description :: String
                 , puzzle      :: String
                 , expected    :: Maybe[(Char, Int)]
                 }

cases :: [Case]
cases = [ Case { description = "puzzle with three letters"
               , puzzle      = "I + BB == ILL"
               , expected    = Just [('I', 1), ('B', 9), ('L', 0)]
               }
        , Case { description = "solution must have unique value for each letter"
               , puzzle      = "A == B"
               , expected    = Nothing
               }
        , Case { description = "leading zero solution is invalid"
               , puzzle      = "ACA + DD == BD"
               , expected    = Nothing
               }
        , Case { description = "puzzle with four letters"
               , puzzle      = "AS + A == MOM"
               , expected    = Just [('A', 9), ('S', 2), ('M', 1), ('O', 0)]
               }
        , Case { description = "puzzle with six letters"
               , puzzle      = "NO + NO + TOO == LATE"
               , expected    = Just [('N', 7), ('O', 4), ('T', 9), ('L', 1),
                                      ('A', 0), ('E', 2)]
               }
        , Case { description = "puzzle with seven letters"
               , puzzle      = "HE + SEES + THE == LIGHT"
               , expected    = Just [('E', 4), ('G', 2), ('H', 5), ('I', 0),
                                      ('L', 1), ('S', 9), ('T', 7)]
               }
        , Case { description = "puzzle with eight letters"
               , puzzle      = "SEND + MORE == MONEY"
               , expected    = Just [('S', 9), ('E', 5), ('N', 6), ('D', 7), ('M', 1),
                                      ('O', 0), ('R', 8), ('Y', 2)]
               }
        -- some more (and more demanding) tests
--        , Case { description  = "puzzle with ten letters"
--               , puzzle       = "AND + A + STRONG + OFFENSE + AS + A + GOOD == DEFENSE"
--               , expected     = Just [('A', 5), ('D', 3), ('E', 4), ('F', 7), ('G', 8),
--                                      ('N', 0), ('O', 2), ('R', 1), ('S', 6), ('T', 9)]
--               }
--        , Case { description  = "puzzle with multiplication"
--               , puzzle       = "IF * DR == DORI"
--               , expected     = Just [('I', 8), ('F', 2), ('D', 3), ('R', 9), ('O', 1)]
--               }
--        , Case { description  = "puzzle with exponents"
--               , puzzle       = "PI * R ^ 2 == AREA"
--               , expected     = Just [('P', 9), ('I', 6), ('R', 7), ('A', 4), ('E', 0)]
--               }
        ]