X-Git-Url: https://git.njae.me.uk/?p=advent-of-code-19.git;a=blobdiff_plain;f=advent24%2Fsrc%2Fadvent24b.hs;fp=advent24%2Fsrc%2Fadvent24b.hs;h=1b173b78e55fe18c661ca73f415f932d7d3f23c2;hp=0000000000000000000000000000000000000000;hb=dd1deef80ef62982bd6c014e1a38d28190c53961;hpb=418d5771f9b52ca7d813c1daebc91772a6e74a88 diff --git a/advent24/src/advent24b.hs b/advent24/src/advent24b.hs new file mode 100644 index 0000000..1b173b7 --- /dev/null +++ b/advent24/src/advent24b.hs @@ -0,0 +1,80 @@ +import Debug.Trace + +import qualified Data.Set as S + +data Cell = Cell { level :: Int + , row :: Int + , column :: Int + } deriving (Show, Eq, Ord) +type Grid = S.Set Cell + + +gridSize = 5 + +main :: IO () +main = + do grid0 <- readGrid + print grid0 + let finalGrid = head $ drop 200 $ iterate update grid0 + print $ S.size finalGrid + + +readGrid = + do gs <- readFile "data/advent24.txt" + let grid = lines gs + let isBug r c = (grid!!(r - 1))!!(c - 1) == '#' + let level = 0 + return $ S.fromList [Cell {..} | row <- [1..gridSize], column <- [1..gridSize], isBug row column] + +neighbourSpaces :: Cell -> Grid +neighbourSpaces cell = + ( (neighbourSpacesLeft cell) + <> (neighbourSpacesRight cell) + <> (neighbourSpacesAbove cell) + <> (neighbourSpacesBelow cell) + ) + +neighbourSpacesLeft :: Cell -> Grid +neighbourSpacesLeft (Cell {..}) + | column == 4 && row == 3 = S.fromList [ Cell { level = (level + 1), row = r, column = 5} | r <- [1..gridSize] ] + | column == 1 = S.singleton ( Cell { level = (level - 1), row = 3, column = 2}) + | otherwise = S.singleton ( Cell { level, row, column = (column - 1)}) + +neighbourSpacesRight :: Cell -> Grid +neighbourSpacesRight (Cell {..}) + | column == 2 && row == 3 = S.fromList [ Cell { level = (level + 1), row = r, column = 1} | r <- [1..gridSize] ] + | column == 5 = S.singleton ( Cell { level = (level - 1), row = 3, column = 4}) + | otherwise = S.singleton ( Cell { level, row, column = (column + 1)}) + +neighbourSpacesAbove :: Cell -> Grid +neighbourSpacesAbove (Cell {..}) + | row == 4 && column == 3 = S.fromList [ Cell { level = (level + 1), row = 5, column = c} | c <- [1..gridSize] ] + | row == 1 = S.singleton ( Cell { level = (level - 1), row = 2, column = 3}) + | otherwise = S.singleton ( Cell { level, row = (row - 1), column}) + +neighbourSpacesBelow :: Cell -> Grid +neighbourSpacesBelow (Cell {..}) + | row == 2 && column == 3 = S.fromList [ Cell { level = (level + 1), row = 1, column = c} | c <- [1..gridSize] ] + | row == 5 = S.singleton ( Cell { level = (level - 1), row = 4, column = 3}) + | otherwise = S.singleton ( Cell { level, row = (row + 1), column}) + + +countOccupiedNeighbours :: Cell -> Grid -> Int +countOccupiedNeighbours cell grid = S.size $ S.intersection grid $ neighbourSpaces cell + +bugSurvives :: Grid -> Cell -> Bool +bugSurvives grid cell = alive && oneNeighbour + where alive = cell `S.member` grid + oneNeighbour = (countOccupiedNeighbours cell grid) == 1 + +bugBorn :: Grid -> Cell -> Bool +bugBorn grid cell = dead && (nNbrs == 1 || nNbrs == 2) + where dead = cell `S.notMember` grid + nNbrs = countOccupiedNeighbours cell grid + +update :: Grid -> Grid +update grid = S.union (S.filter (bugSurvives grid) bugs) (S.filter (bugBorn grid) empties) + where bugs = grid + empties = (S.foldr mergeEmpties S.empty grid) `S.difference` bugs + mergeEmpties cell acc = S.union acc $ neighbourSpaces cell +