175 lines
4.6 KiB
Python
175 lines
4.6 KiB
Python
from lib import *
|
|
|
|
input = read_input(2019, 17)
|
|
|
|
|
|
class IntCode:
|
|
def __init__(self, mem):
|
|
self.mem = {i: e for i, e in enumerate(mem)}
|
|
self.pc = 0
|
|
self.running = False
|
|
self.inp = []
|
|
self.out = []
|
|
self.rel = 0
|
|
|
|
def start(self):
|
|
self.running = True
|
|
self.cont()
|
|
|
|
def get_arg(self, i):
|
|
mode = self.mem[self.pc] // (10 ** (i + 1)) % 10
|
|
out = self.mem[self.pc + i]
|
|
if mode == 1:
|
|
return out
|
|
elif mode == 2:
|
|
out += self.rel
|
|
return self.mem.get(out, 0)
|
|
|
|
def write_arg(self, i, value):
|
|
mode = self.mem[self.pc] // (10 ** (i + 1)) % 10
|
|
pos = self.mem[self.pc + i]
|
|
assert mode != 1
|
|
if mode == 2:
|
|
pos += self.rel
|
|
self.mem[pos] = value
|
|
|
|
def cont(self):
|
|
while True:
|
|
opcode = self.mem[self.pc] % 100
|
|
|
|
if opcode == 1:
|
|
self.write_arg(3, self.get_arg(1) + self.get_arg(2))
|
|
self.pc += 4
|
|
elif opcode == 2:
|
|
self.write_arg(3, self.get_arg(1) * self.get_arg(2))
|
|
self.pc += 4
|
|
elif opcode == 3:
|
|
if not self.inp:
|
|
return
|
|
self.write_arg(1, self.inp.pop(0))
|
|
self.pc += 2
|
|
elif opcode == 4:
|
|
self.out.append(self.get_arg(1))
|
|
self.pc += 2
|
|
elif opcode == 5:
|
|
if self.get_arg(1):
|
|
self.pc = self.get_arg(2)
|
|
else:
|
|
self.pc += 3
|
|
elif opcode == 6:
|
|
if not self.get_arg(1):
|
|
self.pc = self.get_arg(2)
|
|
else:
|
|
self.pc += 3
|
|
elif opcode == 7:
|
|
self.write_arg(3, int(self.get_arg(1) < self.get_arg(2)))
|
|
self.pc += 4
|
|
elif opcode == 8:
|
|
self.write_arg(3, int(self.get_arg(1) == self.get_arg(2)))
|
|
self.pc += 4
|
|
elif opcode == 9:
|
|
self.rel += self.get_arg(1)
|
|
self.pc += 2
|
|
elif opcode == 99:
|
|
self.running = False
|
|
return
|
|
|
|
|
|
(*mem,) = map(int, input.split(","))
|
|
intcode = IntCode(mem)
|
|
intcode.start()
|
|
grid = "".join(map(chr, intcode.out)).strip().splitlines()
|
|
out = 0
|
|
for i in range(1, len(grid) - 1):
|
|
for j in range(1, len(grid[i]) - 1):
|
|
if grid[i][j] == grid[i][j - 1] == grid[i][j + 1] == grid[i - 1][j] == grid[i + 1][j] == "#":
|
|
out += i * j
|
|
print(out)
|
|
|
|
|
|
def apply_direction(x, y, d):
|
|
d %= 4
|
|
if d == 0:
|
|
y -= 1
|
|
elif d == 2:
|
|
y += 1
|
|
elif d == 1:
|
|
x += 1
|
|
elif d == 3:
|
|
x -= 1
|
|
return x, y
|
|
|
|
|
|
def is_path(x, y):
|
|
return y in range(len(grid)) and x in range(len(grid[y])) and grid[y][x] == "#"
|
|
|
|
|
|
(*mem,) = map(int, input.split(","))
|
|
mem[0] = 2
|
|
intcode = IntCode(mem)
|
|
intcode.start()
|
|
grid = []
|
|
x = y = None
|
|
direction = 0
|
|
for i, line in enumerate("".join(map(chr, intcode.out)).strip().splitlines()):
|
|
if "^" in line:
|
|
x, y = line.index("^"), i
|
|
grid.append(line)
|
|
instructions = []
|
|
while True:
|
|
if is_path(*apply_direction(x, y, direction - 1)):
|
|
inst = "L"
|
|
direction -= 1
|
|
elif is_path(*apply_direction(x, y, direction + 1)):
|
|
inst = "R"
|
|
direction += 1
|
|
else:
|
|
break
|
|
|
|
cnt = 0
|
|
while True:
|
|
nx, ny = apply_direction(x, y, direction)
|
|
if is_path(nx, ny):
|
|
cnt += 1
|
|
x, y = nx, ny
|
|
else:
|
|
break
|
|
if cnt:
|
|
instructions.append(inst + "," + str(cnt))
|
|
|
|
|
|
def get_groups(start, groups):
|
|
if start >= len(instructions):
|
|
return groups
|
|
|
|
for i in range(3):
|
|
if groups[i] is not None:
|
|
if all(groups[i][j] == instructions[j + start] for j in range(len(groups[i]))):
|
|
return get_groups(start + len(groups[i]), groups)
|
|
else:
|
|
groups = groups[:]
|
|
groups[i] = []
|
|
for j in range(1, 5):
|
|
groups[i].append(instructions[start + j - 1])
|
|
result = get_groups(start + j, groups)
|
|
if result:
|
|
return result
|
|
|
|
|
|
groups = get_groups(0, [None, None, None])
|
|
main = []
|
|
i = 0
|
|
while i < len(instructions):
|
|
for j, g in enumerate(groups):
|
|
if g == instructions[i : i + len(g)]:
|
|
main.append("ABC"[j])
|
|
i += len(g)
|
|
break
|
|
|
|
intcode.inp += list(map(ord, ",".join(main) + "\n"))
|
|
for g in groups:
|
|
intcode.inp += list(map(ord, ",".join(g) + "\n"))
|
|
intcode.inp.append(ord("n"))
|
|
intcode.inp.append(ord("\n"))
|
|
intcode.cont()
|
|
print(intcode.out[-1])
|