Mercurial > repos > other > adventofcode2023
view day25.rb @ 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 | |
children |
line wrap: on
line source
#! /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)