Advent of Code 2020 Day 24
Today, we continued the progress of day 11, and day 17 by going to the "next level" of Conway's Game of Life. The different today is that rather than 3D, 4D, or in a square-based grid, we're now required to work in a hexagonal grid. The real problem with a hexagonal grid is that so much of programming is dictated by rectangular grid spaces, which means using an x
, y
coordinate system will require modification. Luckily, because this is a common problem (look at how many games and systems use hexagons for tiling) because it's a pretty lucrative shape for having concrete neighbors (diagonals in a square-based grid still have somewhat questionable "neighbor" conditions). Luckily, there are websites that are around to help, one such website is red blob games which has a great page on hexagonal grids and specifically the coordinate system that I used was the doubled coordinates which really provides consistent pathing for this problem in particular.
Part one relied less on a consistent coordinate system (because it just needed to make sure moves worked properly) but part two relied heavily on a consistent set of coordinate systems to support the neighbor searching functionality. The way the double coordinates work is that for an individual row, you only have x-coordinates every other value, so on row 0
for instance, you might have x-coordinate 0
, 2
, 4
, 6
, 8
, ...
but on the following row (row 1
) you would start at x-coordinate 1
, 3
, 5
, 7
, 9
, ...
. This provides SOME stability in the way that items are addressed. Additionally, you can pick your y-coordinate offset for moves to the ne
, nw
, se
, and sw
to be whatever you want, some pick 2
to be consistent with effectively a 2 x 2
grid pattern, but you can also pick to offset by 1
up and down. This also assume you have a grid where the movement left and right (east
and west
) is direct and the other moves that go up are at angles.
As I said before, the key in part one was to solidify the few examples to get back to the same square when necessary, in part two you really have to be able to address other values. Since the proportion of "black" tiles to "white" tiles in the puzzle was pretty heavily weighted on the "white" tiles, I chose to store the black tiles in a list based on coordinates (x
, and y
) and make counts of increasing neighbors of those black tiles by 1 each, to then combine all of those counts to deal with the cell rules for the game of life portion. Then using Maps
and Lists
to handle adding/removing from the list of all black tiles and perform that work. It ended up being a fairly straightforward problem once you decide on a coordinate system, and that coordinate system specifically has to work for your application. While you can use 1-value offsets for some applications, you really need to have the doubled coordinates (in the x-direction) to complete this puzzle successfully.
I only have one more thing to point out. One of the frustrations doing this work in Java is the complete disdain java has for easier access to things like lists, tuples
and other simple data structures in favor of pushing you to classes. I've had to deal with x/y-coordinates so many times in this year's advent of code and in Python, you can throw together some things pretty easily, but in Java, it just seems like you're pushing in a direction that no one things you should be pushing. I had to generate a Coordinate
class to use as a key in a map, but in python, this is as simple as using a tuple, which simplifies the code and just makes things more readable and nice to work with. I WISH that Java would have some of those concepts, if even just built in, but I understand being strictly typed makes that hard. Lists of Strings end up being so much more work to start in Java than they are in python because of type requirements, but it all kind of makes sense in the long run. If you want to join my Advent of Code leaderboard, feel free to join with the code: 699615-aae0e8af
.