From 6a1a537ac8f0d4fab44b806aa8986dce4aab8f9e Mon Sep 17 00:00:00 2001 From: Neil Smith Date: Sun, 6 Dec 2020 14:24:41 +0000 Subject: [PATCH] Added problem, some tidying --- advent24/src/advent24b.hs | 40 +++-- advent24/src/advent24tape.hs | 89 ---------- advent24/src/advent24v.hs | 78 --------- problems/day24.html | 328 +++++++++++++++++++++++++++++++++++ 4 files changed, 354 insertions(+), 181 deletions(-) delete mode 100644 advent24/src/advent24tape.hs delete mode 100644 advent24/src/advent24v.hs create mode 100644 problems/day24.html diff --git a/advent24/src/advent24b.hs b/advent24/src/advent24b.hs index 1b173b7..a259df4 100644 --- a/advent24/src/advent24b.hs +++ b/advent24/src/advent24b.hs @@ -1,4 +1,4 @@ -import Debug.Trace +-- import Debug.Trace import qualified Data.Set as S @@ -14,7 +14,7 @@ gridSize = 5 main :: IO () main = do grid0 <- readGrid - print grid0 + -- print grid0 let finalGrid = head $ drop 200 $ iterate update grid0 print $ S.size finalGrid @@ -36,27 +36,39 @@ neighbourSpaces 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)}) + | 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 { 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)}) + | 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 { 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}) + | 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 { row = (row - 1), ..}) 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}) + | 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 { row = (row + 1), ..}) countOccupiedNeighbours :: Cell -> Grid -> Int diff --git a/advent24/src/advent24tape.hs b/advent24/src/advent24tape.hs deleted file mode 100644 index 8f6ce96..0000000 --- a/advent24/src/advent24tape.hs +++ /dev/null @@ -1,89 +0,0 @@ - --- import Debug.Trace - - -import Data.Bool (bool) -import Data.Distributive (Distributive(..)) -import Data.Functor.Rep (Representable(..), distributeRep) -import Data.Functor.Identity (Identity(..)) -import Control.Comonad.Representable.Store (Store(..), StoreT(..), store, experiment, runStore) -import Control.Comonad (Comonad(..)) - -import Data.Maybe -import Data.List -import qualified Data.Set as S -import qualified Data.Map as M - -import Control.Concurrent (threadDelay) -import Control.Monad (forM_) - -import Control.Comonad -import Control.Comonad.Cofree -import Data.Distributive -import Data.Functor.Rep -import qualified Data.Sequence as Q -import qualified Data.List.NonEmpty as NE - - -data TPossible a = TPossible - { leftward :: a - , rightward :: a - , above :: a - , below :: a - } deriving (Show, Eq, Functor) - -data TChoice = L | R | U | D - deriving (Show, Eq) - -instance Distributive TPossible where - distribute :: Functor f => f (TPossible a) -> TPossible (f a) - distribute fga = TPossible (fmap leftward fga) (fmap rightward fga) - (fmap above fga) (fmap below fga) - -instance Representable TPossible where - type Rep TPossible = TChoice - - index :: TPossible a -> TChoice -> a - index here L = leftward here - index here R = rightward here - index here U = above here - index here D = below here - - tabulate :: (TChoice -> a) -> TPossible a - tabulate describe = TPossible (describe L) (describe R) - (describe U) (describe D) - -relativePosition :: Q.Seq TChoice -> Int -relativePosition = sum . fmap valOf - where - valOf L = (-1) - valOf R = 1 - valOf U = (-10) - valOf D = 10 - -numberLine :: Cofree TPossible Int -numberLine = tabulate relativePosition - -project :: NE.NonEmpty a -> Cofree TPossible a -project l = tabulate describe - where - describe = (l NE.!!) . foldl go 0 - maxIndex = length l - 1 - minIndex = 0 - go n L = max minIndex (n - 1) - go n R = min maxIndex (n + 1) - go n U = max minIndex (n - 1) - go n D = min maxIndex (n + 1) - -elems :: NE.NonEmpty String -elems = "one" NE.:| ["two", "three"] - -path :: Q.Seq TChoice -path = Q.fromList [R, R, R, R, L] - -moveTo :: Q.Seq TChoice -> Cofree TPossible a -> Cofree TPossible a -moveTo ind = extend (\cfr -> index cfr ind) - -main :: IO () -main = print $ index (project elems) path --- main = print elems diff --git a/advent24/src/advent24v.hs b/advent24/src/advent24v.hs deleted file mode 100644 index 7707dee..0000000 --- a/advent24/src/advent24v.hs +++ /dev/null @@ -1,78 +0,0 @@ - - -import Control.Concurrent (threadDelay) - - -import Data.Functor.Compose (Compose(..)) -import Data.Vector (Vector, (!), generate) -import Data.Bool (bool) -import Data.Distributive (Distributive(..)) -import Data.Functor.Rep (Representable(..), distributeRep) -import Data.Functor.Identity (Identity(..)) -import Control.Comonad.Representable.Store (Store(..), StoreT(..), store, experiment) -import Control.Comonad (Comonad(..)) -import Control.Monad (forM_) - -type Coord = (Int, Int) -type Grid = Store (Compose Vector Vector) Bool -type Rule = Grid -> Bool - -instance Distributive Vector where - distribute = distributeRep - -instance Representable Vector where - type Rep Vector = Int - index v i = v ! (i `mod` gridSize) - tabulate = generate gridSize - -gridSize :: Int -gridSize = 20 - -neighbourCoords :: [Coord] -neighbourCoords = [(x, y) | x <- [-1, 0, 1], y <- [-1, 0, 1], (x, y) /= (0, 0)] - -addCoords :: Coord -> Coord -> Coord -addCoords (x, y) (x', y') = (x + x', y + y') - -basicRule :: Rule -basicRule g = numNeighboursAlive == 3 || (alive && numNeighboursAlive == 2) - where - alive = extract g - neighbours = experiment (at neighbourCoords) g - numNeighboursAlive = length (filter id neighbours) - -step :: Rule -> Grid -> Grid -step = extend - -render :: Grid -> String -render (StoreT (Identity (Compose g)) _) = foldMap ((++ "\n") . foldMap (bool "." "#")) g - -mkGrid :: [Coord] -> Grid -mkGrid xs = store (`elem` xs) (0, 0) - -at :: [Coord] -> Coord -> [Coord] -coords `at` origin = map (addCoords origin) coords - -glider, blinker, beacon :: [Coord] -glider = [(1, 0), (2, 1), (0, 2), (1, 2), (2, 2)] -blinker = [(0, 0), (1, 0), (2, 0)] -beacon = [(0, 0), (1, 0), (0, 1), (3, 2), (2, 3), (3, 3)] - - - - - - -tickTime :: Int -tickTime = 200000 - -start :: Grid -start = mkGrid $ - glider `at` (0, 0) - ++ beacon `at` (15, 5) - -main :: IO () -main = forM_ (iterate (step basicRule) start) $ \grid -> do - putStr "\ESC[2J" -- Clear terminal screen - putStrLn (render grid) - threadDelay tickTime \ No newline at end of file diff --git a/problems/day24.html b/problems/day24.html new file mode 100644 index 0000000..011bfd2 --- /dev/null +++ b/problems/day24.html @@ -0,0 +1,328 @@ + + + + +Day 24 - Advent of Code 2019 + + + + + + + +

