module Days.Day10 where import AOCUtil import Data.Char import Data.List import GHC.Utils.Misc runA :: IO () runA = interactF "data/day10.txt" (solve) runB :: IO () runB = interactF "data/day10.txt" (solveB) solve :: String -> String solve = show . sum . map score . zip [1 ..] . scanl applyInstruction 1 . cycleCorrection . map parseInstruction . lines solveB :: String -> String solveB = unlines . chunkList 40 . map getPixel . zip [0 ..] . scanl applyInstruction 1 . cycleCorrection . map parseInstruction . lines data Instruction = Noop | Add Int parseInstruction :: String -> Instruction parseInstruction s | isPrefixOf "noop" s = Noop | isPrefixOf "addx" s = Add . read . last . words $ s | otherwise = error "bad instruction" cycleCorrection :: [Instruction] -> [Instruction] cycleCorrection = concatMap duplicateI duplicateI :: Instruction -> [Instruction] duplicateI Noop = [Noop] duplicateI (Add x) = [Noop, Add x] applyInstruction :: Int -> Instruction -> Int applyInstruction i Noop = i applyInstruction i (Add x) = i + x score :: (Int, Int) -> Int score (i, v) | i `elem` [20, 60, 100, 140, 180, 220] = i * v | otherwise = 0 getPixel :: (Int, Int) -> Char getPixel (i, v) = if abs ((i `mod` 40) - v) <= 1 then '#' else '.'