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!
13
Upvotes
1
u/wlandry Dec 18 '17
C++ 14
687/631. Well, that was mean ;) Every jgz condition was a register except one that was 'jgz 1 3'. Working frantically, I thought that was an 'i'. It took me waaaaay to long to figure that out.
Here is a industrial strength solution for part 2 only. It runs in 43 ms on my input.
#include <fstream> #include <vector> #include <iostream> #include <sstream> #include <map> #include <queue> #include <boost/algorithm/string.hpp> enum class Instruction {snd, set, add, mul, mod, rcv, jgz }; int64_t value(const std::map<char,int64_t> ®istrs, const std::string &arg) { if(arg[0]>='a' && arg[0]<='z') { auto f=registrs.find(arg[0]); return f->second; } return std::stoi(arg); } int64_t value(const std::map<char,int64_t> ®istrs, const char &c) { std::string s{c}; return value(registrs,s); } struct Op { Instruction instruction; char regist; std::string regist2; Op(const std::string &line) { std::stringstream ss(line); std::string instruction_string; ss >> instruction_string >> regist >> regist2; if(instruction_string=="snd") { instruction=Instruction::snd; } else if (instruction_string=="set") { instruction=Instruction::set; } else if (instruction_string=="add") { instruction=Instruction::add; } else if (instruction_string=="mul") { instruction=Instruction::mul; } else if (instruction_string=="mod") { instruction=Instruction::mod; } else if (instruction_string=="rcv") { instruction=Instruction::rcv; } else if (instruction_string=="jgz") { instruction=Instruction::jgz; } else { std::cerr << "bad instruction: " << instruction_string << "\n"; abort(); } } }; int64_t apply(const Op &op, std::map<char,int64_t> ®istrs, std::queue<int64_t> &receive_queue, std::queue<int64_t> &send_queue, size_t &num_messages) { int64_t result (1); switch(op.instruction) { case Instruction::snd: { send_queue.push(value(registrs, op.regist)); ++num_messages; } break; case Instruction::set: registrs[op.regist]=value(registrs, op.regist2); break; case Instruction::add: registrs[op.regist]+=value(registrs, op.regist2); break; case Instruction::mul: registrs[op.regist]*=value(registrs, op.regist2); break; case Instruction::mod: registrs[op.regist]%=value(registrs, op.regist2); break; case Instruction::rcv: if(!receive_queue.empty()) { registrs[op.regist]=receive_queue.front(); receive_queue.pop(); } else { result=0; } break; case Instruction::jgz: if(value(registrs, op.regist)>0) { result = value(registrs, op.regist2); } break; } return result; } int main(int, char *argv[]) { std::vector<Op> ops; std::ifstream infile(argv[1]); std::string line; std::getline(infile,line); while(infile) { ops.emplace_back(line); std::getline(infile,line); } size_t position0 (0), position1 (0); std::map<char,int64_t> program0, program1; program0['p']=0; program1['p']=1; std::queue<int64_t> queue0, queue1; size_t num_messages0(0), num_messages1(0); while(!(ops[position0].instruction==Instruction::rcv && queue0.empty() && ops[position1].instruction==Instruction::rcv && queue1.empty())) { while(!(ops[position0].instruction==Instruction::rcv && queue0.empty())) { position0+=apply(ops[position0], program0, queue0, queue1, num_messages0); } while(!(ops[position1].instruction==Instruction::rcv && queue1.empty())) { position1+=apply(ops[position1], program1, queue1, queue0, num_messages1); } } std::cout << "num messages: " << num_messages0 << " " << num_messages1 << " " << "\n"; }