rmion

Robert Mion

Posted on February 15, 2022

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.

💖 💪 🙅 🚩
rmion
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.

Related

Rain Risk
adventofcode Rain Risk

April 3, 2022

Docking Data
adventofcode Docking Data

March 28, 2022

Rambunctious Recitation
adventofcode Rambunctious Recitation

March 25, 2022

Shuttle Search
adventofcode Shuttle Search

March 31, 2022

Ticket Translation
adventofcode Ticket Translation

March 24, 2022