data Instruction = Add Int | Noop deriving (Eq, Show) getCyclesAt = [20, 60 .. 220] parseInstruction :: String -> Instruction parseInstruction s = case head split of "addx" -> Add (read $ split !! 1) "noop" -> Noop instr -> error $ "unknown instruction " ++ instr where split = words s parse :: String -> [Instruction] parse = map parseInstruction . lines executeProgram :: [Instruction] -> [Int] executeProgram = concat . scanl exec [1] where exec :: [Int] -> Instruction -> [Int] exec xs instr = case instr of (Add y) -> [x, x + y] Noop -> [x] where x = last xs main = interact $ show . sum . (\cycles -> map (\i -> i * cycles !! (i-1)) getCyclesAt) . executeProgram . parse