summaryrefslogtreecommitdiffstats
path: root/solutions/py/intcode.py
diff options
context:
space:
mode:
Diffstat (limited to 'solutions/py/intcode.py')
-rw-r--r--solutions/py/intcode.py62
1 files changed, 48 insertions, 14 deletions
diff --git a/solutions/py/intcode.py b/solutions/py/intcode.py
index f83a7ef..0f17962 100644
--- a/solutions/py/intcode.py
+++ b/solutions/py/intcode.py
@@ -1,4 +1,4 @@
-params = {1:3, 2:3, 3:1, 4:1, 5:2, 6:2, 7:3, 8:3, 99:0}
+param_amount = {1:3, 2:3, 3:1, 4:1, 5:2, 6:2, 7:3, 8:3, 9:1, 99:0}
ADD = 1
MULT = 2
@@ -8,43 +8,74 @@ JNZ = 5
JEZ = 6
LET = 7
EQV = 8
+BAS = 9
HAL = 99
class Computer(object):
def __init__(self, program):
self.memory = program.copy()
+ self.memory_size = len(self.memory) # pointers greater than this go in extra memory
self.pointer = 0
- self.phase_read = False
+ self.phase_read = False # for day 7
+ self.relative_base = 0
+ self.extra_mem = {}
self.input = None
self.output = None
def parse_op(self, op):
+ #TODO
code = op % 100
- return [code] + [(op // 10**(i+2)) % 10**(i+1) for i in range(params[code])]
+ ops = str(op).zfill(param_amount[code]+2)
+ return [code] + [int(x) for x in ops[:-2][::-1]]
+ #return [code] + [(op // 10**(i+2)) % 10**(i+1) for i in range(param_amount[code])]
def clear_flags(self):
self.input = None
self.output = None
+ def write(self, addr, val):
+ if addr > self.memory_size:
+ self.extra_mem[addr] = val
+ else:
+ self.memory[addr] = val
+
+ def get(self, addr):
+ if addr > self.memory_size:
+ return self.extra_mem[addr] if addr in self.extra_mem else 0
+ else:
+ return self.memory[addr]
+
def get_param(self, inst, num):
- return self.memory[self.pointer + num] if inst[num] == True else\
- self.memory[self.memory[self.pointer + num]]
+ if inst[num] == 0:
+ return self.get(self.get(self.pointer + num))
+ elif inst[num] == 1:
+ return self.get(self.pointer + num)
+ elif inst[num] == 2:
+ return self.get(self.relative_base + self.get(self.pointer + num))
+
+ def write_param(self, inst, num, val):
+ if inst[num] == 0:
+ self.write(self.get(self.pointer + num), val)
+ elif inst[num] == 1:
+ self.write(self.pointer + num, val)
+ elif inst[num] == 2:
+ self.write(self.relative_base + self.get(self.pointer + num), val)
def step(self):
inst = self.parse_op(self.memory[self.pointer])
if inst[0] == HAL:
return
elif inst[0] == ADD:
- self.memory[self.memory[self.pointer+3]] = \
- self.get_param(inst, 1) + self.get_param(inst, 2)
+ self.write_param(inst, 3, \
+ self.get_param(inst, 1) + self.get_param(inst, 2))
self.pointer += 4
elif inst[0] == MULT:
- self.memory[self.memory[self.pointer+3]] = \
- self.get_param(inst, 1) * self.get_param(inst, 2)
+ self.write_param(inst, 3, \
+ self.get_param(inst, 1) * self.get_param(inst, 2))
self.pointer += 4
elif inst[0] == IN:
- self.memory[self.memory[self.pointer+1]] = self.input
+ self.write_param(inst, 1, self.input)
self.input = None
self.pointer += 2
elif inst[0] == OUT:
@@ -61,15 +92,18 @@ class Computer(object):
else:
self.pointer += 3
elif inst[0] == LET:
- self.memory[self.memory[self.pointer+3]] = 1 if \
+ self.write_param(inst, 3, 1 if \
self.get_param(inst, 1) < self.get_param(inst, 2) \
- else 0
+ else 0)
self.pointer += 4
elif inst[0] == EQV:
- self.memory[self.memory[self.pointer+3]] = 1 if \
+ self.write_param(inst, 3, 1 if \
self.get_param(inst, 1) == self.get_param(inst, 2) \
- else 0
+ else 0)
self.pointer += 4
+ elif inst[0] == BAS:
+ self.relative_base += self.get_param(inst, 1)
+ self.pointer += 2
else:
print(self.memory)
print(self.pointer)