# --- Day 5: Sunny with a Chance of Asteroids --- # You're starting to sweat as the ship makes its way toward Mercury. The Elves # suggest that you get the air conditioner working by upgrading your ship # computer to support the Thermal Environment Supervision Terminal. # The Thermal Environment Supervision Terminal (TEST) starts by running a # diagnostic program (your puzzle input). The TEST diagnostic program will run # on your existing Intcode computer after a few modifications: # First, you'll need to add two new instructions: # Opcode 3 takes a single integer as input and saves it to the position # given by its only parameter. For example, the instruction 3,50 would take an # input value and store it at address 50. # Opcode 4 outputs the value of its only parameter. For example, the # instruction 4,50 would output the value at address 50. # Programs that use these instructions will come with documentation that # explains what should be connected to the input and output. The program # 3,0,4,0,99 outputs whatever it gets as input, then halts. # Second, you'll need to add support for parameter modes: # Each parameter of an instruction is handled based on its parameter mode. # Right now, your ship computer already understands parameter mode 0, position # mode, which causes the parameter to be interpreted as a position - if the # parameter is 50, its value is the value stored at address 50 in memory. # Until now, all parameters have been in position mode. # Now, your ship computer will also need to handle parameters in mode 1, # immediate mode. In immediate mode, a parameter is interpreted as a value - # if the parameter is 50, its value is simply 50. # Parameter modes are stored in the same value as the instruction's opcode. # The opcode is a two-digit number based only on the ones and tens digit of the # value, that is, the opcode is the rightmost two digits of the first value in # an instruction. Parameter modes are single digits, one per parameter, read # right-to-left from the opcode: the first parameter's mode is in the hundreds # digit, the second parameter's mode is in the thousands digit, the third # parameter's mode is in the ten-thousands digit, and so on. Any missing modes # are 0. # For example, consider the program 1002,4,3,4,33. # The first instruction, 1002,4,3,4, is a multiply instruction - the rightmost # two digits of the first value, 02, indicate opcode 2, multiplication. Then, # going right to left, the parameter modes are 0 (hundreds digit), 1 (thousands # digit), and 0 (ten-thousands digit, not present and therefore zero): # ABCDE # 1002 # DE - two-digit opcode, 02 == opcode 2 # C - mode of 1st parameter, 0 == position mode # B - mode of 2nd parameter, 1 == immediate mode # A - mode of 3rd parameter, 0 == position mode, # omitted due to being a leading zero # This instruction multiplies its first two parameters. The first parameter, 4 # in position mode, works like it did before - its value is the value stored at # address 4 (33). The second parameter, 3 in immediate mode, simply has value # 3. The result of this operation, 33 * 3 = 99, is written according to the # third parameter, 4 in position mode, which also works like it did before - # 99 is written to address 4. # Parameters that an instruction writes to will never be in immediate mode. # Finally, some notes: # It is important to remember that the instruction pointer should increase # by the number of values in the instruction after the instruction finishes. # Because of the new instructions, this amount is no longer always 4. # Integers can be negative: 1101,100,-1,4,0 is a valid program (find # 100 + -1, store the result in position 4). # The TEST diagnostic program will start by requesting from the user the ID of # the system to test by running an input instruction - provide it 1, the ID for # the ship's air conditioner unit. # It will then perform a series of diagnostic tests confirming that various # parts of the Intcode computer, like parameter modes, function correctly. For # each test, it will run an output instruction indicating how far the result # of the test was from the expected value, where 0 means the test was # successful. Non-zero outputs mean that a function is not working correctly; # check the instructions that were run before the output instruction to see # which one failed. # Finally, the program will output a diagnostic code and immediately halt. This # final output isn't an error; an output followed immediately by a halt means # the program finished. If all outputs were zero except the diagnostic code, # the diagnostic program ran successfully. # After providing 1 to the only input instruction and passing all the tests, # what diagnostic code does the program produce? with open("files/P5.txt") as f: code = [int(number) for number in f.read().strip().split(",")] # function to return a five-element array to represent the intcode def intcodeArray(num: int) -> list[str]: intcode: list[str] = list(str(num)) if len(intcode) < 5: for i in range(5 - len(intcode)): intcode.insert(0, "0") for i in range(len(intcode)): intcode[i] = int(intcode[i]) return intcode def value(mode: int, position: int) -> int: if mode == 0: val = code[code[position]] else: val = code[position] return val def part_1() -> None: pos = 0 while code[pos] != 99: opcode: list[str] = intcodeArray(code[pos]) # add two values if opcode[4] == 1: i2 = pos + 1 i3 = pos + 2 o4 = code[pos + 3] code[o4] = value(opcode[2], i2) + value(opcode[1], i3) pos += 4 # multiply two values elif opcode[4] == 2: i2 = pos + 1 i3 = pos + 2 o4 = code[pos + 3] code[o4] = value(opcode[2], i2) * value(opcode[1], i3) pos += 4 # take an input value elif opcode[4] == 3: print("What is your input value?") choice = input() choice = int(choice) if opcode[2] == 0: code[code[pos + 1]] = choice else: code[pos + 1] = choice pos += 2 # print an output value elif opcode[4] == 4: _value = value(opcode[2], pos + 1) if _value != 0: print(f"The diagnostic code is {_value}") pos += 2 if __name__ == "__main__": part_1()