import GHC.Utils.Misc (chunkList) data Instruction = Add Int | Noop deriving (Eq, Show) crtWidth = 40 crtHeight = 6 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 drawScreen :: [Int] -> String drawScreen cycles = unlines $ chunkList crtWidth $ map drawChar [0 .. (crtWidth * crtHeight - 1)] where drawChar :: Int -> Char drawChar i = if xDist <= 1 then '#' else '.' where xScan = i `mod` crtWidth xSprite = cycles !! (i) xDist = abs (xScan - xSprite) main = interact $ (++ "\ni hope it is understandable for this to be an exception to the \"program must output something that's copypastable into aoc's output field\" rule that i've set for myself. read!!!!\n") . drawScreen . executeProgram . parse