[2024][ruby][8.x]
change kwollqruovwlzxtmxxyousyrtmykpztw
commit fbec7ec469b7e8c9cf3d6af744df6b7048243a3a
author Alpha Chen <alpha@kejadlen.dev>
date
parent muvuxtxy
diff --git a/2024/ruby/day_08.rb b/2024/ruby/day_08.rb
new file mode 100644
index 0000000..e2302b5
--- /dev/null
+++ b/2024/ruby/day_08.rb
@@ -0,0 +1,56 @@
+input = DATA
+  .readlines(chomp: true).flat_map.with_index {|row, y|
+    row.chars.map.with_index {|i, x|
+      [[y,x], i]
+    }
+  }.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)|
+    dy = by - ay
+    dx = bx - ax
+    [[ay-dy, ax-dx], [by+dy, bx+dx]]
+  }.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
+
+  (ay,ax), (by,bx) = a, b
+
+  dy = by - ay
+  dx = bx - ax
+  r = Rational(dy, dx)
+  dy = r.numerator
+  dx = r.denominator
+
+  y, x = a
+  loop do
+    break unless input.has_key?([y,x])
+    yield [y,x]
+    y -= dy
+    x -= dx
+  end
+
+  y, x = b
+  loop do
+    break unless input.has_key?([y,x])
+    yield [y,x]
+    y += dy
+    x += dx
+  end
+end
+
+pp freqs.flat_map {|freq|
+  antennae = input.select { _2 == freq }.keys
+  antennae.combination(2).flat_map {|a,b|
+    antinodes(input, a, b).to_a
+  }
+}.sort.uniq.length
+
+__END__