Hydrothermal Venture
Tags: adventofcode, programming, algorithms, computerscience
Published: 2022-02-15 02:22:06

## [Advent of Code 2021 Day 5](https://adventofcode.com/2021/day/5)

### [Try the simulator!](https://aochydrothermalventure.rmion.repl.co/)
![How the simulator works](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/kzvzl0uvspl3zvp2kyn4.gif)

## 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
```

#### [Here are my algorithms written in JavaScript](https://replit.com/@rmion/AoCTwentyOneDay5)

#### Here's a visual description of how my updated algorithm works
![Animation of the algorithm described above](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/keirw7mjk8rxd0c4mc55.gif)

## 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.