[hs] Solve 2020_08 part 1
This commit is contained in:
parent
a97a5be6c8
commit
12d4bf1471
2 changed files with 74 additions and 0 deletions
|
|
@ -10,6 +10,7 @@ import qualified Aoc.Y2020.D04 as D04
|
||||||
import qualified Aoc.Y2020.D05 as D05
|
import qualified Aoc.Y2020.D05 as D05
|
||||||
import qualified Aoc.Y2020.D06 as D06
|
import qualified Aoc.Y2020.D06 as D06
|
||||||
import qualified Aoc.Y2020.D07 as D07
|
import qualified Aoc.Y2020.D07 as D07
|
||||||
|
import qualified Aoc.Y2020.D08 as D08
|
||||||
|
|
||||||
year :: Year
|
year :: Year
|
||||||
year = Year 2020
|
year = Year 2020
|
||||||
|
|
@ -20,4 +21,5 @@ year = Year 2020
|
||||||
, ( 5, D05.day)
|
, ( 5, D05.day)
|
||||||
, ( 6, D06.day)
|
, ( 6, D06.day)
|
||||||
, ( 7, D07.day)
|
, ( 7, D07.day)
|
||||||
|
, ( 8, D08.day)
|
||||||
]
|
]
|
||||||
|
|
|
||||||
72
hs/src/Aoc/Y2020/D08.hs
Normal file
72
hs/src/Aoc/Y2020/D08.hs
Normal file
|
|
@ -0,0 +1,72 @@
|
||||||
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
|
|
||||||
|
module Aoc.Y2020.D08
|
||||||
|
( day
|
||||||
|
) where
|
||||||
|
|
||||||
|
import qualified Data.Map as Map
|
||||||
|
import qualified Data.Set as Set
|
||||||
|
|
||||||
|
import Aoc.Day
|
||||||
|
import Aoc.Parse
|
||||||
|
|
||||||
|
data Opcode = Acc | Jmp | Nop
|
||||||
|
deriving (Show, Eq, Ord)
|
||||||
|
|
||||||
|
data Instr = Instr Opcode Int
|
||||||
|
deriving (Show, Eq, Ord)
|
||||||
|
|
||||||
|
parser :: Parser [Instr]
|
||||||
|
parser = manyLines $ Instr <$> (pOpcode <* char ' ') <*> signed (pure ()) decimal
|
||||||
|
where
|
||||||
|
pOpcode = (Acc <$ string "acc") <|> (Jmp <$ string "jmp") <|> (Nop <$ string "nop")
|
||||||
|
|
||||||
|
data State = State
|
||||||
|
{ sInstrs :: Map.Map Int Instr
|
||||||
|
, sIdx :: Int
|
||||||
|
, sAcc :: Int
|
||||||
|
} deriving (Show)
|
||||||
|
|
||||||
|
newState :: [Instr] -> State
|
||||||
|
newState instrs = State (Map.fromList $ zip [0..] instrs) 0 0
|
||||||
|
|
||||||
|
incIdx :: Int -> State -> State
|
||||||
|
incIdx delta s = s { sIdx = delta + sIdx s }
|
||||||
|
|
||||||
|
incAcc :: Int -> State -> State
|
||||||
|
incAcc delta s = s { sAcc = delta + sAcc s }
|
||||||
|
|
||||||
|
step :: State -> Maybe State
|
||||||
|
step s = do
|
||||||
|
(Instr op val) <- sInstrs s Map.!? sIdx s
|
||||||
|
pure $ case op of
|
||||||
|
Acc -> incIdx 1 $ incAcc val s
|
||||||
|
Jmp -> incIdx val s
|
||||||
|
Nop -> incIdx 1 s
|
||||||
|
|
||||||
|
run :: State -> [State]
|
||||||
|
run s = s : case step s of
|
||||||
|
Nothing -> []
|
||||||
|
Just s' -> run s'
|
||||||
|
|
||||||
|
untilRepeatingIdx :: [State] -> [State]
|
||||||
|
untilRepeatingIdx = helper Set.empty
|
||||||
|
where
|
||||||
|
helper _ [] = []
|
||||||
|
helper idxs (s:ss)
|
||||||
|
| i `Set.member` idxs = []
|
||||||
|
| otherwise = s : helper (Set.insert i idxs) ss
|
||||||
|
where i = sIdx s
|
||||||
|
|
||||||
|
solver :: [Instr] -> IO ()
|
||||||
|
solver instrs = do
|
||||||
|
let s = newState instrs
|
||||||
|
|
||||||
|
putStrLn ">> Part 1"
|
||||||
|
print $ sAcc $ last $ untilRepeatingIdx $ run s
|
||||||
|
|
||||||
|
putStrLn ""
|
||||||
|
putStrLn ">> Part 2"
|
||||||
|
|
||||||
|
day :: Day
|
||||||
|
day = dayParse parser solver
|
||||||
Loading…
Add table
Add a link
Reference in a new issue