Reading coordinates and intersections I wanted to use linear algebra because I like the aesthetics of math but I realized pretty quickly that this won't help here because of parallel lines. I ditched it but in retorspective I would have still helped me because I could have prettier iterations. This is a mess now, because it's super, super naive as I had no time to research of think about prettier methods hidden in the ruby toolset (my daughter waking up any time is like a Damocles sword while coding the challenge 😁)
Well, what strategy did I follow without linear algebra? Filling the grid by calculating all the coordinates between the points and then I could stick to the ruby elegance of handling arrays. I could basically count the amount of intersections by finding the count of coordinates that are the same (with array#tally
) and then I used array#count
to count those with a value (in the hash given by tally) greater or equal 2.
I had this beauty very quickly coords.map(&:spread).compact.flatten(1).tally.values.count{ _1 >= 2 }
where spread
is my custom grid filling method. I learned about the shortcut _1
on a previous day in someone else's challenge and found the awesome tally in the docs during the first 1-2 days.
I struggled a lot more with the loop building. I wanted to use ranges but they are useless for negative values and so it got super naive. Anyway, part 1 & 2 done ✅🙌
Update I saw some until loop (code golfed, see appendix) and there I got the idea of using an enumerator
combined with the new knowledge of the operator <=>
to get the direction sign.
That looks not perfect but is much more pleasant and ruby like for my feeling.
def spread
spreader = Enumerator.new do |yielder|
x = @p1.x
y = @p1.y
dx = @p2.x <=> @p1.x
dy = @p2.y <=> @p1.y
loop do
yielder << [x, y]
x += dx
y += dy
end
end
spreader.take_while { _1 != [@p2.x, @p2.y] } + [[@p2.x, @p2.y]]
end
--- Day 5: Hydrothermal Venture ---
You come across a field of hydrothermal vents on the ocean floor! These vents constantly produce large, opaque clouds, so it would be best to avoid them if possible.
They tend to form in lines; the submarine helpfully produces a list of nearby lines of vents (your puzzle input) for you to review. For example:
0,9 -> 5,9
8,0 -> 0,8
9,4 -> 3,4
2,2 -> 2,1
7,0 -> 7,4
6,4 -> 2,0
0,9 -> 2,9
3,4 -> 1,4
0,0 -> 8,8
5,5 -> 8,2
Each line of vents is given as a line segment in the format x1,y1 -> x2,y2 where x1,y1 are the coordinates of one end the line segment and x2,y2 are the coordinates of the other end. These line segments include the points at both ends. In other words:
An entry like 1,1 -> 1,3 covers points 1,1, 1,2, and 1,3.
An entry like 9,7 -> 7,7 covers points 9,7, 8,7, and 7,7.
For now, only consider horizontal and vertical lines: lines where either x1 = x2 or y1 = y2.
So, the horizontal and vertical lines from the above list would produce the following diagram:
.......1..
..1....1..
..1....1..
.......1..
.112111211
..........
..........
..........
..........
222111....
In this diagram, the top left corner is 0,0 and the bottom right corner is 9,9. Each position is shown as the number of lines which cover that point or . if no line covers that point. The top-left pair of 1s, for example, comes from 2,2 -> 2,1; the very bottom row is formed by the overlapping lines 0,9 -> 5,9 and 0,9 -> 2,9.
To avoid the most dangerous areas, you need to determine the number of points where at least two lines overlap. In the above example, this is anywhere in the diagram with a 2 or larger - a total of 5 points.
Consider only horizontal and vertical lines. At how many points do at least two lines overlap?
The first half of this puzzle is complete! It provides one gold star: *
--- Part Two ---
Unfortunately, considering only horizontal and vertical lines doesn't give you the full picture; you need to also consider diagonal lines.
Because of the limits of the hydrothermal vent mapping system, the lines in your list will only ever be horizontal, vertical, or a diagonal line at exactly 45 degrees. In other words:
An entry like 1,1 -> 3,3 covers points 1,1, 2,2, and 3,3.
An entry like 9,7 -> 7,9 covers points 9,7, 8,8, and 7,9.
Considering all lines from the above example would now produce the following diagram:
1.1....11.
.111...2..
..2.1.111.
...1.2.2..
.112313211
...1.2....
..1...1...
.1.....1..
1.......1.
222111....
You still need to determine the number of points where at least two lines overlap. In the above example, this is still anywhere in the diagram with a 2 or larger - now a total of 12 points.
Consider all of the lines. At how many points do at least two lines overlap?