Refacto day 5 intcode computer

This commit is contained in:
Gabriel Augendre 2020-03-04 23:40:42 +01:00
parent efb48beccc
commit 84d0a06e9a
No known key found for this signature in database
GPG key ID: 1E693F4CE4AEE7B4

View file

@ -1,59 +1,79 @@
ZERO_PARAM_CODES = [99] NUMBER_OF_PARAMS_MAP = {
ONE_PARAM_CODES = [3, 4] 1: 3,
THREE_PARAMS_CODES = [1, 2] 2: 3,
3: 1,
4: 1,
99: 0,
}
LAST_IS_RESULT_MAP = {
1: True,
2: True,
3: True,
4: False,
}
def get_value(program, args, param_modes, index):
if param_modes[index] == 0:
return program[args[index]]
return args[index]
def parse_args(program, raw_args, param_modes, last_is_result=False):
args = []
limit = -1 if last_is_result else None
for i, arg in enumerate(raw_args[:limit]):
args.append(get_value(program, raw_args, param_modes, i))
if last_is_result:
args.append(raw_args[-1])
return args
def compute(lst): def compute(lst):
result = lst.copy() program = lst.copy()
i = 0 pointer = 0
while i < len(result): while pointer < len(program):
first_instruction = str(result[i]) pointer_moved = False
code = int(first_instruction[-2:]) instruction = str(program[pointer])
param_modes = first_instruction[:-2] code = int(instruction[-2:])
if code == 99: if code == 99:
print("Halting due to code 99") print("Halting due to code 99")
return result return program
if code in THREE_PARAMS_CODES:
offset = 4
param_modes = param_modes.zfill(offset - 1)
param_modes_parsed = list(map(int, reversed(param_modes)))
position1, position2 = result[i + 1], result[i + 2] number_of_params = NUMBER_OF_PARAMS_MAP[code]
if param_modes_parsed[0] == 0: offset = number_of_params + 1
item1 = result[position1] param_modes = instruction[:-2]
else: param_modes = param_modes.zfill(number_of_params)
item1 = position1 param_modes = list(map(int, reversed(param_modes)))
if param_modes_parsed[1] == 0: raw_params = []
item2 = result[position2] for i in range(1, offset):
else: raw_params.append(program[pointer + i])
item2 = position2
result_index = result[i + 3]
if code == 1: last_is_result = LAST_IS_RESULT_MAP[code]
result[result_index] = item1 + item2 params = parse_args(program, raw_params, param_modes, last_is_result)
elif code == 2:
result[result_index] = item1 * item2
elif code in ONE_PARAM_CODES: if code == 1:
offset = 2 # Addition
param_mode = int(param_modes.zfill(offset - 1)) program[params[2]] = params[0] + params[1]
position = result[i + 1] elif code == 2:
if code == 3: # Multiplication
result[position] = int(input(f"Input for instruction {i}")) program[params[2]] = params[0] * params[1]
elif code == 4: elif code == 3:
if param_mode == 0: # Input
res = result[position] program[params[0]] = int(input(f"Input for instruction {pointer}"))
else: elif code == 4:
res = position # Output
print(res) print(params[0])
else: else:
raise ValueError(f"Something bad happened, code={code}") raise ValueError(f"Something bad happened, code={code}")
i += offset if not pointer_moved:
pointer += offset
return result return program
if __name__ == "__main__": if __name__ == "__main__":