Пример #1
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));
        }