Advent of Code

Neil Smith (AoC++) 48*

   0x0000|2019

+ + + +
+ +

--- Day 24: Planet of Discord ---

You land on Eris, your last stop before reaching Santa. As soon as you do, your sensors start picking up strange life forms moving around: Eris is infested with bugs! With an over 24-hour roundtrip for messages between you and Earth, you'll have to deal with this problem on your own.

+

Eris isn't a very large place; a scan of the entire area fits into a 5x5 grid (your puzzle input). The scan shows bugs (#) and empty spaces (.).

+

Each minute, The bugs live and die based on the number of bugs in the four adjacent tiles:

+
    +
  • A bug dies (becoming an empty space) unless there is exactly one bug adjacent to it.
  • +
  • An empty space becomes infested with a bug if exactly one or two bugs are adjacent to it.
  • +
+

Otherwise, a bug or empty space remains the same. (Tiles on the edges of the grid have fewer than four adjacent tiles; the missing tiles count as empty space.) This process happens in every location simultaneously; that is, within the same minute, the number of adjacent bugs is counted for every tile first, and then the tiles are updated.

+

Here are the first few minutes of an example scenario:

+
Initial state:
+....#
+#..#.
+#..##
+..#..
+#....
+
+After 1 minute:
+#..#.
+####.
+###.#
+##.##
+.##..
+
+After 2 minutes:
+#####
+....#
+....#
+...#.
+#.###
+
+After 3 minutes:
+#....
+####.
+...##
+#.##.
+.##.#
+
+After 4 minutes:
+####.
+....#
+##..#
+.....
+##...
+
+

To understand the nature of the bugs, watch for the first time a layout of bugs and empty spaces matches any previous layout. In the example above, the first layout to appear twice is:

+
.....
+.....
+.....
+#....
+.#...
+
+

To calculate the biodiversity rating for this layout, consider each tile left-to-right in the top row, then left-to-right in the second row, and so on. Each of these tiles is worth biodiversity points equal to increasing powers of two: 1, 2, 4, 8, 16, 32, and so on. Add up the biodiversity points for tiles with bugs; in this example, the 16th tile (32768 points) and 22nd tile (2097152 points) have bugs, a total biodiversity rating of 2129920.

+

What is the biodiversity rating for the first layout that appears twice?

+
+

Your puzzle answer was 17863711.

--- Part Two ---

After careful analysis, one thing is certain: you have no idea where all these bugs are coming from.

+

Then, you remember: Eris is an old Plutonian settlement! Clearly, the bugs are coming from recursively-folded space.

+

This 5x5 grid is only one level in an infinite number of recursion levels. The tile in the middle of the grid is actually another 5x5 grid, the grid in your scan is contained as the middle tile of a larger 5x5 grid, and so on. Two levels of grids look like this:

