static void Main11(string[] args) { string inputProgram = File.ReadAllText(@".\Day11\input.txt"); long[] instructionSet = inputProgram.Trim('\n').Split(',').Select((instr) => Int64.Parse(instr)).ToArray(); LargeMemSet memSet = new LargeMemSet(instructionSet); PaintBot pb = new PaintBot(); ComputeIntCode(memSet, pb); Console.WriteLine(pb.TotalPanelsPainted); pb.printPainting(); }
private static void ComputeIntCode(LargeMemSet instructionSet, PaintBot bot) { long activeInstruction = 0; long relativeBase = 0; bool givenPaintInstr = false; while (instructionSet[activeInstruction] != 99) { long instruction = instructionSet[activeInstruction]; // opcode is right most two digits long opcode = instruction % 100; long firstMode = (instruction / 100) % 10; long secondMode = (instruction / 1000) % 10; long thirdMode = (instruction / 10000) % 10; long firstParamValue = 0; long firstParamIndex = 0; long secondParamValue = 0; long thirdParamIndex = 0; long[] opcodesNeedingFirstParam = { 1, 2, 3, 4, 5, 6, 7, 8, 9 }; long[] opcodesNeedingSecondParam = { 1, 2, 5, 6, 7, 8 }; long[] opcodesNeedingThirdParam = { 1, 2, 7, 8 }; if (opcodesNeedingFirstParam.Contains(opcode)) { switch (firstMode) { // Position case 0: firstParamIndex = instructionSet[activeInstruction + 1]; break; // Immediate case 1: firstParamIndex = activeInstruction + 1; break; // Relative case 2: firstParamIndex = instructionSet[activeInstruction + 1] + relativeBase; break; } firstParamValue = instructionSet[firstParamIndex]; } if (opcodesNeedingSecondParam.Contains(opcode)) { switch (secondMode) { case 0: secondParamValue = instructionSet[instructionSet[activeInstruction + 2]]; break; case 1: secondParamValue = instructionSet[activeInstruction + 2]; break; case 2: secondParamValue = instructionSet[instructionSet[activeInstruction + 2] + relativeBase]; break; } } if (opcodesNeedingThirdParam.Contains(opcode)) { switch (thirdMode) { case 0: thirdParamIndex = instructionSet[activeInstruction + 3]; break; case 1: throw new Exception("Cannot store at immediate position"); case 2: thirdParamIndex = instructionSet[activeInstruction + 3] + relativeBase; break; } } switch (opcode) { // add case 1: instructionSet[thirdParamIndex] = firstParamValue + secondParamValue; activeInstruction += 4; break; case 2: instructionSet[thirdParamIndex] = firstParamValue * secondParamValue; activeInstruction += 4; break; case 3: instructionSet[firstParamIndex] = bot.getCameraReading(); activeInstruction += 2; break; case 4: if (!givenPaintInstr) { bot.paint((int)firstParamValue); givenPaintInstr = true; } else { bot.changeDirectionAndMove((int)firstParamValue); givenPaintInstr = false; } activeInstruction += 2; break; case 5: if (firstParamValue != 0) { activeInstruction = secondParamValue; } else { activeInstruction += 3; } break; case 6: if (firstParamValue == 0) { activeInstruction = secondParamValue; } else { activeInstruction += 3; } break; case 7: if (firstParamValue < secondParamValue) { instructionSet[thirdParamIndex] = 1; } else { instructionSet[thirdParamIndex] = 0; } activeInstruction += 4; break; case 8: if (firstParamValue == secondParamValue) { instructionSet[thirdParamIndex] = 1; } else { instructionSet[thirdParamIndex] = 0; } activeInstruction += 4; break; case 9: relativeBase += firstParamValue; activeInstruction += 2; break; default: throw new Exception($"Unexpected opcode {instructionSet[activeInstruction]}"); } } }