Mercurial > hg > aoc
view 2017/day18.d @ 23:5cf02601cd14
day 18
author | Jordi Gutiérrez Hermoso <jordigh@octave.org> |
---|---|
date | Mon, 18 Dec 2017 23:35:03 -0500 |
parents | |
children | 776d882c78b8 |
line wrap: on
line source
import std.stdio; import std.array: array; import std.string: split; import std.conv: to, ConvException; import std.datetime: msecs; import std.concurrency; void runProgram(immutable string[] opcodes, ulong pid, Tid otherProg) { // Connect the two threads if (otherProg == ownerTid) { otherProg = receiveOnly!Tid(); } else { send(otherProg, thisTid()); } long ip = 0; long[char] regs = ['p': pid]; long sent = 0; while(0 <= ip && ip < opcodes.length) { auto opcode = opcodes[ip].split; auto op = opcode[0]; auto reg = opcode[1][0]; long val = 0; if (opcode.length > 2) { try { val = to!long(opcode[2]); } catch(ConvException){ val = regs.get(opcode[2][0], 0); } } switch(op) { case "snd": send(otherProg, regs.get(reg, 0)); sent++; goto default; case "rcv": if (!receiveTimeout(100.msecs, (long val) {regs[reg] = val;})) { goto done; } goto default; case "set": regs[reg] = val; goto default; case "add": regs[reg] = regs.get(reg, 0) + val; goto default; case "mul": regs[reg] = regs.get(reg, 0) * val; goto default; case "mod": regs[reg] = regs.get(reg, 0) % val; goto default; case "jgz": long cmp; try { cmp = to!long(opcode[1]); } catch(ConvException) { cmp = regs.get(reg, 0); } if (cmp > 0) { ip += val; break; } goto default; default: ip++; } } // We're done, dad! done: send(ownerTid, thisTid, sent); } void main(string[] args) { immutable auto opcodes = File(args[1]).byLineCopy.array.idup; auto tid1 = spawn(&runProgram, opcodes, 0, thisTid); auto tid2 = spawn(&runProgram, opcodes, 1, tid1); // Wait for both children to let us know they're done. auto done1 = receiveOnly!(Tid, long); auto done2 = receiveOnly!(Tid, long); if (done1[0] == tid2) { writeln(done1[1]); } else { writeln(done2[1]); } }