Add diff between day 7 and day 5 intcode
parent
5148386675
commit
180f6ea990
|
@ -0,0 +1,134 @@
|
||||||
|
--- day5intcode.py 2019-12-07 02:05:47.884308151 -0500
|
||||||
|
+++ day7intcode.py 2019-12-07 02:05:23.720568375 -0500
|
||||||
|
@@ -1,5 +1,6 @@
|
||||||
|
import sys
|
||||||
|
-from typing import Iterable, List, Tuple, Optional
|
||||||
|
+import itertools
|
||||||
|
+from typing import List, Tuple, Optional
|
||||||
|
|
||||||
|
|
||||||
|
# Halt indicates that the assembled program should terminate
|
||||||
|
@@ -29,6 +30,7 @@
|
||||||
|
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
|
||||||
|
|
||||||
|
def _extract_parameter_modes(self, raw_modes) -> Tuple[int, ...]:
|
||||||
|
PARAMETER_COUNTS = {
|
||||||
|
@@ -63,8 +65,8 @@
|
||||||
|
return tuple(modes)
|
||||||
|
|
||||||
|
# Run the given operation, starting at the given instruction pointer
|
||||||
|
- # Returns the address that the instruction pointer should become
|
||||||
|
- def run(self, memory: List[int], instruction_pointer: int, program_input: Optional[int] = None) -> int:
|
||||||
|
+ # Returns the address that the instruction pointer should become, followed by the output of the operation, if any
|
||||||
|
+ def run(self, memory: List[int], instruction_pointer: int, program_input: Optional[int] = None) -> Tuple[int, Optional[int]]:
|
||||||
|
OPERATION_FUNCS = {
|
||||||
|
# nop for terminate
|
||||||
|
Operation.OPCODE_TERMINATE: Operation.terminate,
|
||||||
|
@@ -78,6 +80,9 @@
|
||||||
|
Operation.OPCODE_EQUALS: Operation.equals
|
||||||
|
}
|
||||||
|
|
||||||
|
+ # Reset the output of a previous run
|
||||||
|
+ self.output = None
|
||||||
|
+
|
||||||
|
args = []
|
||||||
|
for i, mode in enumerate(self.modes):
|
||||||
|
# Add 1 to move past the opcode itself
|
||||||
|
@@ -92,65 +97,68 @@
|
||||||
|
|
||||||
|
func = OPERATION_FUNCS[self.opcode]
|
||||||
|
if program_input is None:
|
||||||
|
- jump_addr = func(memory, *args)
|
||||||
|
+ jump_addr = func(self, memory, *args)
|
||||||
|
else:
|
||||||
|
- jump_addr = func(memory, program_input, *args)
|
||||||
|
+ jump_addr = func(self, memory, program_input, *args)
|
||||||
|
|
||||||
|
if jump_addr is not None:
|
||||||
|
- return jump_addr
|
||||||
|
+ return jump_addr, self.output
|
||||||
|
|
||||||
|
- return instruction_pointer + len(self.modes) + 1
|
||||||
|
+ return instruction_pointer + len(self.modes) + 1, self.output
|
||||||
|
|
||||||
|
- @staticmethod
|
||||||
|
- def terminate(memory: List[int]) -> None:
|
||||||
|
+ def terminate(self, memory: List[int]) -> None:
|
||||||
|
raise Halt("catch fire")
|
||||||
|
|
||||||
|
- @staticmethod
|
||||||
|
- def add(memory: List[int], a: int, b: int, loc: int) -> None:
|
||||||
|
+ def add(self, memory: List[int], a: int, b: int, loc: int) -> None:
|
||||||
|
memory[loc] = a + b
|
||||||
|
|
||||||
|
- @staticmethod
|
||||||
|
- def multiply(memory: List[int], a: int, b: int, loc: int) -> None:
|
||||||
|
+ def multiply(self, memory: List[int], a: int, b: int, loc: int) -> None:
|
||||||
|
memory[loc] = a * b
|
||||||
|
|
||||||
|
- @staticmethod
|
||||||
|
- def input(memory: List[int], program_input: int, loc: int) -> None:
|
||||||
|
+ def input(self, memory: List[int], program_input: int, loc: int) -> None:
|
||||||
|
memory[loc] = program_input
|
||||||
|
|
||||||
|
- @staticmethod
|
||||||
|
- def output(memory: List[int], value: int) -> None:
|
||||||
|
+ def output(self, memory: List[int], value: int) -> None:
|
||||||
|
+ self.output = value
|
||||||
|
print("OUTPUT:", value)
|
||||||
|
|
||||||
|
- @staticmethod
|
||||||
|
- def jump_if_true(memory: List[int], test_value: int, new_instruction_pointer: int) -> Optional[int]:
|
||||||
|
+ def jump_if_true(self, memory: List[int], test_value: int, new_instruction_pointer: int) -> Optional[int]:
|
||||||
|
return new_instruction_pointer if test_value != 0 else None
|
||||||
|
|
||||||
|
- @staticmethod
|
||||||
|
- def jump_if_false(memory: List[int], test_value: int, new_instruction_pointer: int) -> Optional[int]:
|
||||||
|
+ def jump_if_false(self, memory: List[int], test_value: int, new_instruction_pointer: int) -> Optional[int]:
|
||||||
|
return new_instruction_pointer if test_value == 0 else None
|
||||||
|
|
||||||
|
- @staticmethod
|
||||||
|
- def less_than(memory: List[int], a: int, b: int, loc: int):
|
||||||
|
+ def less_than(self, memory: List[int], a: int, b: int, loc: int):
|
||||||
|
memory[loc] = int(a < b)
|
||||||
|
|
||||||
|
- @staticmethod
|
||||||
|
- def equals(memory: List[int], a: int, b: int, loc: int):
|
||||||
|
+ def equals(self, memory: List[int], a: int, b: int, loc: int):
|
||||||
|
memory[loc] = int(a == b)
|
||||||
|
|
||||||
|
|
||||||
|
-def execute_program(initial_state: List[int], program_inputs: List[int]):
|
||||||
|
- memory = initial_state[:]
|
||||||
|
- i = 0
|
||||||
|
+# Executes the program, returning the instruction pointer to continue at (if the program paused) and a list of all
|
||||||
|
+# outputs that occurred during the program's execution
|
||||||
|
+def execute_program(memory: List[int], program_inputs: List[int], initial_instruction_pointer: int = 0) -> (Optional[int], List[int]):
|
||||||
|
+ i = initial_instruction_pointer
|
||||||
|
input_cursor = 0
|
||||||
|
+ outputs = []
|
||||||
|
while i < len(memory):
|
||||||
|
operation = Operation(memory[i])
|
||||||
|
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):
|
||||||
|
+ return i, outputs
|
||||||
|
program_input = program_inputs[input_cursor]
|
||||||
|
input_cursor += 1
|
||||||
|
|
||||||
|
try:
|
||||||
|
- i = operation.run(memory, i, program_input)
|
||||||
|
+ i, output = operation.run(memory, i, program_input)
|
||||||
|
except Halt:
|
||||||
|
break
|
||||||
|
+
|
||||||
|
+ if output is not None:
|
||||||
|
+ outputs.append(output)
|
||||||
|
+
|
||||||
|
+ # The program is finished, and we are saying there is no instruction pointer
|
||||||
|
+ return None, outputs
|
Loading…
Reference in New Issue