never executed always true always false
1 {-|
2 Module: Y2015.D23
3 Description: Advent of Code Day 23 Solutions.
4 License: MIT
5 Maintainer: @tylerjl
6
7 Solutions to the day 23 set of problems for <adventofcode.com>.
8 -}
9
10 module Y2015.D23 (exInstructions, exInstructions2) where
11
12 import Data.Map.Strict (Map)
13 import qualified Data.Map.Strict as M
14
15 type Registers = Map Register Int
16 type Register = Char
17 data Instruction = Half Register
18 | Triple Register
19 | Increment Register
20 | Jump Int
21 | JIE Register Int
22 | JIO Register Int
23 deriving (Show)
24
25 -- |Solver for part a set of instructions.
26 exInstructions :: String -- ^ Raw instruction/register input string.
27 -> Registers -- ^ Resulting set of register values.
28 exInstructions = runInsts 0 M.empty . toInstructions
29
30 -- |Solver for part b set of instructions.
31 exInstructions2 :: String -- ^ Raw instruction/register input string.
32 -> Registers -- ^ Resulting set of register values.
33 exInstructions2 = runInsts 0 (M.singleton 'a' 1) . toInstructions
34
35 runInsts :: Int -> Registers -> [Instruction] -> Registers
36 runInsts eip rs is | eip < 0 || eip >= length is = rs
37 | otherwise = case is !! eip of
38 (Half r) -> runInsts (eip+1) (M.adjust (`div` 2) r rs) is
39 (Triple r) -> runInsts (eip+1) (M.adjust (*3) r rs) is
40 (Increment r) -> runInsts (eip+1) (M.insertWith (+) r 1 rs) is
41 (Jump j) -> runInsts (eip+j) rs is
42 (JIE r i) -> runInsts (eip+jumpTest i even r) rs is
43 (JIO r i) -> runInsts (eip+jumpTest i (== 1) r) rs is
44 where jumpTest offset f reg = if f $ M.findWithDefault 0 reg rs
45 then offset
46 else 1
47
48 toInstructions :: String -> [Instruction]
49 toInstructions = map (toOperation . words) . lines
50
51 toOperation :: [String] -> Instruction
52 toOperation ["hlf",[r]] = Half r
53 toOperation ["tpl",[r]] = Triple r
54 toOperation ["inc",[r]] = Increment r
55 toOperation ["jmp",offset] = Jump $ toInt offset
56 toOperation ["jie",r:",",offset] = JIE r $ toInt offset
57 toOperation ["jio",r:",",offset] = JIO r $ toInt offset
58 toOperation _ = Jump 0
59
60 toInt :: String -> Int
61 toInt ('-':s) = negate $ read s
62 toInt ('+':s) = read s
63 toInt s = read s