|
| 1 | +parseInput = foldl (++) [] |
| 2 | + . map (\(y, l) -> map (\(x, c) -> ((x, y), read [c])) l) |
| 3 | + . zip [0..] |
| 4 | + . map (zip [0..]) |
| 5 | + . lines |
| 6 | + |
| 7 | +powerup = map (\(p, i) -> (p, i + 1)) |
| 8 | + |
| 9 | +flash l = l >>= (\(p, i) -> if i >= 10 then [p] else []) |
| 10 | + |
| 11 | +flashN l = l >>= neighbours |
| 12 | + |
| 13 | +neighbours (x, y) = [ (x + x', y + y') |
| 14 | + | x' <- [-1..1] |
| 15 | + , y' <- [-1..1] |
| 16 | + , (x', y') /= (0, 0) |
| 17 | + ] |
| 18 | + |
| 19 | +count p = length . filter (==p) |
| 20 | + |
| 21 | +ripple n = map (\(p, i) -> (p, if i /= 0 then i + count p n else i)) |
| 22 | + |
| 23 | +drain = map (\(p, i) -> (p, if i >= 10 then 0 else i)) |
| 24 | + |
| 25 | +step l = snd $ until ((==[]) . fst) m (f', r') |
| 26 | + where |
| 27 | + l' = powerup l |
| 28 | + f' = flashN $ flash l' |
| 29 | + r' = ripple f' (drain l') |
| 30 | + m (_, r) = let f = flash r |
| 31 | + in (f, ripple (flashN f) (drain r)) |
| 32 | + |
| 33 | +part1 x = fst $ foldl f (0, x) [1..100] |
| 34 | + where |
| 35 | + f (s, p) _ = let p' = step p |
| 36 | + in (s + count 0 (map snd p'), p') |
| 37 | + |
| 38 | +part2 x = fst $ until (all (== 0) . map snd . snd) |
| 39 | + (\(x, y) -> (x + 1, step y)) |
| 40 | + (0, x) |
| 41 | + |
| 42 | +main = fmap parseInput (readFile "input.txt") |
| 43 | + >>= mapM_ print . sequence [part1, part2] |
0 commit comments