Beispiel #1
0
        /// <summary>
        /// JumpMan.Cmd entry point
        /// </summary>
        /// <param name="args">Command line arguments (not used)</param>
        static void Main(string[] args)
        {
            var filePath = "./input";
            var reader   = new FileReader();
            var program  = reader
                           .ReadFileByLines(filePath)
                           .Select(operation => new Operation(operation));
            var cpu = new JumpmanCPU(program);

            cpu.AddHaltingRule(
                (cpu) => cpu
                .Trace
                .Select(trace => trace.ProgramCounter)
                .Where(counter => counter == cpu.ProgramCounter)
                .Count()
                > 0
                );

            cpu.RunProgram();

            Console.WriteLine(cpu.Accumulator);

            // We can patch the program by editing one instruction from a nop to a jump or vice versa.
            // The program ends normaly by having the ProgramCounter exceed the length of the program.
            // So detect when that happens.
            var        arrayProgram = program.ToArray <IOperation>();
            IOperation oldOperation;

            for (var i = 0; i < arrayProgram.Length; i++)
            {
                if (arrayProgram[i].OpCode == OpCode.jmp || arrayProgram[i].OpCode == OpCode.nop)
                {
                    oldOperation = arrayProgram[i];
                    var sign = oldOperation.Argument >= 0 ? "+" : string.Empty;
                    if (arrayProgram[i].OpCode == OpCode.jmp)
                    {
                        arrayProgram[i] = new Operation(string.Format("nop {0}{1}", sign, oldOperation.Argument));
                    }
                    else
                    {
                        arrayProgram[i] = new Operation(string.Format("jmp {0}{1}", sign, oldOperation.Argument));
                    }

                    cpu.LoadNewProgram(arrayProgram);
                    cpu.RunProgram();
                    if (cpu.TerminatedNormally)
                    {
                        // we did it!
                        break;
                    }
                    else
                    {
                        arrayProgram[i] = oldOperation;
                    }
                }
            }

            Console.WriteLine(cpu.Accumulator);
        }
        public void LoadNewProgram_GivenValidProgram_SetsProgramAsExpected(IEnumerable <IOperation> program)
        {
            var sut = new JumpmanCPU(new IOperation[] { });

            sut.LoadNewProgram(program);

            Assert.Equal(program, sut.Program);
        }
        public void LoadNewProgram_GivenInvalidProgram_ThrowsException()
        {
            var sut = new JumpmanCPU(new IOperation[] { });

            var program = new IOperation[]
            {
                OpCodeUtility.MockOperation(OpCode.debug, 0)
            };

            var exception = Assert.Throws <ArgumentException>(() => sut.LoadNewProgram(program));

            Assert.StartsWith("The Opcodes: \"debug\" are not supported.", exception.Message);
        }