-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathDay23.cs
122 lines (105 loc) · 3 KB
/
Day23.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
using System.Collections.Generic;
using System.Numerics;
using System.Threading.Tasks;
//Buggy mess of stuff not behaving as the AoC creator expected when asynchronous.
class Day23 {
public static int Solution1() {
Intcode referenceComputer = new Intcode("input23.txt", false);
Router router = new Router() {
isSolution1 = true
};
for (int address = 0; address < 50; address++) {
Intcode computer = referenceComputer.Duplicate();
computer.SetInput(new Queue<BigInteger>());
computer.InQueue.Enqueue(address);
computer.SetOutput(new Queue<BigInteger>());
router.inputs.Add(computer.OutQueue);
router.outputs[address] = computer.InQueue;
_ = computer.RunAsync();
}
return router.Start().Result;
}
public static int Solution2() {
Intcode referenceComputer = new Intcode("input23.txt", false);
Router router = new Router() {
isSolution1 = false
};
for (int address = 0; address < 50; address++) {
Intcode computer = referenceComputer.Duplicate();
computer.SetInput(new Queue<BigInteger>());
computer.InQueue.Enqueue(address);
computer.SetOutput(new Queue<BigInteger>());
router.inputs.Add(computer.OutQueue);
router.outputs[address] = computer.InQueue;
_ = computer.RunAsync();
}
return router.Start().Result;
}
class Router {
public readonly List<Queue<BigInteger>> inputs = new List<Queue<BigInteger>>();
public readonly Dictionary<int, Queue<BigInteger>> outputs = new Dictionary<int, Queue<BigInteger>>();
public bool isSolution1;
BigInteger x, y;
public async Task<int> Start() {
BigInteger lasty = int.MinValue;
int idleCount = 0;
while (true) {
bool inputEmpty = true;
foreach (Queue<BigInteger> input in inputs) {
while (input.Count >= 3) { //3 instructions necessary to send a packet
inputEmpty = false;
int destination;
BigInteger x, y;
lock (input) {
destination = (int)input.Dequeue();
x = input.Dequeue();
y = input.Dequeue();
}
if (destination == 255) {
if (isSolution1) {
return (int)y;
}
this.x = x;
this.y = y;
} else {
Queue<BigInteger> output = outputs[destination];
lock (output) {
output.Enqueue(x);
output.Enqueue(y);
}
}
}
}
//Check for system idle
bool outputEmpty = true;
foreach (Queue<BigInteger> output in outputs.Values) {
if (output.Count > 0) {
outputEmpty = false;
break;
}
}
if (inputEmpty) {
if (outputEmpty) {
idleCount++;
if (idleCount > 100) {
if (y == lasty) {
return (int)y;
}
lasty = y;
Queue<BigInteger> output = outputs[0];
lock (output) {
output.Enqueue(x);
output.Enqueue(y);
}
}
} else {
idleCount = 0;
}
await Task.Delay(1);
} else {
idleCount = 0;
}
}
}
}
}