annotate day20.rb @ 30:6de4f4d5404d

Implement Day 21 "possible spaces in a maze" Part 2 needs something like "find the repeats and lowest common multiple" that I'm not bothering with
author IBBoard <dev@ibboard.co.uk>
date Wed, 03 Jan 2024 12:01:18 +0000
parents 739415015d27
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
29
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
1 #! /usr/bin/env ruby
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
2
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
3 if ARGV.length != 1
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
4 abort("Incorrect arguments - needs input file")
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
5 elsif not File.exist? (ARGV[0])
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
6 abort("File #{ARGV[0]} did not exist")
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
7 end
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
8
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
9 file = ARGV[0]
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
10
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
11 FlipFlop = Struct.new(:state, :next)
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
12 Conjunction = Struct.new(:state, :next)
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
13 SignalMessage = Struct.new(:source, :state, :target)
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
14
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
15 nodes = Hash.new
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
16 broadcast = []
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
17
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
18 File.open(file, "r").each_line(chomp: true) do |line|
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
19 input, output = line.split(" -> ")
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
20 outputs = output.split(", ")
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
21 if input[0] == "&"
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
22 nodes[input[1..-1]] = Conjunction.new(Hash.new, outputs)
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
23 elsif input[0] == "%"
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
24 nodes[input[1..-1]] = FlipFlop.new(false, outputs)
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
25 else
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
26 broadcast = outputs
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
27 end
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
28 end
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
29
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
30 nodes.each do |node_name, node|
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
31 node.next.each do |target_name|
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
32 target_node = nodes[target_name]
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
33 if target_node.is_a?(Conjunction)
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
34 target_node.state[node_name] = false
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
35 end
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
36 end
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
37 end
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
38
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
39 button_presses = 1000
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
40 high_count = 0
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
41 low_count = 0
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
42
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
43 button_presses.times do |press|
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
44 low_count += 1
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
45 signals = []
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
46 processed = []
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
47 broadcast.each {|output| signals << SignalMessage.new("broadcast", false, output)}
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
48 while signals.length > 0
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
49 #puts "#{signals}"
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
50 signal = signals.shift()
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
51 if signal.state
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
52 high_count += 1
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
53 else
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
54 low_count += 1
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
55 end
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
56 target = nodes[signal.target]
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
57 if target.nil?
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
58 puts "Inactive node '#{signal.target}'"
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
59 elsif target.is_a?(FlipFlop)
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
60 # High signals stop here
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
61 next if signal.state
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
62 # Low signals affect state
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
63 target.state = !target.state
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
64 target.next.each {|output| signals << SignalMessage.new(signal.target, target.state, output)}
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
65 elsif target.is_a?(Conjunction)
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
66 target.state[signal.source] = signal.state
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
67 all_high = target.state.values.all?
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
68 target.next.each {|output| signals << SignalMessage.new(signal.target, !all_high, output)}
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
69 end
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
70 end
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
71 end
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
72
739415015d27 Implement Day 20 switches part 1
IBBoard <dev@ibboard.co.uk>
parents:
diff changeset
73 puts "Low: #{low_count}; High: #{high_count}; Score: #{low_count * high_count}"