Skip to content

Commit 767428b

Browse files
committedDec 19, 2024
Day 18
1 parent 38ec696 commit 767428b

File tree

1 file changed

+64
-0
lines changed

1 file changed

+64
-0
lines changed
 

‎18_duet.rb

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
def run(insts, id, tx, rx)
2+
regs = Hash.new(0)
3+
regs[:p] = id
4+
vals_received = 0
5+
pc = 0
6+
resolve = ->(y) { y.is_a?(Integer) ? y : regs[y] }
7+
8+
-> {
9+
ran_anything = false
10+
11+
while pc >= 0 && (inst = insts[pc])
12+
case inst[0]
13+
when :snd
14+
tx << resolve[inst[1]]
15+
when :set
16+
regs[inst[1]] = resolve[inst[2]]
17+
when :add
18+
regs[inst[1]] += resolve[inst[2]]
19+
when :mul
20+
regs[inst[1]] *= resolve[inst[2]]
21+
when :mod
22+
regs[inst[1]] %= resolve[inst[2]]
23+
when :rcv
24+
if tx.object_id == rx.object_id
25+
# Part 1!
26+
return rx[-1] if resolve[inst[1]] != 0
27+
else
28+
# Part 2!
29+
return ran_anything ? :wait : :still_waiting unless (val = rx[vals_received])
30+
vals_received += 1
31+
regs[inst[1]] = val
32+
end
33+
when :jgz
34+
pc += (resolve[inst[2]] - 1) if resolve[inst[1]] > 0
35+
else raise "Unknown instruction #{inst}"
36+
end
37+
38+
pc += 1
39+
ran_anything = true
40+
end
41+
42+
:finished
43+
}
44+
end
45+
46+
insts = ARGF.map { |l|
47+
inst, *args = l.split
48+
[inst.to_sym, *args.map { |a| a.match?(/-?\d+/) ? a.to_i : a.to_sym }].freeze
49+
}.freeze
50+
51+
sound = []
52+
puts run(insts, 0, sound, sound)[]
53+
54+
send = [[], []]
55+
runners = [0, 1].map { |id| run(insts, id, send[id], send[1 - id]) }
56+
other_was_waiting = false
57+
puts 0.step { |n|
58+
status = runners[n % 2][]
59+
if status == :still_waiting && other_was_waiting
60+
# Deadlocked.
61+
break send[1].size
62+
end
63+
other_was_waiting = status == :still_waiting
64+
}

0 commit comments

Comments
 (0)
Failed to load comments.