Minor intcode cleanup
parent
2e63f5b59a
commit
1342fb40e6
|
@ -1,5 +1,5 @@
|
|||
--- day9intcode.py 2019-12-11 01:02:10.952864966 -0500
|
||||
+++ day11intcode.py 2019-12-11 01:02:34.308613523 -0500
|
||||
+++ day11intcode.py 2019-12-11 01:14:04.585182158 -0500
|
||||
@@ -1,7 +1,6 @@
|
||||
import collections
|
||||
import sys
|
||||
|
@ -9,7 +9,52 @@
|
|||
|
||||
# Halt indicates that the assembled program should terminate
|
||||
class Halt(Exception):
|
||||
@@ -136,7 +135,6 @@
|
||||
@@ -35,14 +34,14 @@
|
||||
# Opcodes that write to memory as their last parameter
|
||||
MEMORY_OPCODES = (OPCODE_ADD, OPCODE_MULTIPLY, OPCODE_INPUT, OPCODE_LESS_THAN, OPCODE_EQUALS)
|
||||
|
||||
- def __init__(self, instruction: int):
|
||||
+ def __init__(self, instruction: int, rel_base: int = 0):
|
||||
# The opcode is the first two digits of the number, the rest are parameter modes
|
||||
self.opcode: int = instruction % 100
|
||||
if self.opcode not in Operation.ALL_OPCODES:
|
||||
raise ValueError(f"Bad opcode: {self.opcode}")
|
||||
self.modes: Tuple[int, ...] = self._extract_parameter_modes(instruction//100)
|
||||
self.output = None
|
||||
- self.rel_base = 0
|
||||
+ self.rel_base = rel_base
|
||||
|
||||
def _extract_parameter_modes(self, raw_modes) -> Tuple[int, ...]:
|
||||
PARAMETER_COUNTS = {
|
||||
@@ -69,8 +68,8 @@
|
||||
return tuple(modes)
|
||||
|
||||
# Run the given operation, starting at the given instruction pointer
|
||||
- # Returns the address that the instruction pointer should become, the relative base, followed by the output of the operation, if any
|
||||
- def run(self, memory: Memory, instruction_pointer: int, rel_base: int = 0, program_input: Optional[int] = None) -> Tuple[int, int, Optional[int]]:
|
||||
+ # Returns the address that the instruction pointer should become
|
||||
+ def run(self, memory: Memory, instruction_pointer: int, program_input: Optional[int] = None) -> int:
|
||||
OPERATION_FUNCS = {
|
||||
# nop for terminate
|
||||
Operation.OPCODE_TERMINATE: Operation.terminate,
|
||||
@@ -87,7 +86,6 @@
|
||||
|
||||
# Reset the output and rel base of a previous run
|
||||
self.output = None
|
||||
- self.rel_base = rel_base
|
||||
|
||||
args = []
|
||||
for i, mode in enumerate(self.modes):
|
||||
@@ -120,7 +118,7 @@
|
||||
if jump_addr is not None:
|
||||
out_addr = jump_addr
|
||||
|
||||
- return out_addr, self.rel_base, self.output
|
||||
+ return out_addr
|
||||
|
||||
def terminate(self, memory: Memory) -> None:
|
||||
raise Halt("catch fire")
|
||||
@@ -136,7 +134,6 @@
|
||||
|
||||
def output(self, memory: Memory, value: int) -> None:
|
||||
self.output = value
|
||||
|
@ -17,8 +62,14 @@
|
|||
|
||||
def jump_if_true(self, memory: Memory, test_value: int, new_instruction_pointer: int) -> Optional[int]:
|
||||
return new_instruction_pointer if test_value != 0 else None
|
||||
@@ -154,13 +152,13 @@
|
||||
self.rel_base += rel_base
|
||||
@@ -150,31 +147,33 @@
|
||||
def equals(self, memory: Memory, a: int, b: int, loc: int) -> None:
|
||||
memory[loc] = int(a == b)
|
||||
|
||||
- def set_rel_base(self, memory: Memory, rel_base: int) -> None:
|
||||
- self.rel_base += rel_base
|
||||
+ def set_rel_base(self, memory: Memory, base_delta: int) -> None:
|
||||
+ self.rel_base += base_delta
|
||||
|
||||
|
||||
-# Executes the program, returning the instruction pointer to continue at (if the program paused) and a list of all
|
||||
|
@ -26,7 +77,7 @@
|
|||
-def execute_program(memory: Memory, program_inputs: List[int], initial_instruction_pointer: int = 0) -> (Optional[int], List[int]):
|
||||
+# Executes the program, returning the instruction pointer to continue at (if the program paused), the relative base,
|
||||
+# and a list of all outputs that occurred during the program's execution
|
||||
+def execute_program(memory: Memory, program_inputs: List[int], initial_instruction_pointer: int = 0, initial_rel_base: int = 0) -> (Optional[int], int, List[int]):
|
||||
+def execute_program(memory: Memory, program_inputs: List[int], initial_instruction_pointer: int = 0, initial_rel_base: int = 0) -> Tuple[Optional[int], int, List[int]]:
|
||||
i = initial_instruction_pointer
|
||||
input_cursor = 0
|
||||
- rel_base = 0
|
||||
|
@ -34,8 +85,10 @@
|
|||
+ rel_base = initial_rel_base
|
||||
# Go up to the maximum address, not the number of addresses
|
||||
while i < max(memory.keys()):
|
||||
operation = Operation(memory[i])
|
||||
@@ -169,7 +167,7 @@
|
||||
- operation = Operation(memory[i])
|
||||
+ operation = Operation(memory[i], rel_base)
|
||||
program_input = None
|
||||
# If we're looking for input
|
||||
if operation.opcode == Operation.OPCODE_INPUT:
|
||||
# If we are out of input, don't fail out, but rather just pause execution
|
||||
if input_cursor >= len(program_inputs):
|
||||
|
@ -44,7 +97,15 @@
|
|||
program_input = program_inputs[input_cursor]
|
||||
input_cursor += 1
|
||||
|
||||
@@ -182,4 +180,4 @@
|
||||
try:
|
||||
- i, rel_base, output = operation.run(memory, i, rel_base, program_input)
|
||||
+ i = operation.run(memory, i, program_input)
|
||||
+ output = operation.output
|
||||
+ rel_base = operation.rel_base
|
||||
except Halt:
|
||||
break
|
||||
|
||||
@@ -182,4 +181,4 @@
|
||||
outputs.append(output)
|
||||
|
||||
# The program is finished, and we are saying there is no instruction pointer
|
||||
|
|
|
@ -34,14 +34,14 @@ class Operation:
|
|||
# Opcodes that write to memory as their last parameter
|
||||
MEMORY_OPCODES = (OPCODE_ADD, OPCODE_MULTIPLY, OPCODE_INPUT, OPCODE_LESS_THAN, OPCODE_EQUALS)
|
||||
|
||||
def __init__(self, instruction: int):
|
||||
def __init__(self, instruction: int, rel_base: int = 0):
|
||||
# The opcode is the first two digits of the number, the rest are parameter modes
|
||||
self.opcode: int = instruction % 100
|
||||
if self.opcode not in Operation.ALL_OPCODES:
|
||||
raise ValueError(f"Bad opcode: {self.opcode}")
|
||||
self.modes: Tuple[int, ...] = self._extract_parameter_modes(instruction//100)
|
||||
self.output = None
|
||||
self.rel_base = 0
|
||||
self.rel_base = rel_base
|
||||
|
||||
def _extract_parameter_modes(self, raw_modes) -> Tuple[int, ...]:
|
||||
PARAMETER_COUNTS = {
|
||||
|
@ -68,8 +68,8 @@ class Operation:
|
|||
return tuple(modes)
|
||||
|
||||
# Run the given operation, starting at the given instruction pointer
|
||||
# Returns the address that the instruction pointer should become, the relative base, followed by the output of the operation, if any
|
||||
def run(self, memory: Memory, instruction_pointer: int, rel_base: int = 0, program_input: Optional[int] = None) -> Tuple[int, int, Optional[int]]:
|
||||
# Returns the address that the instruction pointer should become
|
||||
def run(self, memory: Memory, instruction_pointer: int, program_input: Optional[int] = None) -> int:
|
||||
OPERATION_FUNCS = {
|
||||
# nop for terminate
|
||||
Operation.OPCODE_TERMINATE: Operation.terminate,
|
||||
|
@ -86,7 +86,6 @@ class Operation:
|
|||
|
||||
# Reset the output and rel base of a previous run
|
||||
self.output = None
|
||||
self.rel_base = rel_base
|
||||
|
||||
args = []
|
||||
for i, mode in enumerate(self.modes):
|
||||
|
@ -119,7 +118,7 @@ class Operation:
|
|||
if jump_addr is not None:
|
||||
out_addr = jump_addr
|
||||
|
||||
return out_addr, self.rel_base, self.output
|
||||
return out_addr
|
||||
|
||||
def terminate(self, memory: Memory) -> None:
|
||||
raise Halt("catch fire")
|
||||
|
@ -148,20 +147,20 @@ class Operation:
|
|||
def equals(self, memory: Memory, a: int, b: int, loc: int) -> None:
|
||||
memory[loc] = int(a == b)
|
||||
|
||||
def set_rel_base(self, memory: Memory, rel_base: int) -> None:
|
||||
self.rel_base += rel_base
|
||||
def set_rel_base(self, memory: Memory, base_delta: int) -> None:
|
||||
self.rel_base += base_delta
|
||||
|
||||
|
||||
# Executes the program, returning the instruction pointer to continue at (if the program paused), the relative base,
|
||||
# and a list of all outputs that occurred during the program's execution
|
||||
def execute_program(memory: Memory, program_inputs: List[int], initial_instruction_pointer: int = 0, initial_rel_base: int = 0) -> (Optional[int], int, List[int]):
|
||||
def execute_program(memory: Memory, program_inputs: List[int], initial_instruction_pointer: int = 0, initial_rel_base: int = 0) -> Tuple[Optional[int], int, List[int]]:
|
||||
i = initial_instruction_pointer
|
||||
input_cursor = 0
|
||||
outputs = []
|
||||
rel_base = initial_rel_base
|
||||
# Go up to the maximum address, not the number of addresses
|
||||
while i < max(memory.keys()):
|
||||
operation = Operation(memory[i])
|
||||
operation = Operation(memory[i], rel_base)
|
||||
program_input = None
|
||||
# If we're looking for input
|
||||
if operation.opcode == Operation.OPCODE_INPUT:
|
||||
|
@ -172,7 +171,9 @@ def execute_program(memory: Memory, program_inputs: List[int], initial_instructi
|
|||
input_cursor += 1
|
||||
|
||||
try:
|
||||
i, rel_base, output = operation.run(memory, i, rel_base, program_input)
|
||||
i = operation.run(memory, i, program_input)
|
||||
output = operation.output
|
||||
rel_base = operation.rel_base
|
||||
except Halt:
|
||||
break
|
||||
|
||||
|
|
Loading…
Reference in New Issue