14
authorMart Lubbers <mart@martlubbers.net>
Mon, 14 Dec 2020 08:32:50 +0000 (09:32 +0100)
committerMart Lubbers <mart@martlubbers.net>
Mon, 14 Dec 2020 08:33:34 +0000 (09:33 +0100)
14/input2 [new file with mode: 0644]
14/input3 [new file with mode: 0644]
14/one.icl

diff --git a/14/input2 b/14/input2
new file mode 100644 (file)
index 0000000..e15150a
--- /dev/null
+++ b/14/input2
@@ -0,0 +1,4 @@
+mask = XXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXX0X
+mem[8] = 11
+mem[7] = 101
+mem[8] = 0
diff --git a/14/input3 b/14/input3
new file mode 100644 (file)
index 0000000..2e961e3
--- /dev/null
+++ b/14/input3
@@ -0,0 +1,4 @@
+mask = 000000000000000000000000000000X1001X
+mem[42] = 100
+mask = 00000000000000000000000000000000X0XX
+mem[26] = 1
index 54f7cd0..ceb0b18 100644 (file)
@@ -16,7 +16,9 @@ read f
 Start w
        # (io, w) = stdio w
        # ls = split ['\n'] $ read io
-       = (sum $ 'DM'.elems $ one [] ls 'DM'.newMap)
+       = ( sum $ 'DM'.elems $ one [] ls 'DM'.newMap
+         , sum $ 'DM'.elems $ two [] ls 'DM'.newMap
+         )
 
 toBin :: (Int -> [Char])
 toBin = tob [35,34..0]
@@ -25,8 +27,8 @@ where
                | n >= 2^b = ['1':tob bs (n-2^b)]
                           = ['0':tob bs n]
        tob [] _ = []
-fromBin :: ([Char] -> Int)
-fromBin = foldr (\a b->a+2*b) 0 o map digitToInt
+fromBin :: [Char] -> Int
+fromBin rs= sum [n*2^i\\i<-[35,34..] & n <- map digitToInt rs]
 
 one :: [Char] [[Char]] -> ((Map Int Int) -> Map Int Int)
 one _ [['mask = ':mask]:xs] = one mask xs
@@ -42,3 +44,24 @@ where
        msk 'X' c = c
 one mask [[]:xs] = one mask xs
 one mask [] = id
+
+two :: [Char] [[Char]] -> ((Map Int Int) -> Map Int Int)
+two _ [['mask = ':mask]:xs] = two mask xs
+two mask [['mem[':rest]:xs]
+       = case span isDigit rest of
+               (addr, ['] = ':val])
+                       = foldl (o) (two mask xs)
+                               [ 'DM'.put (fromBin addr) $ toInt $ toString val
+                               \\addr<-mkAddrs $ zipWith aMask mask $ toBin $ toInt $ toString addr]
+where
+       aMask :: Char Char -> Char
+       aMask 'X' _ = 'X'
+       aMask '1' _ = '1'
+       aMask '0' c = c
+
+       mkAddrs :: [Char] -> [[Char]]
+       mkAddrs ['X':msk] = mkAddrs ['1':msk] ++ mkAddrs ['0':msk]
+       mkAddrs [c:msk] = map (\x->[c:x]) $ mkAddrs msk
+       mkAddrs [] = [[]]
+two mask [[]:xs] = two mask xs
+two mask [] = id