Solve day 18 and 19 2017.
This commit is contained in:
109
2017/d18.py
Normal file
109
2017/d18.py
Normal file
@@ -0,0 +1,109 @@
|
||||
from lib import LETTERS_LOWER
|
||||
from collections import defaultdict, deque
|
||||
|
||||
|
||||
def get_value(regs, val):
|
||||
if val in LETTERS_LOWER:
|
||||
return regs[val]
|
||||
return int(val)
|
||||
|
||||
|
||||
def part_1(data):
|
||||
regs = defaultdict(int)
|
||||
insts = data.splitlines()
|
||||
last_sound = None
|
||||
pc = 0
|
||||
while pc <= len(insts):
|
||||
cmds = insts[pc].split()
|
||||
match cmds:
|
||||
case ["set", reg, val]:
|
||||
val = get_value(regs, val)
|
||||
regs[reg] = val
|
||||
case ["mul", reg, val]:
|
||||
val = get_value(regs, val)
|
||||
regs[reg] = regs[reg] * val
|
||||
case ["add", reg, val]:
|
||||
val = get_value(regs, val)
|
||||
regs[reg] = regs[reg] + val
|
||||
case ["mod", reg, val]:
|
||||
val = get_value(regs, val)
|
||||
regs[reg] = regs[reg] % val
|
||||
case ["rcv", val]:
|
||||
if get_value(regs, val) != 0:
|
||||
print(last_sound)
|
||||
return
|
||||
case ["snd", val]:
|
||||
last_sound = get_value(regs, val)
|
||||
case ["jgz", cnd, off]:
|
||||
if get_value(regs, cnd) > 0:
|
||||
pc += get_value(regs, off) # XXX?
|
||||
continue
|
||||
case _:
|
||||
print(cmds)
|
||||
assert False
|
||||
pc += 1
|
||||
|
||||
|
||||
def part_2(data):
|
||||
progs = []
|
||||
insts = data.splitlines()
|
||||
prog1_counter = 0
|
||||
|
||||
for i in [0, 1]:
|
||||
regs = defaultdict(int)
|
||||
regs["p"] = i
|
||||
pc = 0
|
||||
progs.append([pc, regs, False, deque()])
|
||||
|
||||
while not all(prog[2] for prog in progs):
|
||||
for prog in progs:
|
||||
pc, regs, waiting, queue = prog
|
||||
|
||||
cmds = insts[pc].split()
|
||||
match cmds:
|
||||
case ["set", reg, val]:
|
||||
val = get_value(regs, val)
|
||||
regs[reg] = val
|
||||
case ["mul", reg, val]:
|
||||
val = get_value(regs, val)
|
||||
regs[reg] = regs[reg] * val
|
||||
case ["add", reg, val]:
|
||||
val = get_value(regs, val)
|
||||
regs[reg] = regs[reg] + val
|
||||
case ["mod", reg, val]:
|
||||
val = get_value(regs, val)
|
||||
regs[reg] = regs[reg] % val
|
||||
case ["rcv", reg]:
|
||||
if queue:
|
||||
val = queue.popleft()
|
||||
regs[reg] = val
|
||||
else:
|
||||
prog[2] = True
|
||||
pc -= 1
|
||||
case ["snd", val]:
|
||||
val = get_value(regs, val)
|
||||
if prog == progs[0]:
|
||||
other_prog = progs[1]
|
||||
else:
|
||||
prog1_counter += 1
|
||||
other_prog = progs[0]
|
||||
other_prog[3].append(val)
|
||||
case ["jgz", cnd, off]:
|
||||
if get_value(regs, cnd) > 0:
|
||||
pc += get_value(regs, off) # XXX?
|
||||
pc -= 1
|
||||
case _:
|
||||
print(cmds)
|
||||
assert False
|
||||
prog[0] = pc + 1
|
||||
print(prog1_counter)
|
||||
|
||||
|
||||
def main():
|
||||
data = open(0).read().strip()
|
||||
part_1(data)
|
||||
part_2(data)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user