|
|
@@ -0,0 +1,96 @@
|
|
|
+namespace Day20;
|
|
|
+
|
|
|
+public class SignalProcessor
|
|
|
+{
|
|
|
+ private readonly IDictionary<string, Module> _modules = new Dictionary<string, Module>();
|
|
|
+
|
|
|
+ public SignalProcessor(Dictionary<string, (Module m, string[] outputs)> modules)
|
|
|
+ {
|
|
|
+ foreach (var kvp in modules)
|
|
|
+ {
|
|
|
+ _modules[kvp.Key] = kvp.Value.m;
|
|
|
+ foreach (var o in kvp.Value.outputs)
|
|
|
+ {
|
|
|
+ Module? dst;
|
|
|
+ if (modules.TryGetValue(o, out var t))
|
|
|
+ {
|
|
|
+ dst = modules[o].m;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ _modules.TryAdd(o, new SinkModule(o));
|
|
|
+ dst = _modules[o];
|
|
|
+ }
|
|
|
+
|
|
|
+ kvp.Value.m.AddOutput(dst);
|
|
|
+ dst.AddInput(kvp.Value.m);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public HiLo Push(int count)
|
|
|
+ {
|
|
|
+ var visited = new HashSet<string>();
|
|
|
+ var stateCounts = new List<HiLo>();
|
|
|
+ var state = MachineState();
|
|
|
+ var iterations = 0;
|
|
|
+ var result = HiLo.Zero;
|
|
|
+
|
|
|
+ while (!visited.Contains(state) && iterations < count)
|
|
|
+ {
|
|
|
+ Console.WriteLine(state);
|
|
|
+ visited.Add(state);
|
|
|
+ var hilo = PushTheButton();
|
|
|
+
|
|
|
+ stateCounts.Add(hilo);
|
|
|
+ result = result.Add(hilo);
|
|
|
+ state = MachineState();
|
|
|
+ iterations++;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (iterations == 0)
|
|
|
+ {
|
|
|
+ throw new InvalidOperationException("WTF?");
|
|
|
+ }
|
|
|
+
|
|
|
+ if (iterations < count)
|
|
|
+ {
|
|
|
+ Console.WriteLine($"Cycle @ {iterations} with state {state}");
|
|
|
+ var cycles = count / iterations;
|
|
|
+ result = result.Multiply(cycles);
|
|
|
+ var remainder = count % iterations;
|
|
|
+ for (var i = 0; i < remainder; i++)
|
|
|
+ {
|
|
|
+ result = result.Add(stateCounts[i]);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ public HiLo PushTheButton()
|
|
|
+ {
|
|
|
+ var count = HiLo.Zero;
|
|
|
+ var queue = new Queue<Pulse>();
|
|
|
+ queue.Enqueue(new Pulse("button", "broadcaster", false));
|
|
|
+
|
|
|
+ while (queue.Count > 0)
|
|
|
+ {
|
|
|
+ var pulse = queue.Dequeue();
|
|
|
+ Console.WriteLine($"Sending {pulse.Value} from {pulse.Source} to {pulse.Destination}");
|
|
|
+ var dst = _modules[pulse.Destination];
|
|
|
+ count = count.Add(pulse);
|
|
|
+ foreach (var outPulse in dst.Process(pulse))
|
|
|
+ {
|
|
|
+ queue.Enqueue(outPulse);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return count;
|
|
|
+ }
|
|
|
+
|
|
|
+ private string MachineState()
|
|
|
+ {
|
|
|
+ return string.Join("|", _modules.Select(kvp => kvp.Value.GetState()));
|
|
|
+ }
|
|
|
+}
|