2025 ruby day 8
This commit is contained in:
parent
ca03e4367b
commit
7b70b2fca5
10
ruby/2025/8/bin/problem
Normal file
10
ruby/2025/8/bin/problem
Normal 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(&:*)}"
|
||||
96
ruby/2025/8/lib/playground.rb
Normal file
96
ruby/2025/8/lib/playground.rb
Normal 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
|
||||
Loading…
Reference in New Issue
Block a user