mirror of
https://github.com/Crocmagnon/advent-of-code.git
synced 2024-11-22 06:28:11 +01:00
Refactor day 7 intcode for part 2
This commit is contained in:
parent
ba3b3b90ee
commit
98ad800491
3 changed files with 92 additions and 87 deletions
|
@ -1,5 +1,5 @@
|
||||||
import itertools
|
import itertools
|
||||||
from typing import List
|
from typing import List, Union
|
||||||
|
|
||||||
NUMBER_OF_PARAMS_MAP = {
|
NUMBER_OF_PARAMS_MAP = {
|
||||||
1: 3,
|
1: 3,
|
||||||
|
@ -24,36 +24,39 @@ LAST_IS_RESULT_MAP = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class Computer:
|
||||||
|
@staticmethod
|
||||||
def get_value(program, args, param_modes, index):
|
def get_value(program, args, param_modes, index):
|
||||||
if param_modes[index] == 0:
|
if param_modes[index] == 0:
|
||||||
return program[args[index]]
|
return program[args[index]]
|
||||||
return args[index]
|
return args[index]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
def parse_args(program, raw_args, param_modes, last_is_result=False):
|
def parse_args(program, raw_args, param_modes, last_is_result=False):
|
||||||
args = []
|
args = []
|
||||||
limit = -1 if last_is_result else None
|
limit = -1 if last_is_result else None
|
||||||
for i, arg in enumerate(raw_args[:limit]):
|
for i, arg in enumerate(raw_args[:limit]):
|
||||||
args.append(get_value(program, raw_args, param_modes, i))
|
args.append(Computer.get_value(program, raw_args, param_modes, i))
|
||||||
if last_is_result:
|
if last_is_result:
|
||||||
args.append(raw_args[-1])
|
args.append(raw_args[-1])
|
||||||
return args
|
return args
|
||||||
|
|
||||||
|
def __init__(self, initial_program: List[int], inputs: List[int] = None):
|
||||||
|
self.program = initial_program.copy() # type: List[int]
|
||||||
|
self.inputs = inputs.copy() # type: List[int]
|
||||||
|
|
||||||
def compute(lst: List[int], inputs: List[int] = None) -> List[int]:
|
def compute(self, inputs: List[int] = None) -> Union[int, None]:
|
||||||
if inputs is None:
|
if inputs is None:
|
||||||
inputs = []
|
inputs = []
|
||||||
|
self.inputs.extend(inputs)
|
||||||
program = lst.copy() # type: List[int]
|
|
||||||
outputs = [] # type: List[int]
|
|
||||||
|
|
||||||
pointer = 0
|
pointer = 0
|
||||||
while pointer < len(program):
|
while pointer < len(self.program):
|
||||||
pointer_moved = False
|
pointer_moved = False
|
||||||
instruction = str(program[pointer])
|
instruction = str(self.program[pointer])
|
||||||
code = int(instruction[-2:])
|
code = int(instruction[-2:])
|
||||||
if code == 99:
|
if code == 99:
|
||||||
return outputs
|
raise
|
||||||
|
|
||||||
number_of_params = NUMBER_OF_PARAMS_MAP[code]
|
number_of_params = NUMBER_OF_PARAMS_MAP[code]
|
||||||
offset = number_of_params + 1
|
offset = number_of_params + 1
|
||||||
|
@ -62,28 +65,29 @@ def compute(lst: List[int], inputs: List[int] = None) -> List[int]:
|
||||||
param_modes = list(map(int, reversed(param_modes)))
|
param_modes = list(map(int, reversed(param_modes)))
|
||||||
raw_params = []
|
raw_params = []
|
||||||
for i in range(1, offset):
|
for i in range(1, offset):
|
||||||
raw_params.append(program[pointer + i])
|
raw_params.append(self.program[pointer + i])
|
||||||
|
|
||||||
last_is_result = LAST_IS_RESULT_MAP[code]
|
last_is_result = LAST_IS_RESULT_MAP[code]
|
||||||
params = parse_args(program, raw_params, param_modes, last_is_result)
|
params = self.parse_args(
|
||||||
|
self.program, raw_params, param_modes, last_is_result
|
||||||
|
)
|
||||||
|
|
||||||
if code == 1:
|
if code == 1:
|
||||||
# Addition
|
# Addition
|
||||||
program[params[2]] = params[0] + params[1]
|
self.program[params[2]] = params[0] + params[1]
|
||||||
elif code == 2:
|
elif code == 2:
|
||||||
# Multiplication
|
# Multiplication
|
||||||
program[params[2]] = params[0] * params[1]
|
self.program[params[2]] = params[0] * params[1]
|
||||||
elif code == 3:
|
elif code == 3:
|
||||||
# Input
|
# Input
|
||||||
try:
|
try:
|
||||||
input_value = int(inputs.pop(0))
|
input_value = int(self.inputs.pop(0))
|
||||||
except IndexError:
|
except IndexError:
|
||||||
input_value = int(input(f"Input for instruction {pointer}\n> "))
|
input_value = int(input(f"Input for instruction {pointer}\n> "))
|
||||||
program[params[0]] = input_value
|
self.program[params[0]] = input_value
|
||||||
elif code == 4:
|
elif code == 4:
|
||||||
# Output
|
# Output
|
||||||
output_value = params[0]
|
return params[0]
|
||||||
outputs.append(output_value)
|
|
||||||
elif code == 5:
|
elif code == 5:
|
||||||
# Jump if true
|
# Jump if true
|
||||||
if params[0] != 0:
|
if params[0] != 0:
|
||||||
|
@ -97,15 +101,15 @@ def compute(lst: List[int], inputs: List[int] = None) -> List[int]:
|
||||||
elif code == 7:
|
elif code == 7:
|
||||||
# Less than
|
# Less than
|
||||||
if params[0] < params[1]:
|
if params[0] < params[1]:
|
||||||
program[params[2]] = 1
|
self.program[params[2]] = 1
|
||||||
else:
|
else:
|
||||||
program[params[2]] = 0
|
self.program[params[2]] = 0
|
||||||
elif code == 8:
|
elif code == 8:
|
||||||
# Equals
|
# Equals
|
||||||
if params[0] == params[1]:
|
if params[0] == params[1]:
|
||||||
program[params[2]] = 1
|
self.program[params[2]] = 1
|
||||||
else:
|
else:
|
||||||
program[params[2]] = 0
|
self.program[params[2]] = 0
|
||||||
|
|
||||||
else:
|
else:
|
||||||
raise ValueError(f"Something bad happened, code={code}")
|
raise ValueError(f"Something bad happened, code={code}")
|
||||||
|
@ -113,20 +117,19 @@ def compute(lst: List[int], inputs: List[int] = None) -> List[int]:
|
||||||
if not pointer_moved:
|
if not pointer_moved:
|
||||||
pointer += offset
|
pointer += offset
|
||||||
|
|
||||||
return program
|
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
with open("inputs/day07") as input_file:
|
with open("inputs/day07") as input_file:
|
||||||
original_program = list(map(int, input_file.read().split(",")))
|
original_program = list(map(int, input_file.read().split(",")))
|
||||||
values = set()
|
values = set()
|
||||||
for phase in itertools.permutations("01234"):
|
for phase in itertools.permutations("01234"):
|
||||||
amp1 = compute(original_program, [int(phase[0]), 0])
|
amp1 = Computer(original_program, [int(phase[0])]).compute([0])
|
||||||
amp2 = compute(original_program, [int(phase[1]), amp1[0]])
|
amp2 = Computer(original_program, [int(phase[1])]).compute([amp1])
|
||||||
amp3 = compute(original_program, [int(phase[2]), amp2[0]])
|
amp3 = Computer(original_program, [int(phase[2])]).compute([amp2])
|
||||||
amp4 = compute(original_program, [int(phase[3]), amp3[0]])
|
amp4 = Computer(original_program, [int(phase[3])]).compute([amp3])
|
||||||
amp5 = compute(original_program, [int(phase[4]), amp4[0]])
|
amp5 = Computer(original_program, [int(phase[4])]).compute([amp4])
|
||||||
values.add(amp5[0])
|
values.add(amp5)
|
||||||
|
|
||||||
print(max(values))
|
print(max(values))
|
||||||
|
|
||||||
|
|
||||||
|
|
1
2019/inputs/day07-ex4
Normal file
1
2019/inputs/day07-ex4
Normal file
|
@ -0,0 +1 @@
|
||||||
|
3,26,1001,26,-4,26,3,27,1002,27,2,27,1,27,26,27,4,27,1001,28,-1,28,1005,28,6,99,0,0,5
|
1
2019/inputs/day07-ex5
Normal file
1
2019/inputs/day07-ex5
Normal file
|
@ -0,0 +1 @@
|
||||||
|
3,52,1001,52,-5,52,3,53,1,52,56,54,1007,54,5,55,1005,55,26,1001,54,-5,54,1105,1,12,1,53,54,53,1008,54,0,55,1001,55,1,55,2,53,55,53,4,53,1001,56,-1,56,1005,56,6,99,0,0,0,0,10
|
Loading…
Reference in a new issue