Пример #1
0
        private static void PerformTest(InstructionTestSet set)
        {
            //Log.WriteLine("Beginning test for " + set.TestNumber);
            int[] registers;
            int[] command;

            foreach (var kvp in _allOpCodes)
            {
                var opcode = kvp.Value;

                // Step 1, create a clean state as desired by the test
                registers = new int[4];
                Array.Copy(set.InitialRegisterState, registers, registers.Length);
                command = new int[4];                 // Hypothetically, this should not be required - but we track it for debug reasons
                Array.Copy(set.Command, command, command.Length);

                // Step 2, run the command and check that it could make sense i.e. doesn't attempt to address outside the register range
                if (opcode.Execute(command, registers))
                {
                    for (int i = 0; i < command.Length; i++)
                    {
                        if (set.Command[i] != command[i])
                        {
                            Log.WriteLine("Command arguments were mutated for command " + opcode.Name);
                        }
                    }

                    // Step 3, check the results of the commands
                    bool allMatch = true;
                    for (int i = 0; i < registers.Length; i++)
                    {
                        if (set.FinalRegisterState[i] != registers[i])
                        {
                            allMatch = false;
                            break;
                        }
                    }

                    if (allMatch)
                    {
                        //Log.WriteLine("Test Number " + set.TestNumber + " - " + opcode.Name + " matches!");
                        set.MatchingOpCodes.Add(opcode.Name);
                        //Log.WriteLine(set.DebugLog());
                        //Log.WriteLine(DumpRegisters(registers));
                    }
                    else
                    {
                        //Log.WriteLine("Test Number " + set.TestNumber + " - " + opcode.Name + " did not match");
                        //Log.WriteLine(set.DebugLog());
                        //Log.WriteLine(DumpRegisters(registers));
                    }
                }
                else
                {
                    Log.WriteLine("Test Number " + set.TestNumber + " - " + opcode.Name + " did not execute");
                }
            }
        }
Пример #2
0
            public static InstructionTestSet Parse(string first, string middle, string last, int testNumber)
            {
                InstructionTestSet set = new InstructionTestSet();

                set.InitialRegisterState = ParseRegisterState(first);
                set.FinalRegisterState   = ParseRegisterState(last);
                set.Command = ParseCommand(middle);

                set.TestNumber = testNumber;
                return(set);
            }
Пример #3
0
        public static void Solve()
        {
            int sum = 0;

            string inputPath = FileUtils.GetProjectFilePath("Days/Day16/ProblemA/input.txt");

            string[] allLines = File.ReadAllLines(inputPath);

            List <InstructionTestSet> tests = new List <InstructionTestSet>();
            int sets = 0;

            for (int i = 0; i < allLines.Length; i++)
            {
                string line = allLines[i];
                if (line.StartsWith("Before"))
                {
                    tests.Add(InstructionTestSet.Parse(allLines[i], allLines[i + 1], allLines[i + 2], sets));
                    sets++;
                }
            }
            Log.WriteLine("Beginning " + tests.Count + " tests");

            BuildOpCodes();

            foreach (var set in tests)
            {
                PerformTest(set);
            }

            int totalAmbigious = 0;

            foreach (var set in tests)
            {
                if (set.NumMatchingOpCodes >= 3)
                {
                    totalAmbigious++;
                }
                //Log.WriteLine("Test number " + set.TestNumber + " had " + set.NumMatchingOpCodes + " matching opcodes");
            }
            Log.WriteLine(totalAmbigious + " tests had ambigious op codes");
        }
Пример #4
0
        public static void Solve()
        {
            int sum = 0;

            string inputPath = FileUtils.GetProjectFilePath("Days/Day16/ProblemB/input.txt");

            string[] allLines = File.ReadAllLines(inputPath);

            List <InstructionTestSet> tests = new List <InstructionTestSet>();
            int sets = 0;

            for (int i = 0; i < allLines.Length; i++)
            {
                string line = allLines[i];
                if (line.StartsWith("Before"))
                {
                    tests.Add(InstructionTestSet.Parse(allLines[i], allLines[i + 1], allLines[i + 2], sets));
                    sets++;
                }
            }


            BuildOpCodes();
            //Log.WriteLine("Stage 1 - Figure out the minimum set of commands supported by the data");
            foreach (var set in tests)
            {
                PerformTest(set);
                int           instructionId = set.Command[0];
                List <string> existing;
                if (_opCodeIds.TryGetValue(instructionId, out existing))
                {
                    List <string> cp = new List <string>();
                    foreach (var str in existing)
                    {
                        if (set.MatchingOpCodes.Contains(str))                         // Check to see if our hypothesis is still supported
                        {
                            cp.Add(str);
                        }
                    }
                    _opCodeIds[instructionId] = cp;
                }
                else
                {
                    existing = new List <string>();                    // This is the first time we have encountered this command, include all possible options
                    existing.AddRange(set.MatchingOpCodes);
                    _opCodeIds[instructionId] = existing;
                }
            }


            //DumpOpCodeState();

            //Log.WriteLine("Stage 2 - Repeatedly remove unique commands until we have everything disambiguated");
            HashSet <string> removalList = new HashSet <string>();

            while (OpCodesAreAmbiguous())
            {
                string toRemove = null;

                foreach (var kvp in _opCodeIds)
                {
                    if (kvp.Value.Count == 1 && !removalList.Contains(kvp.Value[0]))
                    {
                        toRemove = kvp.Value[0];
                        removalList.Add(kvp.Value[0]);
                        break;
                    }
                }
                if (toRemove == null)
                {
                    break;
                }

                foreach (var kvp in _opCodeIds)
                {
                    if (kvp.Value.Count > 1 && kvp.Value.Contains(toRemove))
                    {
                        kvp.Value.Remove(toRemove);
                    }
                }
            }

            //Log.WriteLine("Finished figuring out commands");
            //DumpOpCodeState();

            int[] registers = new int[4];

            int programStartPoint = sets * 4;

            for (int i = programStartPoint; i < allLines.Length; i++)
            {
                string line = allLines[i].Trim();
                if (!string.IsNullOrEmpty(line))
                {
                    int[]  commandArgs = InstructionTestSet.ParseCommand(line);
                    string opCode      = _opCodeIds[commandArgs[0]][0];
                    var    op          = _allOpCodes[opCode];
                    if (!op.Execute(commandArgs, registers))
                    {
                        Log.WriteLine("Failed to execute line " + i);
                    }
                }
            }
            Log.WriteLine("Program finished, register state is " + DumpRegisters(registers));
        }