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