mirror of
https://github.com/mx42/adventofcode.git
synced 2026-01-14 13:59:51 +01:00
Add 2020 day 8
This commit is contained in:
49
haskellAoC/src/Y2020/Day08.hs
Normal file
49
haskellAoC/src/Y2020/Day08.hs
Normal file
@@ -0,0 +1,49 @@
|
||||
module Y2020.Day08 (y20day08) where
|
||||
|
||||
import Data.List
|
||||
import Data.List.Split
|
||||
import qualified Data.Map as M
|
||||
|
||||
data Instr = Acc Int | Jmp Int | Nop Int deriving (Show)
|
||||
|
||||
-- current offset, current acc, visited offsets
|
||||
type State = (Int, Int, [Int])
|
||||
|
||||
runInstructions :: M.Map Int Instr -> State -> (Bool, Int)
|
||||
runInstructions instr (cur, acc, visited)
|
||||
| cur `elem` visited = (False, acc) -- looping
|
||||
| cur `M.notMember` instr = (True, acc) -- terminated
|
||||
| otherwise = runInstructions instr (newCur, newAcc, newVisited)
|
||||
where newVisited = cur:visited
|
||||
(newCur, newAcc) = case (instr M.! cur) of
|
||||
Nop _ -> (cur + 1, acc)
|
||||
Acc qty -> (cur + 1, acc + qty)
|
||||
Jmp ofs -> (cur + ofs, acc)
|
||||
|
||||
parseInput :: String -> Instr
|
||||
parseInput input
|
||||
| "nop" `isPrefixOf` input = Nop nb
|
||||
| "acc" `isPrefixOf` input = Acc nb
|
||||
| "jmp" `isPrefixOf` input = Jmp nb
|
||||
where nb = (sign raw_sign) 0 number :: Int
|
||||
(raw_sign:raw_number) = (splitOn " " input) !! 1
|
||||
sign '+' = (+)
|
||||
sign '-' = (-)
|
||||
number = read raw_number :: Int
|
||||
|
||||
testSwappedNopJmp :: M.Map Int Instr -> Int -> Int
|
||||
testSwappedNopJmp original offset = case original M.! offset of
|
||||
Acc _ -> next
|
||||
Jmp qty -> resWithSwap (Nop qty)
|
||||
Nop qty -> resWithSwap (Jmp qty)
|
||||
where next = testSwappedNopJmp original (offset + 1)
|
||||
resWithSwap swapped = case (runInstructions (swappedInput swapped) (0, 0, [])) of
|
||||
(True, acc) -> acc
|
||||
(False, _) -> next
|
||||
swappedInput new = M.insert offset new original
|
||||
|
||||
y20day08 :: [String] -> (String, String)
|
||||
y20day08 input = (part1, part2)
|
||||
where part1 = show $ snd $ runInstructions ops (0, 0, [])
|
||||
part2 = show $ testSwappedNopJmp ops 0
|
||||
ops = M.fromList $ zip (iterate (+ 1) 0) $ map parseInput input
|
||||
@@ -7,6 +7,7 @@ import Y2020.Day04
|
||||
import Y2020.Day05
|
||||
import Y2020.Day06
|
||||
import Y2020.Day07
|
||||
import Y2020.Day08
|
||||
|
||||
year2020 :: String -> [String] -> (String, String)
|
||||
year2020 "01" = y20day01
|
||||
@@ -16,3 +17,4 @@ year2020 "04" = y20day04
|
||||
year2020 "05" = y20day05
|
||||
year2020 "06" = y20day06
|
||||
year2020 "07" = y20day07
|
||||
year2020 "08" = y20day08
|
||||
|
||||
Reference in New Issue
Block a user