1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
boxes = DATA.read.lines.map { it.split(?,).map(&:to_i) }

Circuits = Struct.new(:circuits) do
  def connect(a, b)
    c_a, c_b = circuits.values_at(a, b)

    circuit = c_a.merge(c_b)
    circuit.each do |box|
      circuits[box] = circuit
    end

    circuit
  end
end

distances = boxes.combination(2).sort_by {|a, b|
  a.zip(b).sum { (_1 - _2) ** 2 } ** 0.5
}

circuits = Circuits.new(boxes.to_h { [it, Set[it]] })

# part one
distances[0...10].each do |pair|
  circuits.connect(*pair)
end
pp circuits.circuits.values.uniq.map(&:size).sort[-3..].inject(:*)

# part two
a, b = distances[10..].find {|pair| circuits.connect(*pair).size == boxes.size }
pp a[0] * b[0]

__END__