comparison 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
comparison
equal deleted inserted replaced
22:4e7e7835f1db 23:5cf02601cd14
1 import std.stdio;
2 import std.array: array;
3 import std.string: split;
4 import std.conv: to, ConvException;
5 import std.datetime: msecs;
6 import std.concurrency;
7
8 void runProgram(immutable string[] opcodes, ulong pid, Tid otherProg) {
9 // Connect the two threads
10 if (otherProg == ownerTid) {
11 otherProg = receiveOnly!Tid();
12 } else {
13 send(otherProg, thisTid());
14 }
15
16 long ip = 0;
17 long[char] regs = ['p': pid];
18 long sent = 0;
19
20 while(0 <= ip && ip < opcodes.length) {
21 auto opcode = opcodes[ip].split;
22 auto op = opcode[0];
23 auto reg = opcode[1][0];
24 long val = 0;
25 if (opcode.length > 2) {
26 try {
27 val = to!long(opcode[2]);
28 }
29 catch(ConvException){
30 val = regs.get(opcode[2][0], 0);
31 }
32 }
33 switch(op) {
34 case "snd":
35 send(otherProg, regs.get(reg, 0));
36 sent++;
37 goto default;
38 case "rcv":
39 if (!receiveTimeout(100.msecs, (long val) {regs[reg] = val;})) {
40 goto done;
41 }
42 goto default;
43 case "set":
44 regs[reg] = val;
45 goto default;
46 case "add":
47 regs[reg] = regs.get(reg, 0) + val;
48 goto default;
49 case "mul":
50 regs[reg] = regs.get(reg, 0) * val;
51 goto default;
52 case "mod":
53 regs[reg] = regs.get(reg, 0) % val;
54 goto default;
55 case "jgz":
56 long cmp;
57 try {
58 cmp = to!long(opcode[1]);
59 }
60 catch(ConvException) {
61 cmp = regs.get(reg, 0);
62 }
63 if (cmp > 0) {
64 ip += val;
65 break;
66 }
67 goto default;
68 default:
69 ip++;
70 }
71 }
72
73 // We're done, dad!
74 done:
75 send(ownerTid, thisTid, sent);
76 }
77
78 void main(string[] args) {
79 immutable auto opcodes = File(args[1]).byLineCopy.array.idup;
80 auto tid1 = spawn(&runProgram, opcodes, 0, thisTid);
81 auto tid2 = spawn(&runProgram, opcodes, 1, tid1);
82
83 // Wait for both children to let us know they're done.
84 auto done1 = receiveOnly!(Tid, long);
85 auto done2 = receiveOnly!(Tid, long);
86 if (done1[0] == tid2) {
87 writeln(done1[1]);
88 }
89 else {
90 writeln(done2[1]);
91 }
92 }