-
Notifications
You must be signed in to change notification settings - Fork 4
/
Day10.hs
33 lines (29 loc) · 1.31 KB
/
Day10.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
{-|
Module: Day10
Description: <https://adventofcode.com/2022/day/10 Day 10: Cathode-Ray Tube>
-}
{-# LANGUAGE OverloadedStrings, ViewPatterns #-}
module Day10 (day10a, day10b) where
import qualified Data.IntMap as IntMap (fromDistinctAscList, lookupLT)
import Data.Ix (inRange)
import Data.List (intercalate, unfoldr)
import Data.List.Split (chunksOf)
import Data.Maybe (mapMaybe)
import Data.Text (Text)
import qualified Data.Text as T (lines, stripPrefix)
import qualified Data.Text.Read as T (decimal, signed)
parse :: (Integral a) => Text -> [(Int, a)]
parse = scanl f (0, 1) . T.lines where
f (i, x) "noop" = (i + 1, x)
f (i, x) (T.stripPrefix "addx " -> Just (T.signed T.decimal -> Right (dx, ""))) = (i + 2, x + dx)
day10a :: Text -> Int
day10a input = sum . zipWith (*) taps . map snd $ mapMaybe (flip IntMap.lookupLT signals) taps where
signals = IntMap.fromDistinctAscList $ parse input
taps = [20, 60, 100, 140, 180, 220]
day10b :: Text -> String
day10b input = intercalate "\n" $ take 6 rows where
sprites = concat $ unfoldr f (0, 1, parse input)
f (i, x, (j, y):signals) = Just (replicate (j - i) x, (j, y, signals))
f (_, x, _) = Just (repeat x, undefined)
rows = zipWith draw [0..] <$> chunksOf 40 sprites
draw i x = if inRange (-1, 1) $ x - i then '\x2593' else '\x2591'