Day 17. Conway Cubes
Problem statement
https://adventofcode.com/2020/day/17 (mirror)My solution
Another variation on the Game of Life. Pretty simple to understand, unless one reads the description carefully and asks: how did the initial configuration
.#.
..#
###
transform into the following one after a single cycle?
#.#
.##
.#.
The answer is: the slices are not on top of each other. 🙃
..... .....
..#.. .....
...#. => .#.#.
.###. ..##.
..... ..#..
The visualization of a cycle in 4D space is even more confusing.
This time, contrary to day 11, we will use a simple optimization trick that visibly speeds up the simulation.
Every cube that may potentially become active in the next cycle must have an active neighbour in current cycle.
Therefore, we only need to keep a record of currently active cubes! In each cycle, we iterate over the neighbours of currently active cubes and:
- Count the number of neighbours that are active (remember that we are doing this from the point of view of an active node).
- For each inactive node that is a neighbour of currently analyzed active node, increment the active neighbour counter by one. Said counter is implemented as
var inactiveCubes = Dictionary<(int x, int y, int z), int>
(orDictionary<(int x, int y, int z, int w), int>
in case of Part B).
Finally, the set of cubes active in the next cycle will be the union of:
- Set of active nodes that have exactly 2 or 3 active neighbours.
- Set of previously inactive nodes that have exactly 3 active neighbours (we lookup that value from
inactiveCubes
dictionary!).
The only difference between Part A and Part B is the number of dimensions, in which we are looking for neighbours (note the overloaded methods GetNeighbours((int x, int y, int z) cube)
and GetNeighbours((int x, int y, int z, int w) cube)
in the code!).