diff --git a/day14/main.hs b/day14/main.hs index 8afe3dc..ed01a18 100755 --- a/day14/main.hs +++ b/day14/main.hs @@ -126,6 +126,72 @@ solvePart1 input = do fullMem = foldMap (runInitBlock I.empty) . reverse -- +-- Part 2 starts by redefining the meaning for the bits in the mask +-- +data BM = BMUnchanged + | BMForceOne + | BMFloating + +instance Show (BM) + where + show BMUnchanged = "⁰" + show BMForceOne = "¹" + show BMFloating = "^" + +type Mask2 = [BM] + +data InitBlock2 = InitBlock2 { unMask2 :: Mask2, unInitLines2 :: [(Addr,Int)] } + deriving Show + +data Program2 = Program2 { unMem2 :: Mem, unInits2 :: [InitBlock2] } + deriving Show + +mkBM :: String -> Mask2 +mkBM xs | length xs == 36 = map go xs + where + go '1' = BMForceOne + go '0' = BMUnchanged + go 'X' = BMFloating + go c = trace ("Illegal char: " <> show c) $ undefined +mkBM xs | otherwise = trace "Mask is not 36 bit long" $ undefined + + +-- We have to redo the parsing side, because we were too specific (gotcha!) +-- +parseMask2 :: Parser Mask2 +parseMask2 = do + maskStr <- "mask = " *> P.take 36 + P.endOfLine + pure $ mkBM $ T.unpack maskStr + +-- mem[x] = y +parseInitLines2 :: Parser (Addr,Int) +parseInitLines2 = do + x <- "mem[" *> P.decimal + y <- "] = " *> P.decimal + P.endOfLine + pure $ (x,y) + +parseBlock2 :: Parser InitBlock2 +parseBlock2 = do + mask <- parseMask2 + ix <- P.many1 parseInitLines + pure $ InitBlock2 mask ix + +parseInput2 :: Parser [InitBlock2] +parseInput2 = do + bx <- P.many1 parseBlock2 + P.endOfInput + pure bx + +applyMask2 :: Mask2 -> Int -> [BM] +applyMask2 xs a = map go (zip xs (showIntAtBase (2::Int) intToDigit a "")) + where + go (BMForceOne ,_ ) = BMForceOne + go (BMUnchanged,'1' ) = BMForceOne + go (BMUnchanged,'0' ) = BMUnchanged + go (BMFloating ,_ ) = BMFloating + go (nb,_) = trace "Invalid char in base 2 number" $ undefined main :: IO () main = do @@ -141,3 +207,7 @@ main = do putStrLn ":: Day 14 - Part 1" print . solvePart1 . T.pack $ exampleData print . solvePart1 $ input + putStrLn ":: Tests - Part 2" + print $ mkBM "000000000000000000000000000000X1001X" + print $ applyMask2 (mkBM "000000000000000000000000000000X1001X") (42::Int) + putStrLn ":: Day 14 - Part 2"