Ejemplo n.º 1
0
    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}");
        }
Ejemplo n.º 3
0
        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);
        }