Mercurial > repos > other > adventofcode2023
changeset 36:7197f31970ff
Day 25 part 1 instructions and partial solution
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Thu, 18 Apr 2024 19:56:23 +0100 |
parents | ca54f9702892 |
children | 455c825f5080 |
files | day25.rb day25.txt |
diffstat | 2 files changed, 92 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/day25.rb Thu Apr 18 19:56:23 2024 +0100 @@ -0,0 +1,85 @@ +#! /usr/bin/env ruby + +require 'set' + +if ARGV.length != 1 + abort("Incorrect arguments - needs input file") +elsif not File.exist? (ARGV[0]) +abort("File #{ARGV[0]} did not exist") +end + +file = ARGV[0] + + +connections = File.open(file, "r").each_line(chomp: true).flat_map do |line| + node1, rest = line.split(": ") + rest.split(" ").flat_map {|node| [[node1,node], [node,node1]]} +end.group_by {|key, value| key}.transform_values {|vals| vals.map {|val| [val[1], 1]}.to_h} + +puts "#{connections}" + +# From https://en.wikipedia.org/wiki/Stoer%E2%80%93Wagner_algorithm +# and https://tjkendev.github.io/procon-library/python/graph/stoer-wagner-algorithm.html + +def global_minimum_cut(graph, u0) + N = graph.size + res = 10**18 + + # groups = [{i} for i in range(N)] + + merged = [0]*N + for s in range(N-1): + # minimum cut phase + used = [0]*N + used[u0] = 1 + costs = [0]*N + for v in range(N): + if E[u0][v] != -1: + costs[v] = E[u0][v] + order = [] + for _ in range(N-1-s): + v = mc = -1 + for i in range(N): + if used[i] or merged[i]: + continue + if mc < costs[i]: + mc = costs[i] + v = i + # assert v != -1 + + # v: the most tightly connected vertex + for w in range(N): + if used[w] or E[v][w] == -1: + continue + costs[w] += E[v][w] + used[v] = 1 + order.append(v) + + v = order[-1] + ws = 0 + for w in range(N): + if E[v][w] != -1: + ws += E[v][w] + # - the current min-cut is (groups[v], V - groups[v]) + # - the weight of the cut is ws + res = min(res, ws) + + if len(order) > 1: + u = order[-2] + # groups[u].update(groups[v]) + # groups[v] = None + + # merge u and v + merged[v] = 1 + for w in range(N): + if w != u: + if E[v][w] == -1: + continue + if E[u][w] != -1: + E[u][w] = E[w][u] = E[u][w] + E[v][w] + else: + E[u][w] = E[w][u] = E[v][w] + E[v][w] = E[w][v] = -1 + return res + +puts global_minimum_cut(connections, 1) \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/day25.txt Thu Apr 18 19:56:23 2024 +0100 @@ -0,0 +1,7 @@ +--- Day 25: Snowverload --- + +You have a set of connected components. Connections are undirected, but are written as `a: b c d` to show that +a is connected to b, c and d. + +You can cut three connections to split the system in half. What is the product of the number of nodes in each group +when you do that? \ No newline at end of file