--- Writeup at https://work.njae.me.uk/2021/12/09/advent-of-code-2021-day-9/
+-- Writeup at https://work.njae.me.uk/2021/12/12/advent-of-code-2021-day-11/
import Data.Array.IArray
import Data.Char
c = (length $ head rows) - 1
mkOct e = Octopus (digitToInt e) False
+part1 :: Grid -> Int
part1 grid = snd $ (simulate grid) !! 100
+part2 :: Grid -> Int
part2 grid = length $ takeWhile notSyncronised $ simulate grid
where notSyncronised (g, _) = not $ simultaneous g
numFlashers = length flashers
grid3 = resetFlashers grid2 flashers
-
+simultaneous :: Grid -> Bool
simultaneous grid = all zeroOct $ elems grid
where zeroOct (Octopus 0 _) = True
zeroOct _ = False
increment :: Grid -> Grid
increment = amap incrementOne
+incrementSome :: Grid -> [Coord] -> Grid
incrementSome grid locations = grid // (zip locations incrementedOcts)
where incrementedOcts = map (incrementOne . (grid !)) locations
+incrementOne :: Octopus -> Octopus
incrementOne (Octopus energy flashed) = Octopus (energy + 1) flashed
-
findFlashers :: Grid -> [Coord]
findFlashers = map fst . filter (overpowered . snd) . assocs
where overpowered (Octopus energy _) = energy > 9
-
+flash :: Grid -> [Coord] -> Grid
flash grid [] = grid
flash grid (here:agenda)
+ -- already flashed, so ignore
| flashed == True = flash grid agenda
+ -- not enough energy to flash, so ignore
| energy <= 9 = flash grid agenda
| otherwise = flash grid'' agenda'
- -- set this as flashed
- -- increment neighbours
- -- add negighbours to agenda
where Octopus energy flashed = grid ! here
nbrs = neighbours grid here
- octopus' = Octopus (energy + 1) True
- agenda' = nbrs ++ agenda
+ -- set this as flashed
+ octopus' = Octopus energy True
grid' = grid // [(here, octopus')]
+ -- add negighbours to agenda
+ agenda' = nbrs ++ agenda
+ -- increment neighbours
grid'' = incrementSome grid' nbrs
resetFlashers :: Grid -> [Coord] -> Grid
resetFlashers grid locations = grid // (zip locations resetOcts)
where resetOcts = repeat (Octopus 0 False)
-
neighbours :: Grid -> Coord -> [Coord]
neighbours grid here = filter (inRange (bounds grid))
[ here ^+^ (V2 r c)