Mercurial > hg > aoc
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 } |