module Day10Lib ( day10 , day10' ) where import Data.List (transpose) data Instruction = Noop | Addx Int deriving (Show) type Register = Int type Cycle = Int type Computer = (Register, Cycle) processInstruction :: Computer -> Instruction -> [Computer] processInstruction (r, c) (Addx x) = [(r,c + 1), (r + x, c + 2)] processInstruction (r, c) Noop = [(r,c + 1)] processInstructions :: Computer -> [Instruction] -> [Computer] processInstructions comp@(r,c) (ins:inss) = processedComps ++ processInstructions processedComp inss -- | c == 220 = [processedComp] -- -- | c == 20 = processedComp : r * c + processInstructions processedComp inss -- -- | c `mod` 40 == 0 = r * c + processInstructions processedComp inss -- | otherwise = processedComp : processInstructions processedComp inss where processedComps = processInstruction comp ins processedComp = last processedComps -- PARSING convertToInt :: String -> Int convertToInt s = read s :: Int parseInstruction :: String -> Instruction parseInstruction s = case firstPart of "noop" -> Noop "addx" -> Addx lastPart where asWords = words s firstPart = head asWords lastPart = convertToInt $ last asWords parseInput :: String -> [Instruction] parseInput i = map parseInstruction $ lines i -- Increment cycle by 1 to account for offset of looking at previous cycle to determine during cycle value accountForDuringCycleOffset :: Computer -> Computer accountForDuringCycleOffset (r, c) = (r, c + 1) getSignalStrength :: Computer -> Int getSignalStrength (r, c) = r * c day10 :: String -> Int day10 input = registerSum where -- There are less instructions than cycles we are interested in -- The problem isn't clear about this but I believe the program loops instructions = cycle $ parseInput input -- Infinite computer list startingState = (1,0) icl = processInstructions (1, 0) instructions -- -2 on all indexs, one for zero indexing the other for being about the value _during_ the cycle cyclesOfInterest = [icl !! 18, icl !! 58, icl !! 98, icl !! 138, icl !! 178, icl !! 218] registers = map getSignalStrength $ map accountForDuringCycleOffset cyclesOfInterest registerSum = sum registers type Pixel = Bool drawPixel :: Pixel -> Char drawPixel False = '.' drawPixel True = '#' drawPixelGrid :: [[Pixel]] -> String drawPixelGrid grid = unlines $ map (map drawPixel) grid rowifyPixelList :: [Pixel] -> [[Pixel]] rowifyPixelList pl = [r1, r2, r3, r4, r5, r6] where r1 = take 40 pl r2 = take 40 $ drop 40 pl r3 = take 40 $ drop 80 pl r4 = take 40 $ drop 120 pl r5 = take 40 $ drop 160 pl r6 = take 40 $ drop 200 pl zipPixelListWithComputerList :: Computer -> Int -> Pixel zipPixelListWithComputerList (r, c) pindex = if r == horizontalPostion || r - horizontalPostion == 1 || r - horizontalPostion == -1 then True else False where horizontalPostion = pindex `mod` 40 day10' :: String -> String day10' input = drawPixelGrid $ rowifyPixelList $ zipWith zipPixelListWithComputerList icl pixelgrid where instructions = cycle $ parseInput input startingState = (1,0) icl = startingState : processInstructions (1, 0) instructions pixelgrid = [0..239]