DEV Community

Cover image for Hydrothermal Venture
Robert Mion
Robert Mion

Posted on

Hydrothermal Venture

Advent of Code 2021 Day 5

Try the simulator!

How the simulator works

The task at hand: Solve for X where

X = total points where at least two lines overlap

  1. Just the horizontal and vertical lines
  2. 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 
Enter fullscreen mode Exit fullscreen mode

Here are my algorithms written in JavaScript

Here's a visual description of how my updated algorithm works

Animation of the algorithm described above

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.

Top comments (0)