Mercurial > repos > other > adventofcode2023
view day20.rb @ 38:8e92cb172e6b
Output final distance
Also minor code cleanup
author | IBBoard <dev@ibboard.co.uk> |
---|---|
date | Fri, 20 Sep 2024 20:30:11 +0100 |
parents | 739415015d27 |
children |
line wrap: on
line source
#! /usr/bin/env ruby 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] FlipFlop = Struct.new(:state, :next) Conjunction = Struct.new(:state, :next) SignalMessage = Struct.new(:source, :state, :target) nodes = Hash.new broadcast = [] File.open(file, "r").each_line(chomp: true) do |line| input, output = line.split(" -> ") outputs = output.split(", ") if input[0] == "&" nodes[input[1..-1]] = Conjunction.new(Hash.new, outputs) elsif input[0] == "%" nodes[input[1..-1]] = FlipFlop.new(false, outputs) else broadcast = outputs end end nodes.each do |node_name, node| node.next.each do |target_name| target_node = nodes[target_name] if target_node.is_a?(Conjunction) target_node.state[node_name] = false end end end button_presses = 1000 high_count = 0 low_count = 0 button_presses.times do |press| low_count += 1 signals = [] processed = [] broadcast.each {|output| signals << SignalMessage.new("broadcast", false, output)} while signals.length > 0 #puts "#{signals}" signal = signals.shift() if signal.state high_count += 1 else low_count += 1 end target = nodes[signal.target] if target.nil? puts "Inactive node '#{signal.target}'" elsif target.is_a?(FlipFlop) # High signals stop here next if signal.state # Low signals affect state target.state = !target.state target.next.each {|output| signals << SignalMessage.new(signal.target, target.state, output)} elsif target.is_a?(Conjunction) target.state[signal.source] = signal.state all_high = target.state.values.all? target.next.each {|output| signals << SignalMessage.new(signal.target, !all_high, output)} end end end puts "Low: #{low_count}; High: #{high_count}; Score: #{low_count * high_count}"