RosettaCodeData/Task/Intersecting-number-wheels/Haskell/intersecting-number-wheels.hs

47 lines
1.2 KiB
Haskell

import Data.Char (isDigit)
import Data.List (mapAccumL)
import qualified Data.Map.Strict as M
import Data.Maybe (fromMaybe)
---------------- INTERSECTING NUMBER WHEELS --------------
clockWorkTick ::
M.Map Char String ->
(M.Map Char String, Char)
clockWorkTick = flip click 'A'
where
click wheels name
| isDigit name = (wheels, name)
| otherwise =
( click
. flip
(M.insert name . leftRotate)
wheels
<*> head
)
$ fromMaybe ['?'] $ M.lookup name wheels
leftRotate :: [a] -> [a]
leftRotate = take . length <*> (tail . cycle)
--------------------------- TEST -------------------------
main :: IO ()
main = do
let wheelSets =
[ [('A', "123")],
[('A', "1B2"), ('B', "34")],
[('A', "1DD"), ('D', "678")],
[('A', "1BC"), ('B', "34"), ('C', "5B")]
]
putStrLn "State of each wheel-set after 20 clicks:\n"
mapM_ print $
fmap
( flip
(mapAccumL (const . clockWorkTick))
(replicate 20 undefined)
. M.fromList
)
wheelSets
putStrLn "\nInitial state of the wheel-sets:\n"
mapM_ print wheelSets