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)

50 CLI Tools You Can't Live Without

>> Check out this classic DEV post <<