[2024][ruby][8.x] refactored
diff --git a/2024/ruby/day_08.rb b/2024/ruby/day_08.rb
index e2302b5..f41979c 100644
--- a/2024/ruby/day_08.rb
+++ b/2024/ruby/day_08.rb
@@ -6,51 +6,47 @@ input = DATA
}.to_h
freqs = input.values.uniq - %w[.]
-pp freqs.flat_map {|freq|
- antennae = input.select { _2 == freq }.keys
- antennae.combination(2).flat_map {|(ay,ax),(by,bx)|
+antennae = freqs.to_h {|freq|
+ [freq, input.select { _2 == freq }.keys]
+}
+
+pp antennae.values.flat_map {|yxs|
+ yxs.combination(2).flat_map {|(ay,ax),(by,bx)|
dy = by - ay
dx = bx - ax
[[ay-dy, ax-dx], [by+dy, bx+dx]]
- }.select {|yx| input.has_key?(yx) }
+ }.select {|yx|
+ input.has_key?(yx)
+ }
}.uniq.length
def antinodes(input, a, b)
return enum_for(__method__, input, a, b) unless block_given?
- max_y = input.keys.map(&:first).max
- max_x = input.keys.map(&:last).max
+ max_y, max_x = input.keys.transpose.map(&:max)
- (ay,ax), (by,bx) = a, b
+ r = Rational(*b.zip(a).map { _1 - _2 })
+ delta = r.numerator, r.denominator
- dy = by - ay
- dx = bx - ax
- r = Rational(dy, dx)
- dy = r.numerator
- dx = r.denominator
-
- y, x = a
+ yx = a
loop do
- break unless input.has_key?([y,x])
- yield [y,x]
- y -= dy
- x -= dx
+ break unless input.has_key?(yx)
+ yield yx
+ yx = yx.zip(delta).map { _1 - _2 }
end
- y, x = b
+ yx = b
loop do
- break unless input.has_key?([y,x])
- yield [y,x]
- y += dy
- x += dx
+ break unless input.has_key?(yx)
+ yield yx
+ yx = yx.zip(delta).map { _1 + _2 }
end
end
-pp freqs.flat_map {|freq|
- antennae = input.select { _2 == freq }.keys
- antennae.combination(2).flat_map {|a,b|
+pp antennae.values.flat_map {|yxs|
+ yxs.combination(2).flat_map {|a,b|
antinodes(input, a, b).to_a
}
-}.sort.uniq.length
+}.uniq.length
__END__