|
|
@@ -2,7 +2,10 @@
|
|
|
|
|
|
public class SignalProcessor
|
|
|
{
|
|
|
- private readonly IDictionary<string, Module> _modules = new Dictionary<string, Module>();
|
|
|
+ private readonly Dictionary<string, Module> _modules = new Dictionary<string, Module>();
|
|
|
+
|
|
|
+ private HashSet<string> _trackCycles = new HashSet<string>();
|
|
|
+ private Dictionary<string, List<long>> _cycleLengths = new Dictionary<string, List<long>>();
|
|
|
|
|
|
public SignalProcessor(Dictionary<string, (Module m, string[] outputs)> modules)
|
|
|
{
|
|
|
@@ -30,6 +33,7 @@ public class SignalProcessor
|
|
|
|
|
|
public HiLo Push(int count)
|
|
|
{
|
|
|
+ Reset();
|
|
|
var visited = new HashSet<string>();
|
|
|
var stateCounts = new List<HiLo>();
|
|
|
var state = MachineState();
|
|
|
@@ -38,14 +42,14 @@ public class SignalProcessor
|
|
|
|
|
|
while (!visited.Contains(state) && iterations < count)
|
|
|
{
|
|
|
- Console.WriteLine(state);
|
|
|
+ //Console.WriteLine(state);
|
|
|
visited.Add(state);
|
|
|
- var hilo = PushTheButton();
|
|
|
+ iterations++;
|
|
|
+ var hilo = PushTheButton(iterations);
|
|
|
|
|
|
stateCounts.Add(hilo);
|
|
|
result = result.Add(hilo);
|
|
|
state = MachineState();
|
|
|
- iterations++;
|
|
|
}
|
|
|
|
|
|
if (iterations == 0)
|
|
|
@@ -68,7 +72,7 @@ public class SignalProcessor
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
- public HiLo PushTheButton()
|
|
|
+ public HiLo PushTheButton(int iteration)
|
|
|
{
|
|
|
var count = HiLo.Zero;
|
|
|
var queue = new Queue<Pulse>();
|
|
|
@@ -77,7 +81,12 @@ public class SignalProcessor
|
|
|
while (queue.Count > 0)
|
|
|
{
|
|
|
var pulse = queue.Dequeue();
|
|
|
- Console.WriteLine($"Sending {pulse.Value} from {pulse.Source} to {pulse.Destination}");
|
|
|
+ if (_trackCycles.Contains(pulse.Source) && pulse.Value)
|
|
|
+ {
|
|
|
+ _cycleLengths.TryAdd(pulse.Source, new List<long>());
|
|
|
+ _cycleLengths[pulse.Source].Add(iteration);
|
|
|
+ }
|
|
|
+ //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))
|
|
|
@@ -93,4 +102,45 @@ public class SignalProcessor
|
|
|
{
|
|
|
return string.Join("|", _modules.Select(kvp => kvp.Value.GetState()));
|
|
|
}
|
|
|
+
|
|
|
+ public long WaitFor(string sentry)
|
|
|
+ {
|
|
|
+ Reset();
|
|
|
+ var iterations = 0;
|
|
|
+ var sentryInputs = _modules[sentry].Inputs.Single().Inputs.Select(m => m.Name).ToList();
|
|
|
+ _trackCycles = new HashSet<string>(sentryInputs);
|
|
|
+ _cycleLengths = new Dictionary<string, List<long>>();
|
|
|
+
|
|
|
+ while (iterations < 100000)
|
|
|
+ {
|
|
|
+ iterations++;
|
|
|
+ PushTheButton(iterations);
|
|
|
+ }
|
|
|
+
|
|
|
+ var lcmFactors = new HashSet<long>();
|
|
|
+ foreach (var kvp in _cycleLengths)
|
|
|
+ {
|
|
|
+ var first = kvp.Value.First();
|
|
|
+ if (kvp.Value.Any(x => x % first != 0))
|
|
|
+ {
|
|
|
+ throw new Exception($"Mismatching cycle '{kvp.Key}' => {string.Join("\n", kvp.Value)}");
|
|
|
+ }
|
|
|
+
|
|
|
+ foreach (var prime in Primes.Factorize(first))
|
|
|
+ {
|
|
|
+ lcmFactors.Add(prime);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ var lcm = lcmFactors.Aggregate(1L, (acc, item) => acc * item);
|
|
|
+ return lcm;
|
|
|
+ }
|
|
|
+
|
|
|
+ private void Reset()
|
|
|
+ {
|
|
|
+ foreach (var kvp in _modules)
|
|
|
+ {
|
|
|
+ kvp.Value.Reset();
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|