day11
This commit is contained in:
parent
8e5b90fd35
commit
db5f1d0e7c
1 changed files with 271 additions and 0 deletions
271
11/11.py
Executable file
271
11/11.py
Executable file
|
@ -0,0 +1,271 @@
|
||||||
|
#!/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)
|
||||||
|
|
||||||
|
def turnleft(dir):
|
||||||
|
if dir == "U":
|
||||||
|
return "L"
|
||||||
|
elif dir == "L":
|
||||||
|
return "D"
|
||||||
|
elif dir == "D":
|
||||||
|
return "R"
|
||||||
|
elif dir == "R":
|
||||||
|
return "U"
|
||||||
|
|
||||||
|
def turnright(dir):
|
||||||
|
if dir == "U":
|
||||||
|
return "R"
|
||||||
|
elif dir == "R":
|
||||||
|
return "D"
|
||||||
|
elif dir == "D":
|
||||||
|
return "L"
|
||||||
|
elif dir == "L":
|
||||||
|
return "U"
|
||||||
|
|
||||||
|
def moverobot(pos, dir):
|
||||||
|
print("move:", pos)
|
||||||
|
if dir == "U":
|
||||||
|
pos[1] += 1
|
||||||
|
elif dir == "L":
|
||||||
|
pos[0] -= 1
|
||||||
|
elif dir == "D":
|
||||||
|
pos[1] -= 1
|
||||||
|
elif dir == "R":
|
||||||
|
pos[0] += 1
|
||||||
|
print("move->:", pos)
|
||||||
|
return pos
|
||||||
|
|
||||||
|
for line in sys.stdin:
|
||||||
|
instructions = line.rstrip().split(',')
|
||||||
|
|
||||||
|
ints = []
|
||||||
|
grid = {0: {0: 0}}
|
||||||
|
|
||||||
|
if part2:
|
||||||
|
grid[0][0] = 1
|
||||||
|
|
||||||
|
currentdir = "U"
|
||||||
|
currentpos = [0,0]
|
||||||
|
seen = {}
|
||||||
|
minX = None
|
||||||
|
maxX = None
|
||||||
|
minY = None
|
||||||
|
maxY = None
|
||||||
|
|
||||||
|
for j in instructions:
|
||||||
|
ints.append(int(j))
|
||||||
|
|
||||||
|
robot = IntComp(ints,0)
|
||||||
|
|
||||||
|
while not robot.terminated():
|
||||||
|
#print("grid:", grid)
|
||||||
|
currentcolour = 0
|
||||||
|
if currentpos[0] in grid:
|
||||||
|
if currentpos[1] in grid[currentpos[0]]:
|
||||||
|
currentcolour = grid[currentpos[0]][currentpos[1]]
|
||||||
|
print(">>", currentcolour)
|
||||||
|
|
||||||
|
print("cc:", currentcolour, "pos:", currentpos, "dir:", currentdir)
|
||||||
|
|
||||||
|
colour = robot.perform([currentcolour])
|
||||||
|
if robot.terminated():
|
||||||
|
continue
|
||||||
|
|
||||||
|
# paint
|
||||||
|
if currentpos[0] in grid:
|
||||||
|
grid[currentpos[0]][currentpos[1]] = colour[0][0]
|
||||||
|
else:
|
||||||
|
t = {}
|
||||||
|
t[currentpos[1]] = colour[0][0]
|
||||||
|
grid[currentpos[0]] = t
|
||||||
|
xy = ("%d,%d" % (currentpos[0], currentpos[1]))
|
||||||
|
seen[xy] = 1
|
||||||
|
|
||||||
|
# turn
|
||||||
|
direction = robot.perform([])
|
||||||
|
if direction[0][0] == 0:
|
||||||
|
print("LEFT")
|
||||||
|
currentdir = turnleft(currentdir)
|
||||||
|
else:
|
||||||
|
print("RIGHT")
|
||||||
|
currentdir = turnright(currentdir)
|
||||||
|
print("nc1:", colour[0][0], "npos", currentpos, "dir:", currentdir)
|
||||||
|
|
||||||
|
# move
|
||||||
|
currentpos = moverobot(currentpos, currentdir)
|
||||||
|
print("nc2:", colour[0][0], "npos", currentpos, "dir:", currentdir)
|
||||||
|
print("==============")
|
||||||
|
|
||||||
|
if minX is None or currentpos[0] < minX:
|
||||||
|
minX = currentpos[0]
|
||||||
|
if minY is None or currentpos[1] < minY:
|
||||||
|
minY = currentpos[1]
|
||||||
|
if maxX is None or currentpos[0] > maxX:
|
||||||
|
maxX = currentpos[0]
|
||||||
|
if maxY is None or currentpos[1] > maxY:
|
||||||
|
maxY = currentpos[1]
|
||||||
|
|
||||||
|
if part2:
|
||||||
|
for y in range(maxY, minY-1, -1):
|
||||||
|
row = ""
|
||||||
|
for x in range(minX, maxX+1):
|
||||||
|
currentcolour = 0
|
||||||
|
if x in grid:
|
||||||
|
if y in grid[x]:
|
||||||
|
currentcolour = grid[x][y]
|
||||||
|
if currentcolour == 1:
|
||||||
|
row = row + "#"
|
||||||
|
else:
|
||||||
|
row = row + " "
|
||||||
|
print(row)
|
||||||
|
|
||||||
|
else:
|
||||||
|
print(len(seen))
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue