my-solutions/advent-of-code/2024/day_08/lib.rb

83 lines
1.6 KiB
Ruby

class Vec2
attr_accessor :x, :y
def initialize(x, y)
@x = x
@y = y
end
end
def count_antinodes(matrix, limit_length)
station_coords = extract_stations(matrix)
# Create zero matrix.
antinodes = Array.new(matrix.length) { Array.new(matrix[0].length, 0) }
station_coords.each_value do |loc|
(0..loc.length - 2).each do |i|
(i + 1..loc.length - 1).each do |j|
x_diff = loc[j].x - loc[i].x
y_diff = loc[j].y - loc[i].y
x1 = loc[i].x - x_diff
y1 = loc[i].y - y_diff
while in_range?(matrix, x1, y1)
antinodes[x1][y1] += 1
break if limit_length
x1 -= x_diff
y1 -= y_diff
end
x2 = loc[j].x + x_diff
y2 = loc[j].y + y_diff
while in_range?(matrix, x2, y2)
antinodes[x2][y2] += 1
break if limit_length
x2 += x_diff
y2 += y_diff
end
end
end
end
unless limit_length
station_coords.each_value do |locations|
locations.each do |loc|
antinodes[loc.x][loc.y] += 1
end
end
end
count = 0
antinodes.each do |row|
row.each do |value|
next if value.zero?
count += 1
end
end
count
end
def in_range?(matrix, x, y)
x >= 0 and y >= 0 and x < matrix.length and y < matrix[x].length
end
def extract_stations(matrix)
station_coords = {}
(0..matrix.length - 1).each do |x|
(0..matrix[x].length - 1).each do |y|
ch = matrix[x][y]
next if ch == '.'
station_coords[ch] = [] unless station_coords.include?(ch)
station_coords[ch].push(Vec2.new(x, y))
end
end
station_coords
end