示例#1
0
        static int SolveAlternate()
        {
            var machine     = new Machine(TextFile.ReadStringList("input.txt"));
            var target      = machine.Program.Count;
            var originalRun = machine.RunFrom(0);

            foreach (var i in originalRun)
            {
                var originalInstruction = machine.Program[i];
                var flippedInstruction  = InstructionFactory.Flip(originalInstruction);
                machine.Program[i] = flippedInstruction;

                var visited = machine.RunFrom(i);
                if (visited.Contains(target))
                {
                    machine.AC = 0;
                    machine.PC = 0;
                    machine.RunFrom(0);
                    return(machine.AC);
                }
                machine.Program[i] = originalInstruction;
            }
            return(-1);
        }
示例#2
0
 public Machine(List <string> program)
 {
     Program = program.Select(l => InstructionFactory.Parse(l)).ToList();
 }
示例#3
0
        static void Main(string[] args)
        {
            int acWithoutFlip = 0;
            int acAfterFlip   = 0;

            Performance.TimeRun("Read and solve", () =>
            {
                var machine   = new Machine(TextFile.ReadStringList("input.txt"));
                var visited   = machine.RunFrom(0);
                acWithoutFlip = machine.AC;

                var target = machine.Program.Count;
                HashSet <int> knownGood = new HashSet <int>();
                HashSet <int> knownBad  = new HashSet <int>(visited);
                for (int i = 1; i < machine.Program.Count; i++)
                {
                    if (knownBad.Contains(i) || knownGood.Contains(i))//this instruction has already been visited in a previous path
                    {
                        continue;
                    }
                    visited = machine.RunFrom(i);
                    if (visited.Contains(target))
                    {
                        knownGood.UnionWith(visited);
                    }
                    else
                    {
                        knownBad.UnionWith(visited);
                    }
                }

                machine.AC   = 0;
                machine.PC   = 0;
                bool flipped = false;

                while (machine.PC < machine.Program.Count)
                {
                    if (!flipped)
                    {
                        var candidate = NextIfFlipped(machine);
                        if (knownGood.Contains(candidate)) //flipping this instructions brings us to a "winning" path
                        {
                            var curr = machine.Program[machine.PC];
                            var flippedInstruction      = InstructionFactory.Flip(curr);
                            machine.Program[machine.PC] = flippedInstruction;
                            flipped = true;
                        }
                    }
                    machine.Step();
                }
                acAfterFlip = machine.AC;
            }, 100, 10);

            Performance.TimeRun("Alternate solve", () =>
            {
                acAfterFlip = SolveAlternate();
            }, 100, 10);

            Console.WriteLine($"AC before flip: {acWithoutFlip}");
            Console.WriteLine($"AC after flip: {acAfterFlip}");
        }