Solution to problem 5 part 1 in Python
This commit is contained in:
parent
38ba226a7f
commit
b06905b590
157
src/Year_2019/P5.py
Normal file
157
src/Year_2019/P5.py
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
# --- 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()
|
Loading…
Reference in New Issue
Block a user