private async Task <long> Part2() { var program = await ParseInput(); for (var i = 0; i < program.Count; i++) { var newProgram = program.ToList(); if (newProgram[i] is JmpInstruction jmpInstruction) { newProgram[i] = new NopInstruction(jmpInstruction.Value); } else if (newProgram[i] is NopInstruction nopInstruction) { newProgram[i] = new JmpInstruction(nopInstruction.Value); } else { continue; } var computer = new Computer(0, 0); var returnCode = computer.Run(newProgram); if (returnCode == ReturnCode.Completed) { return(computer.Accumulator); } } throw new Exception("Correct program not found."); }
private Instruction[] SwitchFirstJmpNop(Instruction[] instructions, int replaceFrom, out int replaced) { var result = new Instruction[instructions.Length]; replaced = -1; for (int i = 0; i < instructions.Length; i++) { if (replaced < 0 && i >= replaceFrom && (instructions[i].GetCode() == "jmp" || instructions[i].GetCode() == "nop")) { Instruction instructionToReplace = null; if (instructions[i] is JmpInstruction ins) { instructionToReplace = new NopInstruction(ins.Jump); } else if (instructions[i] is NopInstruction ins2) { instructionToReplace = new JmpInstruction(ins2.Value); } result[i] = instructionToReplace; replaced = i; } else { result[i] = instructions[i]; } } return(result); }
public void JmpTest() { State initialState = new State(); Instruction jmpInstruction = new JmpInstruction(4); var newState = jmpInstruction.Execute(initialState); newState.Acc.Should().Be(0); newState.Pc.Should().Be(4); }
private bool GenerateNode(out OneOperandNode node) { node = null; InstructionToken instructionToken; if (this.ExpectInstructionToken(out instructionToken)) { Instructions instruction = instructionToken.Instruction; switch (instruction) { case Instructions.Mov: { Token operand1; Token operand2; if (this.ExpectTwoOperands(out operand1, out operand2)) { node = new MovInstruction(this.rawInput, instructionToken, operand1, operand2); } else { this.LogExpectedTwoOperandsError(instructionToken); return(false); } } break; case Instructions.Add: { Token operand1; Token operand2; if (this.ExpectTwoOperands(out operand1, out operand2)) { node = new AddInstruction(this.rawInput, instructionToken, operand1, operand2); } else { this.LogExpectedTwoOperandsError(instructionToken); return(false); } } break; case Instructions.Sub: { Token operand1; Token operand2; if (this.ExpectTwoOperands(out operand1, out operand2)) { node = new SubInstruction(this.rawInput, instructionToken, operand1, operand2); } else { this.LogExpectedTwoOperandsError(instructionToken); return(false); } } break; case Instructions.Mul: { Token operand1; Token operand2; if (this.ExpectTwoOperands(out operand1, out operand2)) { node = new MulInstruction(this.rawInput, instructionToken, operand1, operand2); } else { this.LogExpectedTwoOperandsError(instructionToken); return(false); } } break; case Instructions.Div: { Token operand1; Token operand2; if (this.ExpectTwoOperands(out operand1, out operand2)) { node = new DivInstruction(this.rawInput, instructionToken, operand1, operand2); } else { this.LogExpectedTwoOperandsError(instructionToken); return(false); } } break; case Instructions.Cmp: { Token operand1; Token operand2; if (this.ExpectTwoOperands(out operand1, out operand2)) { node = new CmpInstruction(this.rawInput, instructionToken, operand1, operand2); } else { this.LogExpectedTwoOperandsError(instructionToken); return(false); } } break; case Instructions.Inc: { Token operand; if (this.ExpectOneOperand(out operand)) { node = new IncInstruction(this.rawInput, instructionToken, operand); } else { this.LogExpectedOneOperandError(instructionToken); return(false); } } break; case Instructions.Dec: { Token operand; if (this.ExpectOneOperand(out operand)) { node = new DecInstruction(this.rawInput, instructionToken, operand); } else { this.LogExpectedOneOperandError(instructionToken); return(false); } } break; case Instructions.Jmp: { Token operand; if (this.ExpectOneOperand(out operand)) { node = new JmpInstruction(this.rawInput, instructionToken, operand); } else { this.LogExpectedOneOperandError(instructionToken); return(false); } } break; case Instructions.Jeq: { Token operand; if (this.ExpectOneOperand(out operand)) { node = new JeqInstruction(this.rawInput, instructionToken, operand); } else { this.LogExpectedOneOperandError(instructionToken); return(false); } } break; case Instructions.Jne: { Token operand; if (this.ExpectOneOperand(out operand)) { node = new JneInstruction(this.rawInput, instructionToken, operand); } else { this.LogExpectedOneOperandError(instructionToken); return(false); } } break; case Instructions.Jsm: { Token operand; if (this.ExpectOneOperand(out operand)) { node = new JsmInstruction(this.rawInput, instructionToken, operand); } else { this.LogExpectedOneOperandError(instructionToken); return(false); } } break; case Instructions.Jns: { Token operand; if (this.ExpectOneOperand(out operand)) { node = new JnsInstruction(this.rawInput, instructionToken, operand); } else { this.LogExpectedOneOperandError(instructionToken); return(false); } } break; } } return(true); }