| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- 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()));
- }
- }
|