data Bit = Zero | One
type Mask = [Maybe Bit]
data State = St
{ getMemory :: M.Map Integer [Bit],
map indiv
where
indiv 'X' = Nothing
indiv '1' = Just One
indiv '0' = Just Zero
zipWith maskBit
where
maskBit Nothing x = x
maskBit (Just y) _ = y
leftpad 36 . reverse . go
where
go 0 = []
go n = (if n `mod` 2 == 1 then One else Zero) : go (n `div` 2)
leftpad m xs = replicate (m - length xs) Zero ++ xs
go . reverse
where
go [] = 0
go (Zero : xs) = 2 * go xs
go (One : xs) = 1 + 2 * go xs
case words s of
"mask" : "=" : rest -> St mem (parseMask $ concat rest)
('m' : 'e' : 'm' : '[' : num) : "=" : rest ->
let index = read $ take (length num - 1) num
n = intToBits $ read $ concat $ rest
mem' = M.insert index (applyMask mask n) mem
in St mem' mask
_ -> undefined
M.foldr ((+) . bitsToInt) 0
. getMemory
. foldl runInstr (St M.empty (replicate 36 Nothing))
. lines
map bitsToInt . foldr (liftA2 (:)) [[]] . zipWith maskBit m
where
maskBit Nothing _ = [Zero, One]
maskBit (Just One) _ = [One]
maskBit (Just Zero) n = [n]
case words s of
"mask" : "=" : rest -> St mem (parseMask $ concat rest)
('m' : 'e' : 'm' : '[' : num) : "=" : rest ->
let index = intToBits $ read $ take (length num - 1) num
indices = applyMaskV2 mask index
n = intToBits $ read $ concat $ rest
mem' = foldr (flip M.insert n) mem indices
in St mem' mask
_ -> undefined
M.foldr ((+) . bitsToInt) 0
. getMemory
. foldl runInstrV2 (St M.empty (replicate 36 Nothing))
. lines