[hs] Solve 2020_14 part 1
This commit is contained in:
parent
82297cd5f2
commit
adb548def2
2 changed files with 73 additions and 0 deletions
|
|
@ -16,6 +16,7 @@ import qualified Aoc.Y2020.D10 as D10
|
||||||
import qualified Aoc.Y2020.D11 as D11
|
import qualified Aoc.Y2020.D11 as D11
|
||||||
import qualified Aoc.Y2020.D12 as D12
|
import qualified Aoc.Y2020.D12 as D12
|
||||||
import qualified Aoc.Y2020.D13 as D13
|
import qualified Aoc.Y2020.D13 as D13
|
||||||
|
import qualified Aoc.Y2020.D14 as D14
|
||||||
|
|
||||||
year :: Year
|
year :: Year
|
||||||
year = Year 2020
|
year = Year 2020
|
||||||
|
|
@ -32,4 +33,5 @@ year = Year 2020
|
||||||
, (11, D11.day)
|
, (11, D11.day)
|
||||||
, (12, D12.day)
|
, (12, D12.day)
|
||||||
, (13, D13.day)
|
, (13, D13.day)
|
||||||
|
, (14, D14.day)
|
||||||
]
|
]
|
||||||
|
|
|
||||||
71
hs/src/Aoc/Y2020/D14.hs
Normal file
71
hs/src/Aoc/Y2020/D14.hs
Normal file
|
|
@ -0,0 +1,71 @@
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
|
||||||
|
module Aoc.Y2020.D14
|
||||||
|
( day
|
||||||
|
) where
|
||||||
|
|
||||||
|
import Control.Monad
|
||||||
|
import Data.List
|
||||||
|
|
||||||
|
import qualified Data.Map as Map
|
||||||
|
|
||||||
|
import Aoc.Day
|
||||||
|
import Aoc.Parse
|
||||||
|
|
||||||
|
data Instr
|
||||||
|
= Mask [Maybe Bool]
|
||||||
|
| Set Int Int
|
||||||
|
|
||||||
|
parser :: Parser [Instr]
|
||||||
|
parser = manyLines (pMask <|> pSet)
|
||||||
|
where
|
||||||
|
pMask = do
|
||||||
|
void $ string "mask = "
|
||||||
|
bits <- sequenceA $ replicate 36 $ (Nothing <$ char 'X') <|> (Just False <$ char '0') <|> (Just True <$ char '1')
|
||||||
|
pure $ Mask $ reverse bits -- Most significant first
|
||||||
|
pSet = do
|
||||||
|
void $ string "mem["
|
||||||
|
addr <- decimal
|
||||||
|
void $ string "] = "
|
||||||
|
Set addr <$> decimal
|
||||||
|
|
||||||
|
digits :: Int -> [Bool]
|
||||||
|
digits = map odd . iterate (`div` 2)
|
||||||
|
|
||||||
|
mask :: [Maybe Bool] -> Int -> [Bool]
|
||||||
|
mask m n = zipWith maskBit m $ digits n
|
||||||
|
where
|
||||||
|
maskBit Nothing = id
|
||||||
|
maskBit (Just a) = const a
|
||||||
|
|
||||||
|
data Mem = Mem
|
||||||
|
{ mMask :: [Maybe Bool]
|
||||||
|
, mMem :: Map.Map Int [Bool]
|
||||||
|
} deriving (Show)
|
||||||
|
|
||||||
|
newMem :: Mem
|
||||||
|
newMem = Mem{mMask = replicate 36 Nothing, mMem = Map.empty}
|
||||||
|
|
||||||
|
setMask :: [Maybe Bool] -> Mem -> Mem
|
||||||
|
setMask m mem = mem{mMask = m}
|
||||||
|
|
||||||
|
setMem :: Int -> Int -> Mem -> Mem
|
||||||
|
setMem addr val mem = mem{mMem = Map.insert addr masked $ mMem mem}
|
||||||
|
where
|
||||||
|
masked = mask (mMask mem) val
|
||||||
|
|
||||||
|
doInstr :: Instr -> Mem -> Mem
|
||||||
|
doInstr (Mask m) = setMask m
|
||||||
|
doInstr (Set addr val) = setMem addr val
|
||||||
|
|
||||||
|
value :: [Bool] -> Int
|
||||||
|
value = sum . map fst . filter snd . zip (iterate (*2) 1)
|
||||||
|
|
||||||
|
solver :: [Instr] -> IO ()
|
||||||
|
solver instrs = do
|
||||||
|
putStrLn ">> Part 1"
|
||||||
|
let mem = foldl' (flip doInstr) newMem instrs
|
||||||
|
print $ sum $ map value $ Map.elems $ mMem mem
|
||||||
|
|
||||||
|
day :: Day
|
||||||
|
day = dayParse parser solver
|
||||||
Loading…
Add table
Add a link
Reference in a new issue