Beispiel #1
0
        // Flips exactly one(1) instruction from Nop->Jmp or Jmp->Nop so the program can run all the way through.
        // Prints the accumulator after that.
        // Correct answer: 1703
        public int SolutionPart2()
        {
            // list of all indices of Instructions that can be reached if starting from the last instruction and working backwards
            List <int> vmReversed = InstructionMethods.BackTravelFromIndex(allInstructions, allInstructions.Count - 1);

            int accumulator = 0;
            // VM should run from the top
            int currentIndex = 0;
            // Current instruction in the loop and a tempInstruction used for switching
            Instruction currInstr;
            Instruction tempInstr = null;

            // if the switch is found, no reason to test anymore
            bool switchFound = false;

            // Program should stop when the index reaches the end
            while (currentIndex != allInstructions.Count)
            {
                currInstr = allInstructions[currentIndex];

                // test for Instruction type and makes a temp swapped version of it.
                if (!switchFound)
                {
                    if (currInstr is Nop)
                    {
                        tempInstr = InstructionMethods.SwapType <Jmp>(currInstr);
                    }
                    else if (currInstr is Jmp)
                    {
                        tempInstr = InstructionMethods.SwapType <Nop>(currInstr);
                    }
                }

                // if the next index of the swapped instruction is in the vmreversed list -
                // then the switch will cause the program to complete
                if (tempInstr != null && vmReversed.Contains(tempInstr.NextIndex))
                {
                    // current instruction is set to the swapped
                    currInstr   = tempInstr;
                    switchFound = true;
                }
                // current instruction runs its action against index and accumulator
                currInstr.Action(ref currentIndex, ref accumulator);
                // the temp instruction is removed
                tempInstr = null;
            }
            return(accumulator);
        }
Beispiel #2
0
        //
        // From a List of Instructions and a Index, travels backwards and makes a list of all instructions visited that way.
        public static List <int> BackTravelFromIndex(List <Instruction> instructions, int fromIndex)
        {
            // Uses Graph traversal logic - the list of instructions never change.
            List <int>  visitedInstructions = new List <int>();
            Instruction currInstr           = instructions[fromIndex];

            // always add current index to the list
            visitedInstructions.Add(currInstr.Index);

            // returns from here, if no instructions leads to the current instruction
            if (currInstr.FormerIndices.Count == 0)
            {
                return(visitedInstructions);
            }

            foreach (int index in currInstr.FormerIndices)
            {
                visitedInstructions.AddRange(InstructionMethods.BackTravelFromIndex(instructions, index));
            }
            return(visitedInstructions);
        }
Beispiel #3
0
 private void CreateInstructions()
 {
     allInstructions = InstructionMethods.CreateVM(dataList);
 }