1 -- Writeup at https://work.njae.me.uk/2022/12/10/advent-of-code-2022-day-9/
4 import Data.Text (Text)
5 import qualified Data.Text.IO as TIO
6 import Data.Attoparsec.Text hiding (take)
7 import Control.Applicative
9 import Data.List.Split (chunksOf)
11 data Operation = Noop | Addx Int
14 type Signal = (Int, Int) -- during cycle, register
18 do dataFileName <- getDataFileName
19 text <- TIO.readFile dataFileName
20 let ops = successfulParse text
21 let regVals = apply ops
23 putStrLn $ part2 regVals
25 part1 :: [Signal] -> Int
26 part1 regVals = calculateSixSignals $ extractSignals regVals
28 part2 :: [Signal] -> String
29 part2 regVals = unlines display
30 where pixels = map isLit regVals
31 rows = chunksOf 40 pixels
32 display = fmap (fmap showPixel) rows
34 apply :: [Operation] -> [Signal]
35 apply ops = zip [1..] $ scanl' (+) 1 $ concatMap applyOp ops
37 applyOp :: Operation -> [Int]
39 applyOp (Addx d) = [0, d]
41 extractSignals :: [Signal] -> [Signal]
42 extractSignals signals = filter (\(t, _n) -> (t + 20) `mod` 40 == 0) signals
44 calculateSixSignals :: [Signal] -> Int
45 calculateSixSignals signals = sum [ (t * n)
51 isLit :: Signal -> Bool
52 isLit (n, x) = abs (x - c) <= 1
55 colummOf :: Int -> Int
56 -- colummOf n = (n - 1) `mod` 40 + 1
57 colummOf n = (n - 1) `mod` 40
59 showPixel :: Bool -> Char
60 -- showPixel True = '#'
61 -- showPixel False = '.'
65 -- Parse the input file
67 operationsP :: Parser [Operation]
68 operationP, noopP, addxP :: Parser Operation
70 operationsP = operationP `sepBy` endOfLine
71 operationP = noopP <|> addxP
72 noopP = Noop <$ "noop"
73 addxP = Addx <$> ("addx " *> signed decimal)
75 successfulParse :: Text -> [Operation]
76 successfulParse input =
77 case parseOnly operationsP input of
78 Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err