[2024][ruby][8.x] refactored
change tnkvzyuyzrstmstqykynzuysooslopzr
commit f716e9b1f39cc3b5d2f16b0c685e77dae1d15f05
author Alpha Chen <alpha@kejadlen.dev>
date
parent xwluywsl
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__