-
Notifications
You must be signed in to change notification settings - Fork 0
/
day20.cs
141 lines (125 loc) · 4.51 KB
/
day20.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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
using System.Data;
using System.Diagnostics.Contracts;
using System.Drawing;
using System.Text.RegularExpressions;
abstract class relay{
abstract public void handleSignal(signal sig, ref Queue<signal> queue, ref SortedDictionary<string, relay> allRelays);
protected IEnumerable<relay> inputs {get;set;}
public string name{get;set;}
public List<string> outputs {get;set;}
protected void sendToAllFollowers(bool high, ref Queue<signal> queue, ref SortedDictionary<string, relay> allRelays){
foreach (var item in outputs)
{
if (allRelays.ContainsKey(item))
queue.Enqueue(new signal(){from=this, to=allRelays[item], high=high});
else
queue.Enqueue(new signal(){from=this, high=high});
}
}
}
class flipflop:relay{
private bool state = false;
public override void handleSignal(signal sig, ref Queue<signal> queue, ref SortedDictionary<string, relay> allRelays){
if (sig.high) return;
state=!state;
this.sendToAllFollowers(state, ref queue, ref allRelays);
}
}
class conj:relay{
private SortedDictionary<string, bool> states = null;
private void initStates(ref SortedDictionary<string, relay> allRelays){
if (states == null){
states=new();
this.inputs = allRelays.Values.Where(a=> a.outputs.Contains(this.name));
foreach (var item in this.inputs)
{
states.Add(item.name, false);
}
}
}
public override void handleSignal(signal sig, ref Queue<signal> queue, ref SortedDictionary<string, relay> allRelays){
initStates(ref allRelays);
states[sig.from.name]=sig.high;
this.sendToAllFollowers(!states.Values.All(a=>a==true), ref queue, ref allRelays);
}
}
class broadcaster:relay{
public override void handleSignal(signal sig, ref Queue<signal> queue, ref SortedDictionary<string, relay> allRelays){
this.sendToAllFollowers(false, ref queue, ref allRelays);
}
}
class signal{
public bool high{get;set;}
public relay from {get;set;}
public relay to{get;set;}
}
static class Day20 {
static List<string> lines;
static Queue<signal> sigQueue = new();
internal static void doit() {
Regex dayNoR = new(@"\d*$");
var input = Helper.getInput(int.Parse(dayNoR.Match(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.Name).Value));
// input = """
// broadcaster -> a, b, c
// %a -> b
// %b -> c
// %c -> inv
// &inv -> a
// """;
broadcaster starter = null;
SortedDictionary<string, relay> allRelays = new();
lines = Helper.getLines(input);
for (int i = 0; i < lines.Count; i++)
{
var parts = lines[i].Split("->", StringSplitOptions.TrimEntries);
var ziele = parts[1].Split(",",StringSplitOptions.TrimEntries);
relay r = null;
switch (lines[i][0])
{
case '%':
r = new flipflop();
parts[0] = parts[0][1..];
break;
case '&':
r = new conj();
parts[0] = parts[0][1..];
break;
default:
r = new broadcaster();
break;
}
r.outputs = new List<string>(ziele);
r.name=parts[0];
if (r is broadcaster rbroad) {
starter=rbroad;
continue;
}
allRelays.Add(r.name, r);
}
var lowCounter = 0L;
var highCounter = 0L;
for (int i = 0; true; i++)
{
var rxCounter=0;
starter.handleSignal(new signal(){ high=false}, ref sigQueue, ref allRelays);
lowCounter++;
while (sigQueue.Count>0) {
var sig = sigQueue.Dequeue();
if (sig.high)
highCounter++;
else
lowCounter++;
//Console.WriteLine((sig.from.name??"") + " -" + (sig.high ? "high" : "low") + "-> " + sig.to.name ?? "" );
if (sig.to != null) sig.to.handleSignal(sig,ref sigQueue, ref allRelays); else rxCounter++;
}
if (i == 1000) {
Console.WriteLine("a: " + lowCounter*highCounter);
}
if (rxCounter == 1) {
Console.WriteLine("PartB: " + i+1);
}
}
long sumB=0;
// Console.WriteLine("b: " + sumB);
}
}