aboutsummaryrefslogtreecommitdiff
path: root/execs/Day08.hs
diff options
context:
space:
mode:
Diffstat (limited to 'execs/Day08.hs')
-rw-r--r--execs/Day08.hs45
1 files changed, 45 insertions, 0 deletions
diff --git a/execs/Day08.hs b/execs/Day08.hs
new file mode 100644
index 0000000..7d3fce8
--- /dev/null
+++ b/execs/Day08.hs
@@ -0,0 +1,45 @@
1module Main where
2
3import Data.Set (Set)
4import qualified Data.Set as Set
5import Data.Map (Map)
6import qualified Data.Map as Map
7import Utils
8
9type Op = (String, Int)
10
11parseLine :: [String] -> Op
12parseLine [s, j] = (s, read (dropWhile (== '+') j))
13
14run :: Int -> Int -> Set Int -> Map Int Op -> Int
15run acc pc visited operations = if Set.member pc visited then acc else handleCase
16 where visited' = Set.insert pc visited
17 handleCase =
18 case Map.lookup pc operations of
19 Just ("acc", v) -> run (acc + v) (pc + 1) visited' operations
20 Just ("nop", _) -> run acc (pc + 1) visited' operations
21 Just ("jmp", j) -> run acc (pc + j) visited' operations
22 _ -> acc
23
24doesEnd :: Int -> Int -> Set Int -> Map Int Op -> Bool
25doesEnd acc pc visited operations = not (Set.member pc visited) && handleCase
26 where visited' = Set.insert pc visited
27 handleCase =
28 case Map.lookup pc operations of
29 Just ("acc", v) -> doesEnd (acc + v) (pc + 1) visited' operations
30 Just ("nop", _) -> doesEnd acc (pc + 1) visited' operations
31 Just ("jmp", j) -> doesEnd acc (pc + j) visited' operations
32 _ -> True -- pc has crossed the end!
33
34genAll :: [Op] -> [[Op]]
35genAll [] = []
36genAll (n@("nop",v):rest) = (("jmp",v):rest) : map (n:) (genAll rest)
37genAll (j@("jmp",v):rest) = (("nop",v):rest) : map (j:) (genAll rest)
38genAll (acc:rest) = map (acc:) $ genAll rest
39
40main :: IO ()
41main = do
42 n <- map (parseLine . words) . lines <$> readFile "input/08"
43 let solve1 = run 0 0 Set.empty . Map.fromList . zip [0..]
44 print $ solve1 n
45 print $ solve1 $ head $ filter (doesEnd 0 0 Set.empty . Map.fromList . zip [0..]) $ genAll n