My Advent of Code solutions in Python. kevinyap.ca/2019/12/going-fast-in-advent-of-code/
advent-of-code python
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Update 2017/day18.py

The two programs in Part 2 don't need to run in lockstep, so we only
actually need to yield at `rcv` instructions (each program can execute
independently until it gets stuck waiting to receive a value). This
means that no special logic needs to be introduced for Part 1.

+20 -29
+20 -29
2017/day18.py
··· 2 2 from collections import deque, defaultdict 3 3 4 4 5 - def duet_program(ops, regs, snd_q, rcv_q, part_1=False): 5 + def duet_program(instrs, snd_q, rcv_q, pid=None): 6 + regs = defaultdict(int) 7 + if pid is not None: 8 + regs['p'] = pid 9 + 6 10 pc = 0 7 11 sends = 0 8 12 9 - while 0 <= pc < len(ops): 10 - op, x, y = ops[pc] 13 + while 0 <= pc < len(instrs): 14 + op, x, y = instrs[pc] 11 15 y = regs[y] if y.isalpha() else int(y) 12 16 13 17 if op == 'snd': ··· 22 26 elif op == 'mod': 23 27 regs[x] %= y 24 28 elif op == 'rcv': 25 - if part_1: 26 - raise StopIteration 29 + if len(rcv_q) > 0: 30 + regs[x] = rcv_q.pop() 27 31 else: 28 - if len(rcv_q) > 0: 29 - regs[x] = rcv_q.pop() 30 - else: 31 - yield op, sends 32 - continue 32 + yield op, sends 33 + continue 33 34 elif op == 'jgz': 34 35 if (regs[x] if x.isalpha() else int(x)) > 0: 35 36 pc += y 36 - yield op, sends 37 37 continue 38 38 39 39 pc += 1 40 - yield op, sends 41 40 42 41 raise StopIteration 43 42 44 43 45 44 # Read puzzle input 46 - OPS = [] 45 + INSTRS = [] 47 46 48 47 for line in fileinput.input(): 49 - parts = line.strip().split() 50 - op, x = parts[:2] 51 - y = 'foo' if len(parts) == 2 else parts[2] 52 - OPS.append((op, x, y)) 48 + instr = line.strip() + ' foo' 49 + op, x, y = instr.split()[:3] 50 + INSTRS.append((op, x, y)) 53 51 54 52 55 53 # Part 1 56 - regs = defaultdict(int) 57 54 snd_queue = deque() 58 - 59 - for _ in duet_program(OPS, regs, snd_queue, deque(), part_1=True): 60 - pass 55 + program = duet_program(INSTRS, snd_queue, deque()) 56 + next(program) 61 57 62 58 print "Value of recovered frequency:", snd_queue[0] 63 59 64 60 65 61 # Part 2 66 - regs_0 = defaultdict(int) 67 - regs_1 = defaultdict(int) 68 - regs_0['p'] = 0 69 - regs_1['p'] = 1 70 - 71 62 queue_0 = deque() 72 63 queue_1 = deque() 73 64 65 + program_0 = duet_program(INSTRS, queue_1, queue_0, pid=0) 66 + program_1 = duet_program(INSTRS, queue_0, queue_1, pid=1) 67 + 74 68 last_op_0 = None 75 69 last_op_1 = None 76 - 77 - program_0 = duet_program(OPS, regs_0, queue_1, queue_0) 78 - program_1 = duet_program(OPS, regs_1, queue_0, queue_1) 79 70 80 71 while not (last_op_0 == last_op_1 == 'rcv' and len(queue_0) == len(queue_1) == 0): 81 72 last_op_0, _ = next(program_0)