day9
This commit is contained in:
parent
38118e4613
commit
2285e2b504
1 changed files with 171 additions and 0 deletions
171
9/9.py
Executable file
171
9/9.py
Executable file
|
@ -0,0 +1,171 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
import sys
|
||||
|
||||
# run with '2' argument for part2 result.
|
||||
part2 = (len(sys.argv) == 2 and sys.argv[1] == '2')
|
||||
|
||||
class IntComp:
|
||||
def __init__(self, instructions, id):
|
||||
self.instructions = instructions
|
||||
self.pcounter = 0
|
||||
self.finished = 0
|
||||
self.ampid = id
|
||||
self.inputs = []
|
||||
self.relbase = 0
|
||||
|
||||
def terminated(self):
|
||||
return self.finished
|
||||
|
||||
def r(self, pos, mode):
|
||||
wantedpos = None
|
||||
if mode == 0:
|
||||
wantedpos = self.instructions[pos]
|
||||
elif mode == 1:
|
||||
wantedpos = pos
|
||||
elif mode == 2:
|
||||
wantedpos = self.relbase + self.instructions[pos]
|
||||
else:
|
||||
print ("Invalid mode!", mode)
|
||||
exit(1)
|
||||
|
||||
# Allow reading from 'new' memory.
|
||||
if wantedpos >= len(self.instructions):
|
||||
for i in range(len(self.instructions), wantedpos+1):
|
||||
self.instructions.append(0)
|
||||
|
||||
return int(self.instructions[wantedpos])
|
||||
|
||||
|
||||
def w(self, pos, v, mode):
|
||||
wantedpos = None
|
||||
if mode == 0:
|
||||
wantedpos = self.instructions[pos]
|
||||
elif mode == 1:
|
||||
wantedpos = pos
|
||||
elif mode == 2:
|
||||
wantedpos = self.relbase + self.instructions[pos]
|
||||
else:
|
||||
print ("Invalid mode!", mode)
|
||||
exit(1)
|
||||
|
||||
# Allow writing to 'new' memory.
|
||||
if wantedpos >= len(self.instructions):
|
||||
for i in range(len(self.instructions), wantedpos+1):
|
||||
self.instructions.append(0)
|
||||
|
||||
self.instructions[wantedpos] = v
|
||||
|
||||
def perform(self, inputs):
|
||||
outputs = []
|
||||
|
||||
for inp in inputs:
|
||||
self.inputs.append(inp)
|
||||
|
||||
while 1:
|
||||
fullopcode = self.instructions[self.pcounter]
|
||||
opcode = fullopcode % 100
|
||||
mode_c = (int(fullopcode/100) % 10)
|
||||
mode_b = (int(fullopcode/1000) % 10)
|
||||
mode_a = (int(fullopcode/10000) % 10)
|
||||
pos_c = self.pcounter+1
|
||||
pos_b = self.pcounter+2
|
||||
pos_a = self.pcounter+3
|
||||
|
||||
#print(self.ampid, "OP:", opcode, mode_c, mode_b, mode_a, pos_c, pos_b, pos_a)
|
||||
|
||||
# add
|
||||
if opcode == 1:
|
||||
val = self.r(pos_c,mode_c) + self.r(pos_b,mode_b)
|
||||
self.w(pos_a, val, mode_a)
|
||||
self.pcounter += 4
|
||||
|
||||
# multiply
|
||||
elif opcode == 2:
|
||||
val = self.r(pos_c, mode_c) * self.r(pos_b, mode_b)
|
||||
self.w(pos_a, val, mode_a)
|
||||
self.pcounter += 4
|
||||
|
||||
# input
|
||||
elif opcode == 3:
|
||||
print ("input:", self.inputs)
|
||||
store = self.inputs.pop(0)
|
||||
self.w(pos_c, store, mode_c)
|
||||
self.pcounter += 2
|
||||
|
||||
# output
|
||||
elif opcode == 4:
|
||||
outputs.append(self.r(pos_c, mode_c))
|
||||
self.pcounter += 2
|
||||
#print("output:", outputs)
|
||||
return (outputs, self.finished)
|
||||
|
||||
# jump-if-true
|
||||
elif opcode == 5:
|
||||
t = self.r(pos_c, mode_c)
|
||||
if t != 0:
|
||||
self.pcounter = self.r(pos_b, mode_b)
|
||||
else:
|
||||
self.pcounter += 3
|
||||
|
||||
# jump-if-false
|
||||
elif opcode == 6:
|
||||
t = self.r(pos_c, mode_c)
|
||||
if t == 0:
|
||||
self.pcounter = self.r(pos_b, mode_b)
|
||||
else:
|
||||
self.pcounter += 3
|
||||
|
||||
# less-than
|
||||
elif opcode == 7:
|
||||
c = self.r(pos_c, mode_c)
|
||||
b = self.r(pos_b, mode_b)
|
||||
if c < b:
|
||||
self.w(pos_a, 1, mode_a)
|
||||
else:
|
||||
self.w(pos_a, 0, mode_a)
|
||||
self.pcounter += 4
|
||||
|
||||
# equals
|
||||
elif opcode == 8:
|
||||
c = self.r(pos_c, mode_c)
|
||||
b = self.r(pos_b, mode_b)
|
||||
if c == b:
|
||||
self.w(pos_a, 1, mode_a)
|
||||
else:
|
||||
self.w(pos_a, 0, mode_a)
|
||||
self.pcounter += 4
|
||||
|
||||
# adjust-relbase
|
||||
elif opcode == 9:
|
||||
c = self.r(pos_c, mode_c)
|
||||
self.relbase += c
|
||||
self.pcounter += 2
|
||||
|
||||
# stop
|
||||
elif opcode == 99:
|
||||
self.finished = 1
|
||||
break
|
||||
|
||||
return (outputs, self.finished)
|
||||
|
||||
|
||||
for line in sys.stdin:
|
||||
instructions = line.rstrip().split(',')
|
||||
|
||||
ints = []
|
||||
for j in instructions:
|
||||
ints.append(int(j))
|
||||
|
||||
a = IntComp(ints,0)
|
||||
|
||||
start = [1]
|
||||
if part2:
|
||||
start = [2]
|
||||
|
||||
ret = a.perform(start)
|
||||
print(ret[0])
|
||||
while not a.terminated():
|
||||
ret = a.perform([])
|
||||
print(ret[0])
|
||||
print("================")
|
Loading…
Add table
Add a link
Reference in a new issue