AOC 23 - Day 11 - Cosmic Expansion
Part 1
Rules
Today we have to help analyzing a map of galaxies. The input looks like this:
...#......
.......#..
#.........
..........
......#...
.#........
.........#
..........
.......#..
#...#.....
To get the answer, we need to do 2 things:
- We have to expand the rows and columns that contains no galaxies. With the previous example, the rows with no galaxies:
v v v
...#......
.......#..
#.........
>..........<
......#...
.#........
.........#
>..........<
.......#..
#...#.....
^ ^ ^
Would become
....#........
.........#...
#............
.............
.............
........#....
.#...........
............#
.............
.............
.........#...
#....#.......
- We then add to get all the possible pairs of galaxies, and sum the shortest path between each pair. A path can only use steps which are up,down,left,right. For example, the distance between the 2 top galaxies is 6:
....#@.......
.....@@@@#...
#............
.............
.............
........#....
.#...........
............#
.............
.............
.........#...
#....#.......
Note that the path can pass through another galaxy.
Code
Let's start by parsing the map. We need 2 parts: The map itself, and the galaxies.
:
:
=
=
return
=
return
We then have to expand the galaxies map. To do this, I just created a second map with the additional rows/columns for empty lines.
Since it's easier to add an horizontal line to a 2d array, I used a cool Python trick I found on this stackoverflow post to rotate a 2d grid. This way we can add rows, rotate our map, add the rows again, and rotate it back to process both rows and columns with the same function:
=
# Rotate map 90 degrees clockwise
=
=
# Rotate 90 degrees counter-clockwise
=
return
=
# Add an additional row if there is only space in this row
return
Since the distance between 2 points is calculating by moving only up/down/left/right, we can use a Manhattan distance to get it without simulating the path:
return +
We then have all the pieces we need to solve part 1:
=
=
=
= 0
+=
return
Part 2
Rules
The part 2 is the same problem as before, but the galaxies expands way much more: each empty row/column now needs to be replaced with 1000000 empty rows/columns.
Code
The trick from part 1 were I was manually inserting the rows would takes way too much time now.
Instead, I opted for the following solution:
- store the y/x index of each empty rows and columns
- for each pair, get the number of points which are in the stored empty rows indexes
- multiply this number by the expansion amount (1 for part 1, 999999 for part 2)
- add this new number to the distance
Let's replace the expansion function by one which only returns the empty rows/columns:
=
=
# Rotate map 90 degrees clockwise
# from https://stackoverflow.com/a/8421412
=
return ,
And implements the function to get the additional distance due to the expansion:
=
, =
, = &
= &
return *
I then moved the logic from part 1 into a dedicated function, which implements this new logic:
# I merged the previous `get_galaxies_map` and `get_galaxies` into one
# to avoid iterating twice on the same map, and to have a tidier code
=
, =
= 0
=
+=
+=
return
We can now update part 1 and add part 2:
return
return
And this day is solved !
All the code is available on github