2025 ruby day 8

This commit is contained in:
Bill Rossi 2025-12-08 04:48:46 -05:00
parent ca03e4367b
commit 7b70b2fca5
2 changed files with 106 additions and 0 deletions

10
ruby/2025/8/bin/problem Normal file
View File

@ -0,0 +1,10 @@
#!/usr/bin/env ruby
require "playground"
pg = Playground.for STDIN.read.chomp
pg.connect_circuits!
puts "Part 1: #{pg.circuits.values.uniq.sort_by(&:length).last(3).map(&:length).reduce(&:*)}"
pg.connect_all_circuits!
puts "Part 2: #{pg.last_pair.map(&:x).reduce(&:*)}"

View File

@ -0,0 +1,96 @@
class Playground
attr_reader :boxes, :circuits, :last_pair
def initialize(boxes)
@boxes = boxes
boxes.each { |box| box.pg = self }
@circuits = boxes.to_h{ |box| [box.index, Circuit.new(box)] }
end
def self.for(input)
new input.split("\n").each_with_index.map(&JunctionBox.method(:for))
end
def distances
boxes.map { |b1| boxes.map { |b2| b1.distance_squared(b2) } }
end
def distance_pairs
distances.each_with_index.map do |dist_row, x|
dist_row.each_with_index.map do |dist, y|
[[x, y].min, [x,y].max, dist]
end
end.flatten(1).uniq.sort_by { |dp| dp[2] }
end
def connect_circuits!(connections=1000)
distance_pairs.first(connections).each do |a, b, _|
connect_circuit!(a, b)
end
end
def connect_all_circuits!
distance_pairs.each do |a, b, _|
connect_circuit!(a, b)
break if all_connected?
end
end
def all_connected?
circuits.values.uniq.length == 1
end
def connect_circuit!(a, b)
return if circuits[a].boxes.include?(boxes[b])
@last_pair = boxes[a], boxes[b]
circuits[a].boxes.push(*Array.new(circuits[b].boxes))
circuits[b].boxes.each { |box| circuits[box.index] = circuits[a] }
end
class JunctionBox
attr_reader :index, :x, :y, :z
attr_accessor :pg
def initialize(index, x, y, z)
@index = index
@x = x
@y = y
@z = z
end
def self.for(line, index)
new index, *line.split(",").map(&:to_i)
end
def distance_squared(other)
return 9999999999999 if self == other
(x - other.x)**2 +
(y - other.y)**2 +
(z - other.z)**2
end
def distances
@distances ||= pg.boxes.map { |box| distance_squared(box) }
end
def to_s
"#{index} (#{x}, #{y}, #{z})"
end
end
class Circuit
attr_reader :boxes
def initialize(box)
@boxes = [box]
end
def to_s
boxes.map(&:index)
end
def length
boxes.length
end
end
end