47 lines
1.2 KiB
Haskell
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
|