+
     |     |         |     |     
+     |     |         |     |     
+     |     |         |     |     
+-----+-----+---------+-----+-----
+     |     |         |     |     
+     |     |         |     |     
+     |     |         |     |     
+-----+-----+---------+-----+-----
+     |     | | | | | |     |     
+     |     |-+-+-+-+-|     |     
+     |     | | | | | |     |     
+     |     |-+-+-+-+-|     |     
+     |     | | |?| | |     |     
+     |     |-+-+-+-+-|     |     
+     |     | | | | | |     |     
+     |     |-+-+-+-+-|     |     
+     |     | | | | | |     |     
+-----+-----+---------+-----+-----
+     |     |         |     |     
+     |     |         |     |     
+     |     |         |     |     
+-----+-----+---------+-----+-----
+     |     |         |     |     
+     |     |         |     |     
+     |     |         |     |     
+
+

(To save space, some of the tiles are not drawn to scale.) Remember, this is only a small part of the infinitely recursive grid; there is a 5x5 grid that contains this diagram, and a 5x5 grid that contains that one, and so on. Also, the ? in the diagram contains another 5x5 grid, which itself contains another 5x5 grid, and so on.

+

The scan you took (your puzzle input) shows where the bugs are on a single level of this structure. The middle tile of your scan is empty to accommodate the recursive grids within it. Initially, no other levels contain bugs.

+

Tiles still count as adjacent if they are directly up, down, left, or right of a given tile. Some tiles have adjacent tiles at a recursion level above or below its own level. For example:

+
     |     |         |     |     
+  1  |  2  |    3    |  4  |  5  
+     |     |         |     |     
+-----+-----+---------+-----+-----
+     |     |         |     |     
+  6  |  7  |    8    |  9  |  10 
+     |     |         |     |     
+-----+-----+---------+-----+-----
+     |     |A|B|C|D|E|     |     
+     |     |-+-+-+-+-|     |     
+     |     |F|G|H|I|J|     |     
+     |     |-+-+-+-+-|     |     
+ 11  | 12  |K|L|?|N|O|  14 |  15 
+     |     |-+-+-+-+-|     |     
+     |     |P|Q|R|S|T|     |     
+     |     |-+-+-+-+-|     |     
+     |     |U|V|W|X|Y|     |     
+-----+-----+---------+-----+-----
+     |     |         |     |     
+ 16  | 17  |    18   |  19 |  20 
+     |     |         |     |     
+-----+-----+---------+-----+-----
+     |     |         |     |     
+ 21  | 22  |    23   |  24 |  25 
+     |     |         |     |     
+
+
    +
  • Tile 19 has four adjacent tiles: 14, 18, 20, and 24.
  • +
  • Tile G has four adjacent tiles: B, F, H, and L.
  • +
  • Tile D has four adjacent tiles: 8, C, E, and I.
  • +
  • Tile E has four adjacent tiles: 8, D, 14, and J.
  • +
  • Tile 14 has eight adjacent tiles: 9, E, J, O, T, Y, 15, and 19.
  • +
  • Tile N has eight adjacent tiles: I, O, S, and five tiles within the sub-grid marked ?.
  • +
+

The rules about bugs living and dying are the same as before.

+

For example, consider the same initial state as above:

+
....#
+#..#.
+#.?##
+..#..
+#....
+
+

The center tile is drawn as ? to indicate the next recursive grid. Call this level 0; the grid within this one is level 1, and the grid that contains this one is level -1. Then, after ten minutes, the grid at each level would look like this:

+
Depth -5:
+..#..
+.#.#.
+..?.#
+.#.#.
+..#..
+
+Depth -4:
+...#.
+...##
+..?..
+...##
+...#.
+
+Depth -3:
+#.#..
+.#...
+..?..
+.#...
+#.#..
+
+Depth -2:
+.#.##
+....#
+..?.#
+...##
+.###.
+
+Depth -1:
+#..##
+...##
+..?..
+...#.
+.####
+
+Depth 0:
+.#...
+.#.##
+.#?..
+.....
+.....
+
+Depth 1:
+.##..
+#..##
+..?.#
+##.##
+#####
+
+Depth 2:
+###..
+##.#.
+#.?..
+.#.##
+#.#..
+
+Depth 3:
+..###
+.....
+#.?..
+#....
+#...#
+
+Depth 4:
+.###.
+#..#.
+#.?..
+##.#.
+.....
+
+Depth 5:
+####.
+#..#.
+#.?#.
+####.
+.....
+
+

In this example, after 10 minutes, a total of 99 bugs are present.

+

Starting with your scan, how many bugs are present after 200 minutes?

+
+

Your puzzle answer was 1937.

Both parts of this puzzle are complete! They provide two gold stars: **

+

At this point, you should return to your Advent calendar and try another puzzle.

+

If you still want to see it, you can get your puzzle input.

+

You can also this puzzle.

+
+ + + + + + \ No newline at end of file -- 2.34.1