So, today's puzzle reaffirmed my hatred of multi-dimension arrays in java, especially when it comes to streams and multi-dimension arrays. Today's part one required the use of an ever-expanding 3D array, part two required the use of an ever-expanding 4D array. The problem statement talked about "an infinite 3-dimensional grid" which really means time to blow up your RAM, so I started conservatively with a
1 x rows x cols array to being with and every iteration expanded by 2 in every dimension. The initial rows and cols are what the input file (or test input) at that point. In part two I started with a
1 x 1 x rows x cols and again expanded in every dimension by 2 for each iteration.
The premise of this puzzle was Conway's game of life, which is a fairly well-known computer science example of dealing with multi-dimension arrays (typically 2D) and having stateful behavior where the current state dictates the next state based on neighboring nodes (similar to day 11) but this time, an "active" node represented by
# needs 2 or 3 neighbors (in 3 or 4 dimensions) to stay active and an inactive node represented by
. needs 3 neighbors (in 3 or 4 dimensions) to become active. I still struggle to imagine 4 dimensions, but maybe that's a good thing.
One important thing I learned today is how to index a 3 and 4 dimension dataset within a 1 dimension array. And deal with the fact that I've very much lucked out in the past because the number of rows typically equals the number of columns, especially for the data that we are given for these puzzles and oh my gosh, I now see where I went wrong in day 11 because in that case, the rows wasn't equal to the columns. Below is a picture of me right now just coming to that realization as I write this blog post.
I've known that in general, you're supposed to use the previous dimension to deal with the multiplication, but this 3D and 4D example really pushed that to the next level. The index for any given depth, row, column coordinate in a 1-D array is
array[depth * rows * cols + row * cols + col] where
col is the current column of interest,
row is the current row of interest and
depth is the current depth of interest with
cols representing the respective rows and columns of the array (you see depths isn't needed here). I'm 99% sure that for the 2D example in day 11, I used
array[row * rows + cols] which in the case of rows being equal to columns is fine, but when the rows and columns don't match, you're in a broken situation, where you miss SOME of the values and get a nice ol'
IndexOutOfBoundsException on the other side. Anyway, for the 4 dimension example you have your
cols and access the given element with
array[time * depths * rows * cols + depth * rows * cols + row * cols + col] which again really seems to be a bit extreme, right? I'm sure there's better optimizations to perform, but it's really annoying to have to do that, so I hope to be done with multi-dimension arrays at this point.
If you want to join my Advent of Code leaderboard, feel free to join with the code: