Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from abc import ABC, abstractmethod
- from typing import List
- import sys
- POSITION_MODE = 0
- VALUE_MODE = 1
- class InstructionBase(ABC):
- def __init__(self, operand1, operand1_mode = None, operand2 = None, operand2_mode = None, operand3 = None, operand3_mode = POSITION_MODE):
- self.operand1 = operand1
- self.operand2 = operand2
- self.operand3 = operand3
- self.operand1_mode = operand1_mode
- self.operand2_mode = operand2_mode
- self.operand3_mode = operand3_mode
- @abstractmethod
- def operate(self, memory: List[int]) -> List[int]:
- pass
- class UnaryInstruction(InstructionBase):
- def __init__(self, operand1, operand1_mode = None):
- super().__init__(operand1, operand1_mode)
- class BinaryInstruction(InstructionBase):
- def __init__(self, operator, operand1, operand1_mode = None, operand2 = None, operand2_mode = None, operand3 = None, operand3_mode = POSITION_MODE):
- super().__init__(operand1, operand1_mode, operand2, operand2_mode, operand3, operand3_mode)
- self.operator = operator
- def operate(self, memory: List[int]) -> List[int]:
- if self.operand1_mode == POSITION_MODE:
- a = memory[memory[self.operand1]]
- else:
- a = memory[self.operand1]
- if self.operand2_mode == POSITION_MODE:
- b = memory[memory[self.operand2]]
- else:
- b = memory[self.operand2]
- value = self.operator(a, b)
- if self.operand3_mode == POSITION_MODE:
- memory[self.operand3] = value
- else:
- raise ValueError('Not implemented')
- return memory
- class ReadInput(UnaryInstruction):
- def __init__(self, operand1, input):
- super().__init__(operand1)
- self.input = input
- def operate(self, memory: List[int]) -> List[int]:
- memory[self.operand1] = self.input
- return memory
- class PrintOutput(UnaryInstruction):
- def __init__(self, operand1, operand1_mode):
- super().__init__(operand1, operand1_mode)
- def operate(self, memory: List[int]) -> List[int]:
- if self.operand1_mode == POSITION_MODE:
- print(memory[self.operand1])
- else:
- print(memory[memory[self.operand1]])
- return memory
- class Add(BinaryInstruction):
- def __init__(self, operand1, operand1_mode = None, operand2 = None, operand2_mode = None, operand3 = None, operand3_mode = POSITION_MODE):
- operator = lambda x, y: x + y
- super().__init__(operator, operand1, operand1_mode, operand2, operand2_mode, operand3, operand3_mode)
- class Multiply(BinaryInstruction):
- def __init__(self, operand1, operand1_mode = None, operand2 = None, operand2_mode = None, operand3 = None, operand3_mode = POSITION_MODE):
- operator = lambda x, y: x * y
- super().__init__(operator, operand1, operand1_mode, operand2, operand2_mode, operand3, operand3_mode)
- def instructionFactory(memory: List[int], input) -> List[InstructionBase]:
- i = 0
- instructions = []
- while memory[i] != 99:
- if memory[i] == 3:
- instructions.append(ReadInput(memory[i + 1], input))
- i = i + 2
- else:
- opcode = str(memory[i]).rjust(5, '0')
- mode1 = int(opcode[-3])
- mode2 = int(opcode[-4])
- mode3 = int(opcode[0])
- if opcode[-2:] == '01':
- instructions.append(Add(i + 1, mode1, i + 2, mode2, i + 3, mode3))
- i = i + 4
- elif opcode[-2:] == '02':
- instructions.append(Multiply(i + 1, mode1, i + 2, mode2, i + 3, mode3))
- i = i + 4
- else:
- instructions.append(PrintOutput(i + 1, mode1))
- i = i + 2
- return instructions
- def runProgram(memory: List[int]):
- instructions = instructionFactory(memory, 1)
- print(instructions)
- for instruction in instructions:
- memory = instruction.operate(memory)
- if __name__ == "__main__":
- with open('day5.txt', 'r') as f:
- memory = [int(num) for num in f.readline().split(',')]
- runProgram(memory)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement