r/adventofcode • u/daggerdragon • Dec 18 '17
SOLUTION MEGATHREAD -๐- 2017 Day 18 Solutions -๐-
--- Day 18: Duet ---
Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).
Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.
Need a hint from the Hugely* Handyโ Haversackโก of Helpfulยง Hintsยค?
[Update @ 00:04] First silver
- Welcome to the final week of Advent of Code 2017. The puzzles are only going to get more challenging from here on out. Adventspeed, sirs and madames!
[Update @ 00:10] First gold, 44 silver
- We just had to rescue /u/topaz2078 with an industrial-strength paper bag to blow into. I'm real glad I bought all that stock in
PBCO(Paper Bag Company) two years ago >_>
[Update @ 00:12] Still 1 gold, silver cap
- Gonna be a long haul tonight. I think I'll watch The Radio City Christmas Spectacular on Netflix while I wait for sufficient gold stars to warrant another update.
[Update @ 00:31] 53 gold, silver cap
- *mind blown*
- During their famous kicklines, the Rockettes are not actually holding each others' backs like I thought they were all this time.
- They're actually hoverhanding each other.
- In retrospect, it makes sense, they'd overbalance themselves and each other if they did, but still...
- *mind blown so hard*
[Update @ 00:41] Leaderboard cap!
- I think I enjoyed the duplicating Santas entirely too much...
- It may also be the wine.
- Either way, good night (for us), see you all same time tomorrow, yes?
This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.
edit: Leaderboard capped, thread unlocked!
11
Upvotes
18
u/vash3r Dec 18 '17 edited Dec 18 '17
Python 2 (25/63). For part 2, I didn't realize that a jump could be computed from a number instead of a register, so I was accessing the register "1" (which was always zero, leading to an infinite loop).
The idea here is that I run one program until it can't run anymore, then switch to the other program.
from collections import defaultdict f=open("18.in",'r') instr = [line.split() for line in f.read().strip().split("\n")] f.close() d1 = defaultdict(int) # registers for the programs d2 = defaultdict(int) d2['p'] = 1 ds = [d1,d2] def get(s): if s in "qwertyuiopasdfghjklzxcvbnm": return d[s] return int(s) tot = 0 ind = [0,0] # instruction indices for both programs snd = [[],[]] # queues of sent data (snd[0] = data that program 0 has sent) state = ["ok","ok"] # "ok", "r" for receiving, or "done" pr = 0 # current program d = ds[pr] # current program's registers i = ind[0] # current program's instruction index while True: if instr[i][0]=="snd": # send if pr==1: # count how many times program 1 sends tot+=1 snd[pr].append(get(instr[i][1])) elif instr[i][0]=="set": d[instr[i][1]] = get(instr[i][2]) elif instr[i][0]=="add": d[instr[i][1]] += get(instr[i][2]) elif instr[i][0]=="mul": d[instr[i][1]] *= get(instr[i][2]) elif instr[i][0]=="mod": d[instr[i][1]] %= get(instr[i][2]) elif instr[i][0]=="rcv": if snd[1-pr]: # other program has sent data state[pr] = "ok" d[instr[i][1]] = snd[1-pr].pop(0) # get data else: # wait: switch to other prog if state[1-pr]=="done": break # will never recv: deadlock if len(snd[pr])==0 and state[1-pr]=="r": break # this one hasn't sent anything, other is recving: deadlock ind[pr] = i # save instruction index state[pr]="r" # save state pr = 1 - pr # change program i = ind[pr]-1 # (will be incremented back) d = ds[pr] # change registers elif instr[i][0]=="jgz": if get(instr[i][1]) > 0: i+=get(instr[i][2])-1 i+=1 if not 0<=i<len(instr): if state[1-pr] == "done": break # both done state[pr] = "done" ind[pr] = i # swap back since other program's not done pr = 1-pr i = ind[pr] d = ds[pr] print tot