Hydrothermal Venture
Robert Mion
Posted on February 15, 2022
Advent of Code 2021 Day 5
Try the simulator!
The task at hand: Solve for X where
X = total points where at least two lines overlap
- Just the horizontal and vertical lines
- Horizontal, vertical and diagonal lines
Input is
- A multi-line string
It represents
- A series of lines
- Each line is denoted by the coordinates of its endpoints
Solving both parts twice
- I solved both parts the day this puzzle was released
- Therefore, this offered the opportunity to re-write my algorithms using my newly acquired computer science and critical-thinking, and algorithmic-reasoning skills
Re-analyzing my original algorithm
- I used a few intermediary variables to store the subsequently parsed input
- I used a series of array copying and mutation methods, like: map-flat-map-flat-map
- I used a few
for
loops to generate and pre-populate a 2D array upon which I then plotted each line - I used a combination of filter, reduce and Math.max to generate the array's width and height
- I used overly specific conditional logic to catch and react to each type of line
A new approach to generating the correct answer
- Forget the need for a 2D array
- Forget intermediary variables to store pieces of the successively-parsed input
- Instead, I would work directly from the parsed input...continually updating the values in the original list of strings until generating what I needed - then filter the appropriate values from the resulting object
Process the input as a string
Split at each end-of-line character into an array of strings
Update each string accordingly
Split at each -> character into an array of two strings
Update each of the strings accordingly
Split at each , character into an array of two strings
Update each of the strings accordingly
Coerce to a number
For Part 1 only:
Filter the updated array of arrays of numbers
Keep only items whose value in the first location or the second location of both nested arrays are equivalent: meaning the range of coordinates is strictly horizontal or vertical
Update - and afterward, flatten - the (filtered?) array of arrays of numbers accordingly
Create a new array to store a list of coordinates
Calculate four values: each of the largest and smallest x,y values from the two coordinates
Calculate two values: the sign-negated (a.k.a. absolute) values for each difference of min and max x,y coordinate values
If either difference is 0, then we're working with horizontal or vertical lines:
For each x coordinate from min to max
For each y coordinate from min to max
Add to the list of coordinates a stringified version of the x,y coordinate
Else, we're working with diagonal lines:
For as many times as needed from 0 to the larger number when comparing the two differences between min and max x,y coordinates
If the x coordinates and y coordinates are listed in relationally-increasing or -decreasing order
Add to the list of coordinates stringified versions of each relationally-increasing x,y coordinate
Else - one of the coordinates is inversely increasing/decreasing compared to the other
Add to the list of coordinates stringified versions of each increasing x coordinate and decreasing y coordinate
For each stringified coordinate in the updated and flattened array
Update a newly-created object accordingly
If it already has an own property equivalent to the stringified coordinate
Increment that key's value by 1
Else, if the property does not yet exist
Create it and set it to 1
Extract the values from the newly-created object, each being integers 1 or higher, into an array
Filter the array to include only integers greater than or equal to 2
Return the length of the filtered array
Here are my algorithms written in JavaScript
Here's a visual description of how my updated algorithm works
A fantastic challenge to practice everything I studied up 'til now in this series
- Array destructuring
- Concise syntax for conditionally setting values for non-existent keys
- Working as much in-place with the source array as possible without needing superfluous 2D arrays
- Using flatMap for, like, the first time ever!
- Using the logical AND operator to streamline an otherwise nested and complex if..else clause
- Thinking critically about how to generalize the patterns of direction deduced from the order of two coordinates, instead of write overly-nested if..else clauses to account for each possible arrangement
I felt incredible solving this puzzle the first time.
I feel an even greater sense of accomplishment this time, especially seeing both rounds of code side-by-side.
💖 💪 🙅 🚩
Robert Mion
Posted on February 15, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.