Done day 10
[advent-of-code-22.git] / advent10 / Main.hs
1 -- Writeup at https://work.njae.me.uk/2022/12/10/advent-of-code-2022-day-9/
2
3 import AoC
4 import Data.Text (Text)
5 import qualified Data.Text.IO as TIO
6 import Data.Attoparsec.Text hiding (take)
7 import Control.Applicative
8 import Data.List
9 import Data.List.Split (chunksOf)
10
11 data Operation = Noop | Addx Int
12 deriving (Show, Eq)
13
14 type Signal = (Int, Int) -- during cycle, register
15
16 main :: IO ()
17 main =
18 do dataFileName <- getDataFileName
19 text <- TIO.readFile dataFileName
20 let ops = successfulParse text
21 let regVals = apply ops
22 print $ part1 regVals
23 putStrLn $ part2 regVals
24
25 part1 :: [Signal] -> Int
26 part1 regVals = calculateSixSignals $ extractSignals regVals
27
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
33
34 apply :: [Operation] -> [Signal]
35 apply ops = zip [1..] $ scanl' (+) 1 $ concatMap applyOp ops
36
37 applyOp :: Operation -> [Int]
38 applyOp Noop = [0]
39 applyOp (Addx d) = [0, d]
40
41 extractSignals :: [Signal] -> [Signal]
42 extractSignals signals = filter (\(t, _n) -> (t + 20) `mod` 40 == 0) signals
43
44 calculateSixSignals :: [Signal] -> Int
45 calculateSixSignals signals = sum [ (t * n)
46 | (t, n) <- signals
47 , t <= 220
48 ]
49
50
51 isLit :: Signal -> Bool
52 isLit (n, x) = abs (x - c) <= 1
53 where c = colummOf n
54
55 colummOf :: Int -> Int
56 -- colummOf n = (n - 1) `mod` 40 + 1
57 colummOf n = (n - 1) `mod` 40
58
59 showPixel :: Bool -> Char
60 -- showPixel True = '#'
61 -- showPixel False = '.'
62 showPixel True = '█'
63 showPixel False = ' '
64
65 -- Parse the input file
66
67 operationsP :: Parser [Operation]
68 operationP, noopP, addxP :: Parser Operation
69
70 operationsP = operationP `sepBy` endOfLine
71 operationP = noopP <|> addxP
72 noopP = Noop <$ "noop"
73 addxP = Addx <$> ("addx " *> signed decimal)
74
75 successfulParse :: Text -> [Operation]
76 successfulParse input =
77 case parseOnly operationsP input of
78 Left _err -> [] -- TIO.putStr $ T.pack $ parseErrorPretty err
79 Right ops -> ops