14.1
[aoc20.git] / 14 / one.icl
1 module one
2
3 import StdEnv
4 import Text
5 import Data.Func
6 import Data.List
7 from Data.Map import :: Map(..)
8 import qualified Data.Map as DM
9
10 read :: *File -> [Char]
11 read f
12 # (ok, c, f) = freadc f
13 | not ok = []
14 = [c:read f]
15
16 Start w
17 # (io, w) = stdio w
18 # ls = split ['\n'] $ read io
19 = (sum $ 'DM'.elems $ one [] ls 'DM'.newMap)
20
21 toBin :: (Int -> [Char])
22 toBin = tob [35,34..0]
23 where
24 tob [b:bs] n
25 | n >= 2^b = ['1':tob bs (n-2^b)]
26 = ['0':tob bs n]
27 tob [] _ = []
28 fromBin :: ([Char] -> Int)
29 fromBin = foldr (\a b->a+2*b) 0 o map digitToInt
30
31 one :: [Char] [[Char]] -> ((Map Int Int) -> Map Int Int)
32 one _ [['mask = ':mask]:xs] = one mask xs
33 one mask [['mem[':rest]:xs]
34 = case span isDigit rest of
35 (num, ['] = ':rest])
36 = one mask xs o 'DM'.put (toInt $ toString num)
37 (fromBin $ zipWith msk mask $ toBin $ toInt $ toString rest)
38 where
39 msk :: Char Char -> Char
40 msk '1' _ = '1'
41 msk '0' _ = '0'
42 msk 'X' c = c
43 one mask [[]:xs] = one mask xs
44 one mask [] = id