do
content <- lines <$> input 10
print $ part1 content
putStr $ part2 content
where
state = catMaybes . flip evalState (0, 1) . sequence . map instruction . parse
part1 = sum . calculateSignalStrength . state
part2 = unlines . splitCRTLines . drawCRT . ((1,1):) . map (first (+1)) . state
go 20
where
singleton . strength c $ every20th c xs
go cycle xs = (strength cycle $ every20th cycle xs) : (go (cycle + 40) . snd $ every20th cycle xs)
strength cycle = (*cycle) . snd . last . fst
every20th cycle = span ((<cycle) . fst)
data Instruction = AddX Int | Noop
mempty
drawCRT ((c, x):[]) = foldr' (\a b -> (drawPixel a x) : b) [] [c..240]
drawCRT ((ac, ax):r@(bc, bx):xs) = (foldr' (\a b -> (drawPixel a ax) : b) [] [ac..bc-1]) ++ drawCRT (r:xs)
go
where
[[]]
go x = (fst $ crtLine x) : go (snd $ crtLine x)
crtLine = splitAt 40
1 = '#'
| otherwise = '.'
where
index = abs (column - y)
column = (x - 1) `mod` 40
2
cycles Noop = 1
type Cycle = Int
type RegX = Int
do
(cycle, regx) <- get
let newCycle = cycle + cycles x
case x of
Noop -> do
put (newCycle, regx)
pure Nothing
(AddX a) -> do
let newSt = (newCycle, regx + a)
put newSt
pure $ Just newSt
do
string "noop"
pure Noop
do
string "addx"
skipSpaces
n <- read <$> munch1 num
pure $ AddX n
where
num c = isDigit c || c == '-'
choice [parseNoop, parseAddX]
map (fst . head . readP_to_S parseInstruction)