|
| 1 | +NETWORK = INPUT.split("\n").each_with_object(Hash.new { |h, k| h[k] = Set.new }) do |line, network| |
| 2 | + computer, connected = line.split("-") |
| 3 | + |
| 4 | + network[computer] << connected |
| 5 | + network[connected] << computer |
| 6 | +end |
| 7 | + |
| 8 | +def cliques(computer, network) |
| 9 | + network[computer].to_a.combination(2).select do |a, b| |
| 10 | + network[a].include?(b) |
| 11 | + end |
| 12 | +end |
| 13 | + |
| 14 | +parties = NETWORK.keys.each_with_object(Set.new) do |computer, lans| |
| 15 | + cliques(computer, NETWORK).each { |peers| lans << Set.new([computer, *peers]) } |
| 16 | +end |
| 17 | +matches = parties.count { |party| party.any? { |cpu| cpu.start_with?("t") } } |
| 18 | + |
| 19 | +solve!("The number of groups containing a 't' computer is:", matches) |
| 20 | + |
| 21 | +def largest_clique(network, clique = Set.new, ignore = Set.new) |
| 22 | + return clique if network.empty? && ignore.empty? |
| 23 | + |
| 24 | + network.keys.map do |computer| |
| 25 | + largest = largest_clique( |
| 26 | + network.slice(*network[computer]), |
| 27 | + clique + [computer], |
| 28 | + ignore.intersection(network[computer]) |
| 29 | + ) |
| 30 | + |
| 31 | + network.delete(computer) |
| 32 | + ignore << computer |
| 33 | + |
| 34 | + largest |
| 35 | + end.reject(&:nil?).max_by(&:size) |
| 36 | +end |
| 37 | + |
| 38 | +max_party = largest_clique(NETWORK.dup) |
| 39 | +solve!("The LAN party password is:", max_party.sort.join(",")) |
0 commit comments