private static Circuit Parse(string input) { var circuit = new Circuit(); foreach (var line in input.Lines()) { var split = line.Split(" -> "); var instruction = split[0].Split(' '); var assigned = split[1]; if (instruction.Length == 1 && ushort.TryParse(instruction[0], out var constant)) { circuit[assigned] = new Circuit.Constant(constant); } else if (instruction.Length == 1) { circuit[assigned] = new Circuit.Assignment(circuit.NewVariable(instruction[0])); } else if (instruction.Length == 2 && instruction[0] == "NOT") { circuit[assigned] = new Not(New(instruction[1], circuit)); } else if (instruction.Length == 3 && instruction[1] == "LSHIFT" && ushort.TryParse(instruction[2], out var lshift)) { circuit[assigned] = new LShift(New(instruction[0], circuit), lshift); } else if (instruction.Length == 3 && instruction[1] == "RSHIFT" && ushort.TryParse(instruction[2], out var rshift)) { circuit[assigned] = new RShift(New(instruction[0], circuit), rshift); } else if (instruction.Length == 3 && instruction[1] == "OR") { circuit[assigned] = new Or(New(instruction[0], circuit), New(instruction[2], circuit)); } else if (instruction.Length == 3 && instruction[1] == "AND") { circuit[assigned] = new And(New(instruction[0], circuit), New(instruction[2], circuit)); } else { throw new FormatException($"'{line}' could not be parsed."); } } return(circuit);
public static void Test() { const int invocationTestCount = 256; const int iterations = 10000; var switches = new Switch[invocationTestCount]; var virtuals = new Superclass[invocationTestCount]; Random random = new Random(5); for (int i = 0; i < invocationTestCount; ++i) { var executionType = (ExecutionType)random.Next(12); switches[i].Type = executionType; switch (executionType) { case ExecutionType.Increment: virtuals[i] = new Increment(); break; case ExecutionType.Decrement: virtuals[i] = new Decrement(); break; case ExecutionType.LShift: virtuals[i] = new LShift(); break; case ExecutionType.RShift: virtuals[i] = new RShift(); break; case ExecutionType.Scramble1: virtuals[i] = new Scramble1(); break; case ExecutionType.Scramble2: virtuals[i] = new Scramble2(); break; case ExecutionType.Increment2: virtuals[i] = new Increment2(); break; case ExecutionType.Decrement2: virtuals[i] = new Decrement2(); break; case ExecutionType.LShift2: virtuals[i] = new LShift2(); break; case ExecutionType.RShift2: virtuals[i] = new RShift2(); break; case ExecutionType.Scramble12: virtuals[i] = new Scramble12(); break; case ExecutionType.Scramble22: virtuals[i] = new Scramble22(); break; } } int switchValue = 0; int virtualValue = 0; //Warmup. for (int i = 0; i < invocationTestCount; ++i) { switches[i].Do(ref switchValue); virtuals[i].Do(ref virtualValue); } var switchStart = Stopwatch.GetTimestamp(); for (int i = 0; i < iterations; ++i) { for (int j = 0; j < invocationTestCount; ++j) { switches[j].Do(ref switchValue); switches[j].Do(ref switchValue); switches[j].Do(ref switchValue); switches[j].Do(ref switchValue); switches[j].Do(ref switchValue); switches[j].Do(ref switchValue); switches[j].Do(ref switchValue); switches[j].Do(ref switchValue); switches[j].Do(ref switchValue); switches[j].Do(ref switchValue); } } var virtualStart = Stopwatch.GetTimestamp(); for (int i = 0; i < iterations; ++i) { for (int j = 0; j < invocationTestCount; ++j) { virtuals[j].Do(ref virtualValue); virtuals[j].Do(ref virtualValue); virtuals[j].Do(ref virtualValue); virtuals[j].Do(ref virtualValue); virtuals[j].Do(ref virtualValue); virtuals[j].Do(ref virtualValue); virtuals[j].Do(ref virtualValue); virtuals[j].Do(ref virtualValue); virtuals[j].Do(ref virtualValue); virtuals[j].Do(ref virtualValue); } } var virtualEnd = Stopwatch.GetTimestamp(); Console.WriteLine($"Switch time (ns): {1e9 * (virtualStart - switchStart) / (Stopwatch.Frequency * invocationTestCount * iterations * 10)}"); Console.WriteLine($"Virtual time (ns): {1e9 * (virtualEnd - virtualStart) / (Stopwatch.Frequency * invocationTestCount * iterations * 10)}"); Console.WriteLine($"Switch accumulator: {switchValue}, virtual accumulator: {virtualValue}"); }
public override Dictionary <string, Wire> ParseInput(string input) { var constants = new List <Wire>(); string GetTokenId(string id) { if (!constants.Any(c => c.Id == id) && ushort.TryParse(id, out var value)) { var constant = new Constant { Id = id, ConstantValue = value }; constants.Add(constant); } return(id); } var values = //"123 -> x\n456 -> y\nx AND y -> d\nx OR y -> e\nx LSHIFT 2 -> f\ny RSHIFT 2 -> g\nNOT x -> h\nNOT y -> i" input.Split('\n').Select(r => { var tokens = r.Split(' '); Wire wire = null; if (tokens.Any(t => t == "NOT")) { wire = new Not { NId = GetTokenId(tokens[1]) } } ; else if (tokens.Any(t => t == "AND")) { wire = new And { AId = GetTokenId(tokens[0]), BId = GetTokenId(tokens[2]) } } ; else if (tokens.Any(t => t == "OR")) { wire = new Or { AId = GetTokenId(tokens[0]), BId = GetTokenId(tokens[2]) } } ; else if (tokens.Any(t => t == "LSHIFT")) { wire = new LShift { IId = GetTokenId(tokens[0]), ShiftValue = ushort.Parse(tokens[2]) } } ; else if (tokens.Any(t => t == "RSHIFT")) { wire = new RShift { IId = GetTokenId(tokens[0]), ShiftValue = ushort.Parse(tokens[2]) } } ; else { wire = ushort.TryParse(tokens[0], out var value) ? (Wire) new Constant { ConstantValue = value } } : new Redirect { RId = tokens[0] }; wire.Id = tokens.Last(); wire.Raw = r; return(wire); }).Concat(constants).ToDictionary(w => w.Id); foreach (var value in values) { value.Value.Wires = values; } return(values); }