[Python/2019] Restructure solutions
This commit is contained in:
parent
40e767096e
commit
fb42493fff
63 changed files with 1393 additions and 1739 deletions
17
Python/2019/01.py
Normal file
17
Python/2019/01.py
Normal file
|
@ -0,0 +1,17 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2019, 1)
|
||||
|
||||
out = 0
|
||||
for line in input.splitlines():
|
||||
out += int(line) // 3 - 2
|
||||
print(out)
|
||||
|
||||
|
||||
out = 0
|
||||
for line in input.splitlines():
|
||||
fuel = int(line) // 3 - 2
|
||||
while fuel > 0:
|
||||
out += fuel
|
||||
fuel = fuel // 3 - 2
|
||||
print(out)
|
|
@ -1,4 +0,0 @@
|
|||
out = 0
|
||||
for line in open("input.txt").read().splitlines():
|
||||
out += int(line) // 3 - 2
|
||||
print(out)
|
|
@ -1,7 +0,0 @@
|
|||
out = 0
|
||||
for line in open("input.txt").read().splitlines():
|
||||
fuel = int(line) // 3 - 2
|
||||
while fuel > 0:
|
||||
out += fuel
|
||||
fuel = fuel // 3 - 2
|
||||
print(out)
|
36
Python/2019/02.py
Normal file
36
Python/2019/02.py
Normal file
|
@ -0,0 +1,36 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2019, 2)
|
||||
|
||||
(*mem,) = map(int, input.strip().split(","))
|
||||
i = 0
|
||||
mem[1] = 12
|
||||
mem[2] = 2
|
||||
while i < len(mem):
|
||||
if mem[i] == 99:
|
||||
break
|
||||
elif mem[i] == 1:
|
||||
mem[mem[i + 3]] = mem[mem[i + 1]] + mem[mem[i + 2]]
|
||||
elif mem[i] == 2:
|
||||
mem[mem[i + 3]] = mem[mem[i + 1]] * mem[mem[i + 2]]
|
||||
i += 4
|
||||
print(mem[0])
|
||||
(*mem,) = map(int, input.strip().split(","))
|
||||
|
||||
|
||||
def simulate(a, b, mem):
|
||||
i = 0
|
||||
mem[1] = a
|
||||
mem[2] = b
|
||||
while i < len(mem):
|
||||
if mem[i] == 99:
|
||||
break
|
||||
elif mem[i] == 1:
|
||||
mem[mem[i + 3]] = mem[mem[i + 1]] + mem[mem[i + 2]]
|
||||
elif mem[i] == 2:
|
||||
mem[mem[i + 3]] = mem[mem[i + 1]] * mem[mem[i + 2]]
|
||||
i += 4
|
||||
return mem[0]
|
||||
|
||||
|
||||
print(*[a * 100 + b for a in range(100) for b in range(100) if simulate(a, b, mem[:]) == 19690720])
|
|
@ -1,13 +0,0 @@
|
|||
*mem, = map(int, open("input.txt").read().strip().split(","))
|
||||
i = 0
|
||||
mem[1] = 12
|
||||
mem[2] = 2
|
||||
while i < len(mem):
|
||||
if mem[i] == 99:
|
||||
break
|
||||
elif mem[i] == 1:
|
||||
mem[mem[i+3]] = mem[mem[i+1]] + mem[mem[i+2]]
|
||||
elif mem[i] == 2:
|
||||
mem[mem[i+3]] = mem[mem[i+1]] * mem[mem[i+2]]
|
||||
i += 4
|
||||
print(mem[0])
|
|
@ -1,17 +0,0 @@
|
|||
*mem, = map(int, open("input.txt").read().strip().split(","))
|
||||
|
||||
def simulate(a, b, mem):
|
||||
i = 0
|
||||
mem[1] = a
|
||||
mem[2] = b
|
||||
while i < len(mem):
|
||||
if mem[i] == 99:
|
||||
break
|
||||
elif mem[i] == 1:
|
||||
mem[mem[i+3]] = mem[mem[i+1]] + mem[mem[i+2]]
|
||||
elif mem[i] == 2:
|
||||
mem[mem[i+3]] = mem[mem[i+1]] * mem[mem[i+2]]
|
||||
i += 4
|
||||
return mem[0]
|
||||
|
||||
print(*[a * 100 + b for a in range(100) for b in range(100) if simulate(a, b, mem[:]) == 19690720])
|
40
Python/2019/03.py
Normal file
40
Python/2019/03.py
Normal file
|
@ -0,0 +1,40 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2019, 3)
|
||||
|
||||
|
||||
def parse_wire(wire):
|
||||
x = 0
|
||||
y = 0
|
||||
out = set()
|
||||
for e in wire.split(","):
|
||||
dx, dy = {"U": (0, -1), "D": (0, 1), "L": (-1, 0), "R": (1, 0)}[e[0]]
|
||||
for _ in range(int(e[1:])):
|
||||
x += dx
|
||||
y += dy
|
||||
out.add((x, y))
|
||||
return out
|
||||
|
||||
|
||||
wire1, wire2 = map(parse_wire, input.splitlines())
|
||||
print(min(abs(x) + abs(y) for x, y in (wire1 & wire2)))
|
||||
|
||||
|
||||
def parse_wire(wire):
|
||||
x = 0
|
||||
y = 0
|
||||
out = {}
|
||||
count = 0
|
||||
for e in wire.split(","):
|
||||
dx, dy = {"U": (0, -1), "D": (0, 1), "L": (-1, 0), "R": (1, 0)}[e[0]]
|
||||
for _ in range(int(e[1:])):
|
||||
x += dx
|
||||
y += dy
|
||||
count += 1
|
||||
if (x, y) not in out:
|
||||
out[(x, y)] = count
|
||||
return out
|
||||
|
||||
|
||||
wire1, wire2 = map(parse_wire, input.splitlines())
|
||||
print(min(wire1[intersection] + wire2[intersection] for intersection in (wire1.keys() & wire2.keys())))
|
|
@ -1,14 +0,0 @@
|
|||
def parse_wire(wire):
|
||||
x = 0
|
||||
y = 0
|
||||
out = set()
|
||||
for e in wire.split(","):
|
||||
dx, dy = {"U": (0, -1), "D": (0, 1), "L": (-1, 0), "R": (1, 0)}[e[0]]
|
||||
for _ in range(int(e[1:])):
|
||||
x += dx
|
||||
y += dy
|
||||
out.add((x, y))
|
||||
return out
|
||||
|
||||
wire1, wire2 = map(parse_wire, open("input.txt").read().splitlines())
|
||||
print(min(abs(x) + abs(y) for x, y in (wire1 & wire2)))
|
|
@ -1,17 +0,0 @@
|
|||
def parse_wire(wire):
|
||||
x = 0
|
||||
y = 0
|
||||
out = {}
|
||||
count = 0
|
||||
for e in wire.split(","):
|
||||
dx, dy = {"U": (0, -1), "D": (0, 1), "L": (-1, 0), "R": (1, 0)}[e[0]]
|
||||
for _ in range(int(e[1:])):
|
||||
x += dx
|
||||
y += dy
|
||||
count += 1
|
||||
if (x, y) not in out:
|
||||
out[(x, y)] = count
|
||||
return out
|
||||
|
||||
wire1, wire2 = map(parse_wire, open("input.txt").read().splitlines())
|
||||
print(min(wire1[intersection] + wire2[intersection] for intersection in (wire1.keys() & wire2.keys())))
|
24
Python/2019/04.py
Normal file
24
Python/2019/04.py
Normal file
|
@ -0,0 +1,24 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2019, 4)
|
||||
|
||||
a, b = map(int, input.split("-"))
|
||||
count = 0
|
||||
for i in range(a, b + 1):
|
||||
string = str(i)
|
||||
if list(string) != sorted(string):
|
||||
continue
|
||||
if any(x == y for x, y in zip(string[1:], string)):
|
||||
count += 1
|
||||
print(count)
|
||||
|
||||
|
||||
a, b = map(int, input.split("-"))
|
||||
count = 0
|
||||
for i in range(a, b + 1):
|
||||
string = str(i)
|
||||
if list(string) != sorted(string):
|
||||
continue
|
||||
if any(string.count(c) == 2 for c in string):
|
||||
count += 1
|
||||
print(count)
|
|
@ -1,9 +0,0 @@
|
|||
a, b = map(int, open("input.txt").read().split("-"))
|
||||
count = 0
|
||||
for i in range(a, b + 1):
|
||||
string = str(i)
|
||||
if list(string) != sorted(string):
|
||||
continue
|
||||
if any(x==y for x, y in zip(string[1:], string)):
|
||||
count += 1
|
||||
print(count)
|
|
@ -1,9 +0,0 @@
|
|||
a, b = map(int, open("input.txt").read().split("-"))
|
||||
count = 0
|
||||
for i in range(a, b + 1):
|
||||
string = str(i)
|
||||
if list(string) != sorted(string):
|
||||
continue
|
||||
if any(string.count(c) == 2 for c in string):
|
||||
count += 1
|
||||
print(count)
|
83
Python/2019/05.py
Normal file
83
Python/2019/05.py
Normal file
|
@ -0,0 +1,83 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2019, 5)
|
||||
|
||||
(*mem,) = map(int, input.split(","))
|
||||
pc = 0
|
||||
while pc < len(mem):
|
||||
opcode = mem[pc] % 100
|
||||
mode1 = mem[pc] // 100 % 10
|
||||
mode2 = mem[pc] // 1000 % 10
|
||||
|
||||
if opcode == 1:
|
||||
arg1 = mem[pc + 1] if mode1 else mem[mem[pc + 1]]
|
||||
arg2 = mem[pc + 2] if mode2 else mem[mem[pc + 2]]
|
||||
mem[mem[pc + 3]] = arg1 + arg2
|
||||
pc += 4
|
||||
elif opcode == 2:
|
||||
arg1 = mem[pc + 1] if mode1 else mem[mem[pc + 1]]
|
||||
arg2 = mem[pc + 2] if mode2 else mem[mem[pc + 2]]
|
||||
mem[mem[pc + 3]] = arg1 * arg2
|
||||
pc += 4
|
||||
elif opcode == 3:
|
||||
mem[mem[pc + 1]] = 1
|
||||
pc += 2
|
||||
elif opcode == 4:
|
||||
arg1 = mem[pc + 1] if mode1 else mem[mem[pc + 1]]
|
||||
if arg1:
|
||||
print(arg1)
|
||||
pc += 2
|
||||
elif opcode == 99:
|
||||
break
|
||||
|
||||
|
||||
(*mem,) = map(int, input.split(","))
|
||||
pc = 0
|
||||
while pc < len(mem):
|
||||
opcode = mem[pc] % 100
|
||||
mode1 = mem[pc] // 100 % 10
|
||||
mode2 = mem[pc] // 1000 % 10
|
||||
|
||||
if opcode == 1:
|
||||
arg1 = mem[pc + 1] if mode1 else mem[mem[pc + 1]]
|
||||
arg2 = mem[pc + 2] if mode2 else mem[mem[pc + 2]]
|
||||
mem[mem[pc + 3]] = arg1 + arg2
|
||||
pc += 4
|
||||
elif opcode == 2:
|
||||
arg1 = mem[pc + 1] if mode1 else mem[mem[pc + 1]]
|
||||
arg2 = mem[pc + 2] if mode2 else mem[mem[pc + 2]]
|
||||
mem[mem[pc + 3]] = arg1 * arg2
|
||||
pc += 4
|
||||
elif opcode == 3:
|
||||
mem[mem[pc + 1]] = 5
|
||||
pc += 2
|
||||
elif opcode == 4:
|
||||
arg1 = mem[pc + 1] if mode1 else mem[mem[pc + 1]]
|
||||
print(arg1)
|
||||
pc += 2
|
||||
elif opcode == 5:
|
||||
arg1 = mem[pc + 1] if mode1 else mem[mem[pc + 1]]
|
||||
arg2 = mem[pc + 2] if mode2 else mem[mem[pc + 2]]
|
||||
if arg1:
|
||||
pc = arg2
|
||||
else:
|
||||
pc += 3
|
||||
elif opcode == 6:
|
||||
arg1 = mem[pc + 1] if mode1 else mem[mem[pc + 1]]
|
||||
arg2 = mem[pc + 2] if mode2 else mem[mem[pc + 2]]
|
||||
if not arg1:
|
||||
pc = arg2
|
||||
else:
|
||||
pc += 3
|
||||
elif opcode == 7:
|
||||
arg1 = mem[pc + 1] if mode1 else mem[mem[pc + 1]]
|
||||
arg2 = mem[pc + 2] if mode2 else mem[mem[pc + 2]]
|
||||
mem[mem[pc + 3]] = int(arg1 < arg2)
|
||||
pc += 4
|
||||
elif opcode == 8:
|
||||
arg1 = mem[pc + 1] if mode1 else mem[mem[pc + 1]]
|
||||
arg2 = mem[pc + 2] if mode2 else mem[mem[pc + 2]]
|
||||
mem[mem[pc + 3]] = int(arg1 == arg2)
|
||||
pc += 4
|
||||
elif opcode == 99:
|
||||
break
|
|
@ -1,26 +0,0 @@
|
|||
*mem, = map(int, open("input.txt").read().split(","))
|
||||
pc = 0
|
||||
while pc < len(mem):
|
||||
opcode = mem[pc] % 100
|
||||
mode1 = mem[pc] // 100 % 10
|
||||
mode2 = mem[pc] // 1000 % 10
|
||||
|
||||
if opcode == 1:
|
||||
arg1 = mem[pc+1] if mode1 else mem[mem[pc+1]]
|
||||
arg2 = mem[pc+2] if mode2 else mem[mem[pc+2]]
|
||||
mem[mem[pc+3]] = arg1 + arg2
|
||||
pc += 4
|
||||
elif opcode == 2:
|
||||
arg1 = mem[pc+1] if mode1 else mem[mem[pc+1]]
|
||||
arg2 = mem[pc+2] if mode2 else mem[mem[pc+2]]
|
||||
mem[mem[pc+3]] = arg1 * arg2
|
||||
pc += 4
|
||||
elif opcode == 3:
|
||||
mem[mem[pc+1]] = 1
|
||||
pc += 2
|
||||
elif opcode == 4:
|
||||
arg1 = mem[pc+1] if mode1 else mem[mem[pc+1]]
|
||||
print(arg1)
|
||||
pc += 2
|
||||
elif opcode == 99:
|
||||
break
|
|
@ -1,50 +0,0 @@
|
|||
*mem, = map(int, open("input.txt").read().split(","))
|
||||
pc = 0
|
||||
while pc < len(mem):
|
||||
opcode = mem[pc] % 100
|
||||
mode1 = mem[pc] // 100 % 10
|
||||
mode2 = mem[pc] // 1000 % 10
|
||||
|
||||
if opcode == 1:
|
||||
arg1 = mem[pc+1] if mode1 else mem[mem[pc+1]]
|
||||
arg2 = mem[pc+2] if mode2 else mem[mem[pc+2]]
|
||||
mem[mem[pc+3]] = arg1 + arg2
|
||||
pc += 4
|
||||
elif opcode == 2:
|
||||
arg1 = mem[pc+1] if mode1 else mem[mem[pc+1]]
|
||||
arg2 = mem[pc+2] if mode2 else mem[mem[pc+2]]
|
||||
mem[mem[pc+3]] = arg1 * arg2
|
||||
pc += 4
|
||||
elif opcode == 3:
|
||||
mem[mem[pc+1]] = 5
|
||||
pc += 2
|
||||
elif opcode == 4:
|
||||
arg1 = mem[pc+1] if mode1 else mem[mem[pc+1]]
|
||||
print(arg1)
|
||||
pc += 2
|
||||
elif opcode == 5:
|
||||
arg1 = mem[pc+1] if mode1 else mem[mem[pc+1]]
|
||||
arg2 = mem[pc+2] if mode2 else mem[mem[pc+2]]
|
||||
if arg1:
|
||||
pc = arg2
|
||||
else:
|
||||
pc += 3
|
||||
elif opcode == 6:
|
||||
arg1 = mem[pc+1] if mode1 else mem[mem[pc+1]]
|
||||
arg2 = mem[pc+2] if mode2 else mem[mem[pc+2]]
|
||||
if not arg1:
|
||||
pc = arg2
|
||||
else:
|
||||
pc += 3
|
||||
elif opcode == 7:
|
||||
arg1 = mem[pc+1] if mode1 else mem[mem[pc+1]]
|
||||
arg2 = mem[pc+2] if mode2 else mem[mem[pc+2]]
|
||||
mem[mem[pc+3]] = int(arg1 < arg2)
|
||||
pc += 4
|
||||
elif opcode == 8:
|
||||
arg1 = mem[pc+1] if mode1 else mem[mem[pc+1]]
|
||||
arg2 = mem[pc+2] if mode2 else mem[mem[pc+2]]
|
||||
mem[mem[pc+3]] = int(arg1 == arg2)
|
||||
pc += 4
|
||||
elif opcode == 99:
|
||||
break
|
39
Python/2019/06.py
Normal file
39
Python/2019/06.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2019, 6)
|
||||
|
||||
graph = {}
|
||||
for line in input.splitlines():
|
||||
a, b = line.split(")")
|
||||
graph.setdefault(a, set()).add(b)
|
||||
|
||||
out = 0
|
||||
Q = [("COM", 0)]
|
||||
while Q:
|
||||
node, count = Q.pop(0)
|
||||
out += count
|
||||
for child in graph.get(node, set()):
|
||||
Q.append((child, count + 1))
|
||||
print(out)
|
||||
|
||||
|
||||
graph = {}
|
||||
for line in input.splitlines():
|
||||
a, b = line.split(")")
|
||||
graph.setdefault(a, set()).add(b)
|
||||
graph.setdefault(b, set()).add(a)
|
||||
|
||||
Q = [("YOU", 0)]
|
||||
visited = set()
|
||||
while Q:
|
||||
node, dist = Q.pop(0)
|
||||
|
||||
if node in visited:
|
||||
continue
|
||||
visited.add(node)
|
||||
|
||||
if node == "SAN":
|
||||
print(dist - 2)
|
||||
|
||||
for child in graph.get(node, set()):
|
||||
Q.append((child, dist + 1))
|
|
@ -1,13 +0,0 @@
|
|||
graph = {}
|
||||
for line in open("input.txt").read().splitlines():
|
||||
a, b = line.split(")")
|
||||
graph.setdefault(a, set()).add(b)
|
||||
|
||||
out = 0
|
||||
Q = [("COM", 0)]
|
||||
while Q:
|
||||
node, count = Q.pop(0)
|
||||
out += count
|
||||
for child in graph.get(node, set()):
|
||||
Q.append((child, count + 1))
|
||||
print(out)
|
|
@ -1,19 +0,0 @@
|
|||
graph = {}
|
||||
for line in open("input.txt").read().splitlines():
|
||||
a, b = line.split(")")
|
||||
graph.setdefault(a, set()).add(b)
|
||||
graph.setdefault(b, set()).add(a)
|
||||
|
||||
Q = [("YOU", 0)]
|
||||
visited = set()
|
||||
while Q:
|
||||
node, dist = Q.pop(0)
|
||||
|
||||
if node in visited: continue
|
||||
visited.add(node)
|
||||
|
||||
if node == "SAN":
|
||||
print(dist - 2)
|
||||
|
||||
for child in graph.get(node, set()):
|
||||
Q.append((child, dist + 1))
|
157
Python/2019/07.py
Normal file
157
Python/2019/07.py
Normal file
|
@ -0,0 +1,157 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2019, 7)
|
||||
|
||||
|
||||
def intcode(mem, inp):
|
||||
pc = 0
|
||||
while pc < len(mem):
|
||||
opcode = mem[pc] % 100
|
||||
mode1 = mem[pc] // 100 % 10
|
||||
mode2 = mem[pc] // 1000 % 10
|
||||
|
||||
if opcode == 1:
|
||||
arg1 = mem[pc + 1] if mode1 else mem[mem[pc + 1]]
|
||||
arg2 = mem[pc + 2] if mode2 else mem[mem[pc + 2]]
|
||||
mem[mem[pc + 3]] = arg1 + arg2
|
||||
pc += 4
|
||||
elif opcode == 2:
|
||||
arg1 = mem[pc + 1] if mode1 else mem[mem[pc + 1]]
|
||||
arg2 = mem[pc + 2] if mode2 else mem[mem[pc + 2]]
|
||||
mem[mem[pc + 3]] = arg1 * arg2
|
||||
pc += 4
|
||||
elif opcode == 3:
|
||||
mem[mem[pc + 1]] = inp.pop(0)
|
||||
pc += 2
|
||||
elif opcode == 4:
|
||||
arg1 = mem[pc + 1] if mode1 else mem[mem[pc + 1]]
|
||||
return arg1
|
||||
pc += 2
|
||||
elif opcode == 5:
|
||||
arg1 = mem[pc + 1] if mode1 else mem[mem[pc + 1]]
|
||||
arg2 = mem[pc + 2] if mode2 else mem[mem[pc + 2]]
|
||||
if arg1:
|
||||
pc = arg2
|
||||
else:
|
||||
pc += 3
|
||||
elif opcode == 6:
|
||||
arg1 = mem[pc + 1] if mode1 else mem[mem[pc + 1]]
|
||||
arg2 = mem[pc + 2] if mode2 else mem[mem[pc + 2]]
|
||||
if not arg1:
|
||||
pc = arg2
|
||||
else:
|
||||
pc += 3
|
||||
elif opcode == 7:
|
||||
arg1 = mem[pc + 1] if mode1 else mem[mem[pc + 1]]
|
||||
arg2 = mem[pc + 2] if mode2 else mem[mem[pc + 2]]
|
||||
mem[mem[pc + 3]] = int(arg1 < arg2)
|
||||
pc += 4
|
||||
elif opcode == 8:
|
||||
arg1 = mem[pc + 1] if mode1 else mem[mem[pc + 1]]
|
||||
arg2 = mem[pc + 2] if mode2 else mem[mem[pc + 2]]
|
||||
mem[mem[pc + 3]] = int(arg1 == arg2)
|
||||
pc += 4
|
||||
elif opcode == 99:
|
||||
break
|
||||
|
||||
|
||||
(*mem,) = map(int, input.split(","))
|
||||
|
||||
|
||||
def test(seq):
|
||||
out = 0
|
||||
for i in seq:
|
||||
out = intcode(mem[:], [i, out])
|
||||
return out
|
||||
|
||||
|
||||
print(max(test(seq) for seq in itertools.permutations(range(5))))
|
||||
|
||||
|
||||
class IntCode:
|
||||
def __init__(self, mem):
|
||||
self.mem = mem
|
||||
self.pc = 0
|
||||
self.running = False
|
||||
self.inp = []
|
||||
self.out = []
|
||||
|
||||
def start(self):
|
||||
self.running = True
|
||||
self.cont()
|
||||
|
||||
def cont(self):
|
||||
while self.pc < len(self.mem):
|
||||
opcode = self.mem[self.pc] % 100
|
||||
mode1 = self.mem[self.pc] // 100 % 10
|
||||
mode2 = self.mem[self.pc] // 1000 % 10
|
||||
|
||||
if opcode == 1:
|
||||
arg1 = self.mem[self.pc + 1] if mode1 else self.mem[self.mem[self.pc + 1]]
|
||||
arg2 = self.mem[self.pc + 2] if mode2 else self.mem[self.mem[self.pc + 2]]
|
||||
self.mem[self.mem[self.pc + 3]] = arg1 + arg2
|
||||
self.pc += 4
|
||||
elif opcode == 2:
|
||||
arg1 = self.mem[self.pc + 1] if mode1 else self.mem[self.mem[self.pc + 1]]
|
||||
arg2 = self.mem[self.pc + 2] if mode2 else self.mem[self.mem[self.pc + 2]]
|
||||
self.mem[self.mem[self.pc + 3]] = arg1 * arg2
|
||||
self.pc += 4
|
||||
elif opcode == 3:
|
||||
if not self.inp:
|
||||
return
|
||||
self.mem[self.mem[self.pc + 1]] = self.inp.pop(0)
|
||||
self.pc += 2
|
||||
elif opcode == 4:
|
||||
arg1 = self.mem[self.pc + 1] if mode1 else self.mem[self.mem[self.pc + 1]]
|
||||
self.out.append(arg1)
|
||||
self.pc += 2
|
||||
elif opcode == 5:
|
||||
arg1 = self.mem[self.pc + 1] if mode1 else self.mem[self.mem[self.pc + 1]]
|
||||
arg2 = self.mem[self.pc + 2] if mode2 else self.mem[self.mem[self.pc + 2]]
|
||||
if arg1:
|
||||
self.pc = arg2
|
||||
else:
|
||||
self.pc += 3
|
||||
elif opcode == 6:
|
||||
arg1 = self.mem[self.pc + 1] if mode1 else self.mem[self.mem[self.pc + 1]]
|
||||
arg2 = self.mem[self.pc + 2] if mode2 else self.mem[self.mem[self.pc + 2]]
|
||||
if not arg1:
|
||||
self.pc = arg2
|
||||
else:
|
||||
self.pc += 3
|
||||
elif opcode == 7:
|
||||
arg1 = self.mem[self.pc + 1] if mode1 else self.mem[self.mem[self.pc + 1]]
|
||||
arg2 = self.mem[self.pc + 2] if mode2 else self.mem[self.mem[self.pc + 2]]
|
||||
self.mem[self.mem[self.pc + 3]] = int(arg1 < arg2)
|
||||
self.pc += 4
|
||||
elif opcode == 8:
|
||||
arg1 = self.mem[self.pc + 1] if mode1 else self.mem[self.mem[self.pc + 1]]
|
||||
arg2 = self.mem[self.pc + 2] if mode2 else self.mem[self.mem[self.pc + 2]]
|
||||
self.mem[self.mem[self.pc + 3]] = int(arg1 == arg2)
|
||||
self.pc += 4
|
||||
elif opcode == 99:
|
||||
self.running = False
|
||||
return
|
||||
|
||||
|
||||
(*mem,) = map(int, input.split(","))
|
||||
|
||||
|
||||
def test(seq):
|
||||
out = 0
|
||||
instances = []
|
||||
for i in range(5):
|
||||
instances.append(IntCode(mem[:]))
|
||||
instances[-1].inp.append(seq[i])
|
||||
instances[-1].start()
|
||||
|
||||
i = 0
|
||||
while instances[-1].running:
|
||||
instances[i].inp.append(out)
|
||||
instances[i].cont()
|
||||
out = instances[i].out.pop()
|
||||
i = (i + 1) % 5
|
||||
return out
|
||||
|
||||
|
||||
print(max(test(seq) for seq in itertools.permutations(range(5, 10))))
|
|
@ -1,61 +0,0 @@
|
|||
import itertools
|
||||
|
||||
def intcode(mem, inp):
|
||||
pc = 0
|
||||
while pc < len(mem):
|
||||
opcode = mem[pc] % 100
|
||||
mode1 = mem[pc] // 100 % 10
|
||||
mode2 = mem[pc] // 1000 % 10
|
||||
|
||||
if opcode == 1:
|
||||
arg1 = mem[pc+1] if mode1 else mem[mem[pc+1]]
|
||||
arg2 = mem[pc+2] if mode2 else mem[mem[pc+2]]
|
||||
mem[mem[pc+3]] = arg1 + arg2
|
||||
pc += 4
|
||||
elif opcode == 2:
|
||||
arg1 = mem[pc+1] if mode1 else mem[mem[pc+1]]
|
||||
arg2 = mem[pc+2] if mode2 else mem[mem[pc+2]]
|
||||
mem[mem[pc+3]] = arg1 * arg2
|
||||
pc += 4
|
||||
elif opcode == 3:
|
||||
mem[mem[pc+1]] = inp.pop(0)
|
||||
pc += 2
|
||||
elif opcode == 4:
|
||||
arg1 = mem[pc+1] if mode1 else mem[mem[pc+1]]
|
||||
return arg1
|
||||
pc += 2
|
||||
elif opcode == 5:
|
||||
arg1 = mem[pc+1] if mode1 else mem[mem[pc+1]]
|
||||
arg2 = mem[pc+2] if mode2 else mem[mem[pc+2]]
|
||||
if arg1:
|
||||
pc = arg2
|
||||
else:
|
||||
pc += 3
|
||||
elif opcode == 6:
|
||||
arg1 = mem[pc+1] if mode1 else mem[mem[pc+1]]
|
||||
arg2 = mem[pc+2] if mode2 else mem[mem[pc+2]]
|
||||
if not arg1:
|
||||
pc = arg2
|
||||
else:
|
||||
pc += 3
|
||||
elif opcode == 7:
|
||||
arg1 = mem[pc+1] if mode1 else mem[mem[pc+1]]
|
||||
arg2 = mem[pc+2] if mode2 else mem[mem[pc+2]]
|
||||
mem[mem[pc+3]] = int(arg1 < arg2)
|
||||
pc += 4
|
||||
elif opcode == 8:
|
||||
arg1 = mem[pc+1] if mode1 else mem[mem[pc+1]]
|
||||
arg2 = mem[pc+2] if mode2 else mem[mem[pc+2]]
|
||||
mem[mem[pc+3]] = int(arg1 == arg2)
|
||||
pc += 4
|
||||
elif opcode == 99:
|
||||
break
|
||||
|
||||
*mem, = map(int, open("input.txt").read().split(","))
|
||||
def test(seq):
|
||||
out = 0
|
||||
for i in seq:
|
||||
out = intcode(mem[:], [i, out])
|
||||
return out
|
||||
|
||||
print(max(test(seq) for seq in itertools.permutations(range(5))))
|
|
@ -1,85 +0,0 @@
|
|||
import itertools
|
||||
|
||||
class IntCode:
|
||||
def __init__(self, mem):
|
||||
self.mem = mem
|
||||
self.pc = 0
|
||||
self.running = False
|
||||
self.inp = []
|
||||
self.out = []
|
||||
|
||||
def start(self):
|
||||
self.running = True
|
||||
self.cont()
|
||||
|
||||
def cont(self):
|
||||
while self.pc < len(self.mem):
|
||||
opcode = self.mem[self.pc] % 100
|
||||
mode1 = self.mem[self.pc] // 100 % 10
|
||||
mode2 = self.mem[self.pc] // 1000 % 10
|
||||
|
||||
if opcode == 1:
|
||||
arg1 = self.mem[self.pc+1] if mode1 else self.mem[self.mem[self.pc+1]]
|
||||
arg2 = self.mem[self.pc+2] if mode2 else self.mem[self.mem[self.pc+2]]
|
||||
self.mem[self.mem[self.pc+3]] = arg1 + arg2
|
||||
self.pc += 4
|
||||
elif opcode == 2:
|
||||
arg1 = self.mem[self.pc+1] if mode1 else self.mem[self.mem[self.pc+1]]
|
||||
arg2 = self.mem[self.pc+2] if mode2 else self.mem[self.mem[self.pc+2]]
|
||||
self.mem[self.mem[self.pc+3]] = arg1 * arg2
|
||||
self.pc += 4
|
||||
elif opcode == 3:
|
||||
if not self.inp:
|
||||
return
|
||||
self.mem[self.mem[self.pc+1]] = self.inp.pop(0)
|
||||
self.pc += 2
|
||||
elif opcode == 4:
|
||||
arg1 = self.mem[self.pc+1] if mode1 else self.mem[self.mem[self.pc+1]]
|
||||
self.out.append(arg1)
|
||||
self.pc += 2
|
||||
elif opcode == 5:
|
||||
arg1 = self.mem[self.pc+1] if mode1 else self.mem[self.mem[self.pc+1]]
|
||||
arg2 = self.mem[self.pc+2] if mode2 else self.mem[self.mem[self.pc+2]]
|
||||
if arg1:
|
||||
self.pc = arg2
|
||||
else:
|
||||
self.pc += 3
|
||||
elif opcode == 6:
|
||||
arg1 = self.mem[self.pc+1] if mode1 else self.mem[self.mem[self.pc+1]]
|
||||
arg2 = self.mem[self.pc+2] if mode2 else self.mem[self.mem[self.pc+2]]
|
||||
if not arg1:
|
||||
self.pc = arg2
|
||||
else:
|
||||
self.pc += 3
|
||||
elif opcode == 7:
|
||||
arg1 = self.mem[self.pc+1] if mode1 else self.mem[self.mem[self.pc+1]]
|
||||
arg2 = self.mem[self.pc+2] if mode2 else self.mem[self.mem[self.pc+2]]
|
||||
self.mem[self.mem[self.pc+3]] = int(arg1 < arg2)
|
||||
self.pc += 4
|
||||
elif opcode == 8:
|
||||
arg1 = self.mem[self.pc+1] if mode1 else self.mem[self.mem[self.pc+1]]
|
||||
arg2 = self.mem[self.pc+2] if mode2 else self.mem[self.mem[self.pc+2]]
|
||||
self.mem[self.mem[self.pc+3]] = int(arg1 == arg2)
|
||||
self.pc += 4
|
||||
elif opcode == 99:
|
||||
self.running = False
|
||||
return
|
||||
|
||||
*mem, = map(int, open("input.txt").read().split(","))
|
||||
def test(seq):
|
||||
out = 0
|
||||
instances = []
|
||||
for i in range(5):
|
||||
instances.append(IntCode(mem[:]))
|
||||
instances[-1].inp.append(seq[i])
|
||||
instances[-1].start()
|
||||
|
||||
i = 0
|
||||
while instances[-1].running:
|
||||
instances[i].inp.append(out)
|
||||
instances[i].cont()
|
||||
out = instances[i].out.pop()
|
||||
i = (i + 1) % 5
|
||||
return out
|
||||
|
||||
print(max(test(seq) for seq in itertools.permutations(range(5, 10))))
|
53
Python/2019/08.py
Normal file
53
Python/2019/08.py
Normal file
|
@ -0,0 +1,53 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2019, 8)
|
||||
|
||||
wid = 25
|
||||
hei = 6
|
||||
|
||||
layers = []
|
||||
for i, c in enumerate(map(int, input.strip())):
|
||||
if i % (wid * hei) == 0:
|
||||
layers.append([])
|
||||
if i % wid == 0:
|
||||
layers[-1].append([])
|
||||
layers[-1][-1].append(c)
|
||||
|
||||
|
||||
def count(layer, digit):
|
||||
return sum(d == digit for l in layer for d in l)
|
||||
|
||||
|
||||
fewest = wid * hei
|
||||
out = 0
|
||||
for layer in layers:
|
||||
cnt = count(layer, 0)
|
||||
if cnt < fewest:
|
||||
fewest = cnt
|
||||
out = count(layer, 1) * count(layer, 2)
|
||||
print(out)
|
||||
|
||||
|
||||
wid = 25
|
||||
hei = 6
|
||||
|
||||
layers = []
|
||||
for i, c in enumerate(map(int, input.strip())):
|
||||
if i % (wid * hei) == 0:
|
||||
layers.append([])
|
||||
if i % wid == 0:
|
||||
layers[-1].append([])
|
||||
layers[-1][-1].append(c)
|
||||
|
||||
out = []
|
||||
for i in range(hei):
|
||||
out.append([])
|
||||
for j in range(wid):
|
||||
d = 2
|
||||
for layer in layers:
|
||||
if layer[i][j] != 2:
|
||||
d = layer[i][j]
|
||||
break
|
||||
out[-1].append(d)
|
||||
for l in out:
|
||||
print("".join(" #"[d] * 2 for d in l))
|
|
@ -1,22 +0,0 @@
|
|||
wid = 25
|
||||
hei = 6
|
||||
|
||||
layers = []
|
||||
for i, c in enumerate(map(int, open("input.txt").read().strip())):
|
||||
if i % (wid * hei) == 0:
|
||||
layers.append([])
|
||||
if i % wid == 0:
|
||||
layers[-1].append([])
|
||||
layers[-1][-1].append(c)
|
||||
|
||||
def count(layer, digit):
|
||||
return sum(d == digit for l in layer for d in l)
|
||||
|
||||
fewest = wid * hei
|
||||
out = 0
|
||||
for layer in layers:
|
||||
cnt = count(layer, 0)
|
||||
if cnt < fewest:
|
||||
fewest = cnt
|
||||
out = count(layer, 1) * count(layer, 2)
|
||||
print(out)
|
|
@ -1,23 +0,0 @@
|
|||
wid = 25
|
||||
hei = 6
|
||||
|
||||
layers = []
|
||||
for i, c in enumerate(map(int, open("input.txt").read().strip())):
|
||||
if i % (wid * hei) == 0:
|
||||
layers.append([])
|
||||
if i % wid == 0:
|
||||
layers[-1].append([])
|
||||
layers[-1][-1].append(c)
|
||||
|
||||
out = []
|
||||
for i in range(hei):
|
||||
out.append([])
|
||||
for j in range(wid):
|
||||
d = 2
|
||||
for layer in layers:
|
||||
if layer[i][j] != 2:
|
||||
d = layer[i][j]
|
||||
break
|
||||
out[-1].append(d)
|
||||
for l in out:
|
||||
print("".join(" #"[d]*2 for d in l))
|
|
@ -1,3 +1,8 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2019, 9)
|
||||
|
||||
|
||||
class IntCode:
|
||||
def __init__(self, mem):
|
||||
self.mem = {i: e for i, e in enumerate(mem)}
|
||||
|
@ -10,18 +15,18 @@ class IntCode:
|
|||
def start(self):
|
||||
self.running = True
|
||||
self.cont()
|
||||
|
||||
|
||||
def get_arg(self, i):
|
||||
mode = self.mem[self.pc] // (10 ** (i+1)) % 10
|
||||
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[out]
|
||||
|
||||
|
||||
def write_arg(self, i, value):
|
||||
mode = self.mem[self.pc] // (10 ** (i+1)) % 10
|
||||
mode = self.mem[self.pc] // (10 ** (i + 1)) % 10
|
||||
pos = self.mem[self.pc + i]
|
||||
assert mode != 1
|
||||
if mode == 2:
|
||||
|
@ -31,7 +36,7 @@ class IntCode:
|
|||
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
|
||||
|
@ -69,7 +74,15 @@ class IntCode:
|
|||
self.running = False
|
||||
return
|
||||
|
||||
*mem, = map(int, open("input.txt").read().split(","))
|
||||
|
||||
(*mem,) = map(int, input.split(","))
|
||||
intcode = IntCode(mem)
|
||||
intcode.inp.append(1)
|
||||
intcode.start()
|
||||
print(*intcode.out)
|
||||
|
||||
|
||||
(*mem,) = map(int, input.split(","))
|
||||
intcode = IntCode(mem)
|
||||
intcode.inp.append(2)
|
||||
intcode.start()
|
|
@ -1,76 +0,0 @@
|
|||
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[out]
|
||||
|
||||
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, open("input.txt").read().split(","))
|
||||
intcode = IntCode(mem)
|
||||
intcode.inp.append(1)
|
||||
intcode.start()
|
||||
print(*intcode.out)
|
|
@ -1,16 +1,16 @@
|
|||
from math import gcd, atan, pi
|
||||
from lib import *
|
||||
|
||||
*grid, = map(list, open("input.txt").read().splitlines())
|
||||
input = read_input(2019, 10)
|
||||
|
||||
|
||||
grid = input.splitlines()
|
||||
height = len(grid)
|
||||
width = len(grid[0])
|
||||
assert all(width == len(l) for l in grid)
|
||||
|
||||
def calc_angle(x, y):
|
||||
if not x:
|
||||
return 0
|
||||
return atan(y / x) * pi / 180 + 90
|
||||
|
||||
def check(x, y, x2, y2):
|
||||
steps = gcd(abs(x2 - x), abs(y2 - y))
|
||||
steps = math.gcd(abs(x2 - x), abs(y2 - y))
|
||||
xstep = (x2 - x) // steps
|
||||
ystep = (y2 - y) // steps
|
||||
for _ in range(steps - 1):
|
||||
|
@ -20,6 +20,7 @@ def check(x, y, x2, y2):
|
|||
return False
|
||||
return True
|
||||
|
||||
|
||||
def count(x, y):
|
||||
out = 0
|
||||
for y2 in range(height):
|
||||
|
@ -28,6 +29,41 @@ def count(x, y):
|
|||
out += 1
|
||||
return out
|
||||
|
||||
|
||||
print(max(count(x, y) for y in range(height) for x in range(width) if grid[y][x] == "#"))
|
||||
|
||||
(*grid,) = map(list, input.splitlines())
|
||||
height = len(grid)
|
||||
width = len(grid[0])
|
||||
|
||||
|
||||
def calc_angle(x, y):
|
||||
if not x:
|
||||
return 0
|
||||
return math.atan(y / x) * math.pi / 180 + 90
|
||||
|
||||
|
||||
def check(x, y, x2, y2):
|
||||
steps = math.gcd(abs(x2 - x), abs(y2 - y))
|
||||
xstep = (x2 - x) // steps
|
||||
ystep = (y2 - y) // steps
|
||||
for _ in range(steps - 1):
|
||||
x += xstep
|
||||
y += ystep
|
||||
if grid[y][x] == "#":
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def count(x, y):
|
||||
out = 0
|
||||
for y2 in range(height):
|
||||
for x2 in range(width):
|
||||
if (x != x2 or y != y2) and grid[y2][x2] == "#" and check(x, y, x2, y2):
|
||||
out += 1
|
||||
return out
|
||||
|
||||
|
||||
asteroids = [(x, y) for y in range(height) for x in range(width) if grid[y][x] == "#"]
|
||||
lx, ly = max(asteroids, key=lambda a: count(*a))
|
||||
asteroids.remove((lx, ly))
|
|
@ -1,27 +0,0 @@
|
|||
from math import gcd
|
||||
|
||||
grid = open("input.txt").read().splitlines()
|
||||
height = len(grid)
|
||||
width = len(grid[0])
|
||||
assert all(width == len(l) for l in grid)
|
||||
|
||||
def check(x, y, x2, y2):
|
||||
steps = gcd(abs(x2 - x), abs(y2 - y))
|
||||
xstep = (x2 - x) // steps
|
||||
ystep = (y2 - y) // steps
|
||||
for _ in range(steps - 1):
|
||||
x += xstep
|
||||
y += ystep
|
||||
if grid[y][x] == "#":
|
||||
return False
|
||||
return True
|
||||
|
||||
def count(x, y):
|
||||
out = 0
|
||||
for y2 in range(height):
|
||||
for x2 in range(width):
|
||||
if (x != x2 or y != y2) and grid[y2][x2] == "#" and check(x, y, x2, y2):
|
||||
out += 1
|
||||
return out
|
||||
|
||||
print(max(count(x, y) for y in range(height) for x in range(width) if grid[y][x] == "#"))
|
|
@ -1,3 +1,8 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2019, 11)
|
||||
|
||||
|
||||
class IntCode:
|
||||
def __init__(self, mem):
|
||||
self.mem = {i: e for i, e in enumerate(mem)}
|
||||
|
@ -10,18 +15,18 @@ class IntCode:
|
|||
def start(self):
|
||||
self.running = True
|
||||
self.cont()
|
||||
|
||||
|
||||
def get_arg(self, i):
|
||||
mode = self.mem[self.pc] // (10 ** (i+1)) % 10
|
||||
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
|
||||
mode = self.mem[self.pc] // (10 ** (i + 1)) % 10
|
||||
pos = self.mem[self.pc + i]
|
||||
assert mode != 1
|
||||
if mode == 2:
|
||||
|
@ -31,7 +36,7 @@ class IntCode:
|
|||
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
|
||||
|
@ -69,7 +74,28 @@ class IntCode:
|
|||
self.running = False
|
||||
return
|
||||
|
||||
*mem, = map(int, open("input.txt").read().split(","))
|
||||
|
||||
(*mem,) = map(int, input.split(","))
|
||||
intcode = IntCode(mem)
|
||||
intcode.start()
|
||||
o = {}
|
||||
x = y = 0
|
||||
dx = 0
|
||||
dy = -1
|
||||
while intcode.running:
|
||||
intcode.inp.append(o.get((x, y), 0))
|
||||
intcode.cont()
|
||||
o[(x, y)] = intcode.out.pop(0)
|
||||
if intcode.out.pop(0):
|
||||
dx, dy = -dy, dx
|
||||
else:
|
||||
dx, dy = dy, -dx
|
||||
x += dx
|
||||
y += dy
|
||||
print(len(o))
|
||||
|
||||
|
||||
(*mem,) = map(int, input.split(","))
|
||||
intcode = IntCode(mem)
|
||||
intcode.start()
|
||||
o = {(0, 0): 1}
|
||||
|
@ -92,4 +118,4 @@ while intcode.running:
|
|||
x += dx
|
||||
y += dy
|
||||
for y in range(miny, maxy + 1):
|
||||
print("".join(2*" #"[o.get((x, y), 0)] for x in range(minx, maxx + 1)))
|
||||
print("".join(2 * " #"[o.get((x, y), 0)] for x in range(minx, maxx + 1)))
|
|
@ -1,89 +0,0 @@
|
|||
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, open("input.txt").read().split(","))
|
||||
intcode = IntCode(mem)
|
||||
intcode.start()
|
||||
o = {}
|
||||
x = y = 0
|
||||
dx = 0
|
||||
dy = -1
|
||||
while intcode.running:
|
||||
intcode.inp.append(o.get((x, y), 0))
|
||||
intcode.cont()
|
||||
o[(x, y)] = intcode.out.pop(0)
|
||||
if intcode.out.pop(0):
|
||||
dx, dy = -dy, dx
|
||||
else:
|
||||
dx, dy = dy, -dx
|
||||
x += dx
|
||||
y += dy
|
||||
print(len(o))
|
|
@ -1,14 +1,36 @@
|
|||
import math
|
||||
import re
|
||||
from lib import *
|
||||
|
||||
input = read_input(2019, 12)
|
||||
|
||||
moons = []
|
||||
for line in open("input.txt").read().splitlines():
|
||||
for line in input.splitlines():
|
||||
x, y, z = map(int, re.match(r"^<x=([\-\d]+), y=([\-\d]+), z=([\-\d]+)>$", line).groups())
|
||||
moons.append(([x, y, z], [0, 0, 0]))
|
||||
|
||||
for _ in range(1000):
|
||||
for pos, vel in moons:
|
||||
for p2, _ in moons:
|
||||
for i in range(3):
|
||||
if pos[i] < p2[i]:
|
||||
vel[i] += 1
|
||||
elif pos[i] > p2[i]:
|
||||
vel[i] -= 1
|
||||
for pos, vel in moons:
|
||||
for i in range(3):
|
||||
pos[i] += vel[i]
|
||||
print(sum(sum(map(abs, pos)) * sum(map(abs, vel)) for pos, vel in moons))
|
||||
|
||||
|
||||
moons = []
|
||||
for line in input.splitlines():
|
||||
x, y, z = map(int, re.match(r"^<x=([\-\d]+), y=([\-\d]+), z=([\-\d]+)>$", line).groups())
|
||||
moons.append(([x, y, z], [0, 0, 0]))
|
||||
|
||||
|
||||
def make_state(dim):
|
||||
return tuple(e[dim] for moon in moons for e in moon)
|
||||
|
||||
|
||||
def simulate_dimension(dim):
|
||||
history = {}
|
||||
time = 0
|
||||
|
@ -28,6 +50,7 @@ def simulate_dimension(dim):
|
|||
for pos, vel in moons:
|
||||
pos[dim] += vel[dim]
|
||||
|
||||
|
||||
x, y, z = map(simulate_dimension, range(3))
|
||||
out = x * y // math.gcd(x, y)
|
||||
out = out * z // math.gcd(out, z)
|
|
@ -1,19 +0,0 @@
|
|||
import re
|
||||
|
||||
moons = []
|
||||
for line in open("input.txt").read().splitlines():
|
||||
x, y, z = map(int, re.match(r"^<x=([\-\d]+), y=([\-\d]+), z=([\-\d]+)>$", line).groups())
|
||||
moons.append(([x, y, z], [0, 0, 0]))
|
||||
|
||||
for _ in range(1000):
|
||||
for pos, vel in moons:
|
||||
for p2, _ in moons:
|
||||
for i in range(3):
|
||||
if pos[i] < p2[i]:
|
||||
vel[i] += 1
|
||||
elif pos[i] > p2[i]:
|
||||
vel[i] -= 1
|
||||
for pos, vel in moons:
|
||||
for i in range(3):
|
||||
pos[i] += vel[i]
|
||||
print(sum(sum(map(abs, pos)) * sum(map(abs, vel)) for pos, vel in moons))
|
|
@ -1,3 +1,8 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2019, 13)
|
||||
|
||||
|
||||
class IntCode:
|
||||
def __init__(self, mem):
|
||||
self.mem = {i: e for i, e in enumerate(mem)}
|
||||
|
@ -10,18 +15,18 @@ class IntCode:
|
|||
def start(self):
|
||||
self.running = True
|
||||
self.cont()
|
||||
|
||||
|
||||
def get_arg(self, i):
|
||||
mode = self.mem[self.pc] // (10 ** (i+1)) % 10
|
||||
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
|
||||
mode = self.mem[self.pc] // (10 ** (i + 1)) % 10
|
||||
pos = self.mem[self.pc + i]
|
||||
assert mode != 1
|
||||
if mode == 2:
|
||||
|
@ -31,7 +36,7 @@ class IntCode:
|
|||
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
|
||||
|
@ -69,7 +74,19 @@ class IntCode:
|
|||
self.running = False
|
||||
return
|
||||
|
||||
*mem, = map(int, open("input.txt").read().split(","))
|
||||
|
||||
(*mem,) = map(int, input.split(","))
|
||||
intcode = IntCode(mem)
|
||||
intcode.start()
|
||||
blocks = 0
|
||||
while intcode.out:
|
||||
_, _, t = intcode.out[:3]
|
||||
del intcode.out[:3]
|
||||
blocks += t == 2
|
||||
print(blocks)
|
||||
|
||||
|
||||
(*mem,) = map(int, input.split(","))
|
||||
mem[0] = 2
|
||||
intcode = IntCode(mem)
|
||||
intcode.start()
|
|
@ -1,80 +0,0 @@
|
|||
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, open("input.txt").read().split(","))
|
||||
intcode = IntCode(mem)
|
||||
intcode.start()
|
||||
blocks = 0
|
||||
while intcode.out:
|
||||
_, _, t = intcode.out[:3]
|
||||
del intcode.out[:3]
|
||||
blocks += t == 2
|
||||
print(blocks)
|
|
@ -1,14 +1,54 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2019, 14)
|
||||
|
||||
|
||||
def ceil(a, b):
|
||||
return a // b + (a % b > 0)
|
||||
|
||||
|
||||
reactions = {}
|
||||
for line in open("input.txt").read().splitlines():
|
||||
for line in input.splitlines():
|
||||
reactants, product = line.split(" => ")
|
||||
reactants = [reactant.split() for reactant in reactants.split(", ")]
|
||||
amount, product = product.split()
|
||||
assert product not in reactions
|
||||
reactions[product] = ([(reactant, int(amount)) for amount, reactant in reactants], int(amount))
|
||||
|
||||
ore_used = 0
|
||||
chemicals = {}
|
||||
Q = [("FUEL", 1)]
|
||||
while Q:
|
||||
chemical, prod_amount = Q.pop(0)
|
||||
if chemical == "ORE":
|
||||
ore_used += prod_amount
|
||||
continue
|
||||
chem_amount = chemicals.get(chemical, 0)
|
||||
reaction_amount = prod_amount - chem_amount
|
||||
if reaction_amount <= 0:
|
||||
chemicals[chemical] -= prod_amount
|
||||
continue
|
||||
reactants, product_amount = reactions[chemical]
|
||||
reaction_count = ceil(reaction_amount, product_amount)
|
||||
for reactant, amount in reactants:
|
||||
Q.append((reactant, amount * reaction_count))
|
||||
chemicals[chemical] = chem_amount + reaction_count * product_amount - prod_amount
|
||||
print(ore_used)
|
||||
|
||||
|
||||
def ceil(a, b):
|
||||
return a // b + (a % b > 0)
|
||||
|
||||
|
||||
reactions = {}
|
||||
for line in input.splitlines():
|
||||
reactants, product = line.split(" => ")
|
||||
reactants = [reactant.split() for reactant in reactants.split(", ")]
|
||||
amount, product = product.split()
|
||||
assert product not in reactions
|
||||
reactions[product] = ([(reactant, int(amount)) for amount, reactant in reactants], int(amount))
|
||||
|
||||
|
||||
def get_ore_used(amount):
|
||||
ore_used = 0
|
||||
chemicals = {}
|
||||
|
@ -30,6 +70,7 @@ def get_ore_used(amount):
|
|||
chemicals[chemical] = chem_amount + reaction_count * product_amount - prod_amount
|
||||
return ore_used
|
||||
|
||||
|
||||
LIMIT = 1000000000000
|
||||
low = 0
|
||||
high = LIMIT
|
|
@ -1,30 +0,0 @@
|
|||
def ceil(a, b):
|
||||
return a // b + (a % b > 0)
|
||||
|
||||
reactions = {}
|
||||
for line in open("input.txt").read().splitlines():
|
||||
reactants, product = line.split(" => ")
|
||||
reactants = [reactant.split() for reactant in reactants.split(", ")]
|
||||
amount, product = product.split()
|
||||
assert product not in reactions
|
||||
reactions[product] = ([(reactant, int(amount)) for amount, reactant in reactants], int(amount))
|
||||
|
||||
ore_used = 0
|
||||
chemicals = {}
|
||||
Q = [("FUEL", 1)]
|
||||
while Q:
|
||||
chemical, prod_amount = Q.pop(0)
|
||||
if chemical == "ORE":
|
||||
ore_used += prod_amount
|
||||
continue
|
||||
chem_amount = chemicals.get(chemical, 0)
|
||||
reaction_amount = prod_amount - chem_amount
|
||||
if reaction_amount <= 0:
|
||||
chemicals[chemical] -= prod_amount
|
||||
continue
|
||||
reactants, product_amount = reactions[chemical]
|
||||
reaction_count = ceil(reaction_amount, product_amount)
|
||||
for reactant, amount in reactants:
|
||||
Q.append((reactant, amount * reaction_count))
|
||||
chemicals[chemical] = chem_amount + reaction_count * product_amount - prod_amount
|
||||
print(ore_used)
|
|
@ -1,4 +1,7 @@
|
|||
import heapq
|
||||
from lib import *
|
||||
|
||||
input = read_input(2019, 15)
|
||||
|
||||
|
||||
class IntCode:
|
||||
def __init__(self, mem):
|
||||
|
@ -12,18 +15,18 @@ class IntCode:
|
|||
def start(self):
|
||||
self.running = True
|
||||
self.cont()
|
||||
|
||||
|
||||
def get_arg(self, i):
|
||||
mode = self.mem[self.pc] // (10 ** (i+1)) % 10
|
||||
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
|
||||
mode = self.mem[self.pc] // (10 ** (i + 1)) % 10
|
||||
pos = self.mem[self.pc + i]
|
||||
assert mode != 1
|
||||
if mode == 2:
|
||||
|
@ -33,7 +36,7 @@ class IntCode:
|
|||
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
|
||||
|
@ -71,6 +74,66 @@ class IntCode:
|
|||
self.running = False
|
||||
return
|
||||
|
||||
|
||||
NORTH, SOUTH, WEST, EAST = range(1, 5)
|
||||
DIRECTIONS = [(0, -1), (0, 1), (-1, 0), (1, 0)]
|
||||
BACK = {NORTH: SOUTH, SOUTH: NORTH, WEST: EAST, EAST: WEST}
|
||||
HIT_WALL, MOVED, REACHED_GOAL = range(3)
|
||||
UNKNOWN, EMPTY, WALL, GOAL = range(4)
|
||||
grid = {(0, 0): EMPTY}
|
||||
|
||||
|
||||
def get(x, y):
|
||||
return grid.get((x, y), 0)
|
||||
|
||||
|
||||
def put(x, y, v):
|
||||
grid[(x, y)] = v
|
||||
|
||||
|
||||
def explore(x, y):
|
||||
for direction, (dx, dy) in enumerate(DIRECTIONS):
|
||||
if get(x + dx, y + dy):
|
||||
continue
|
||||
|
||||
intcode.inp.append(direction + 1)
|
||||
intcode.cont()
|
||||
result = intcode.out.pop(0)
|
||||
if result == HIT_WALL:
|
||||
put(x + dx, y + dy, WALL)
|
||||
continue
|
||||
elif result == MOVED:
|
||||
put(x + dx, y + dy, EMPTY)
|
||||
elif result == REACHED_GOAL:
|
||||
put(x + dx, y + dy, GOAL)
|
||||
explore(x + dx, y + dy)
|
||||
intcode.inp.append(BACK[direction + 1])
|
||||
intcode.cont()
|
||||
intcode.out.pop(0)
|
||||
|
||||
|
||||
(*mem,) = map(int, input.split(","))
|
||||
intcode = IntCode(mem)
|
||||
intcode.start()
|
||||
explore(0, 0)
|
||||
|
||||
Q = [(0, 0, 0)]
|
||||
visited = set()
|
||||
while Q:
|
||||
d, x, y = heapq.heappop(Q)
|
||||
|
||||
if (x, y) in visited:
|
||||
continue
|
||||
visited.add((x, y))
|
||||
|
||||
if get(x, y) == GOAL:
|
||||
print(d)
|
||||
break
|
||||
|
||||
for dx, dy in DIRECTIONS:
|
||||
if get(x + dx, y + dy) != WALL:
|
||||
heapq.heappush(Q, (d + 1, x + dx, y + dy))
|
||||
|
||||
NORTH, SOUTH, WEST, EAST = range(1, 5)
|
||||
DIRECTIONS = [(0, -1), (0, 1), (-1, 0), (1, 0)]
|
||||
BACK = {NORTH: SOUTH, SOUTH: NORTH, WEST: EAST, EAST: WEST}
|
||||
|
@ -79,36 +142,40 @@ UNKNOWN, EMPTY, WALL, GOAL = range(4)
|
|||
grid = {(0, 0): EMPTY}
|
||||
goal = None
|
||||
|
||||
|
||||
def get(x, y):
|
||||
return grid.get((x, y), 0)
|
||||
|
||||
|
||||
def put(x, y, v):
|
||||
global goal
|
||||
if v == GOAL:
|
||||
goal = x, y
|
||||
grid[(x, y)] = v
|
||||
|
||||
|
||||
def explore(x, y):
|
||||
for direction, (dx, dy) in enumerate(DIRECTIONS):
|
||||
if get(x+dx, y+dy):
|
||||
if get(x + dx, y + dy):
|
||||
continue
|
||||
|
||||
intcode.inp.append(direction + 1)
|
||||
intcode.cont()
|
||||
result = intcode.out.pop(0)
|
||||
if result == HIT_WALL:
|
||||
put(x+dx, y+dy, WALL)
|
||||
put(x + dx, y + dy, WALL)
|
||||
continue
|
||||
elif result == MOVED:
|
||||
put(x+dx, y+dy, EMPTY)
|
||||
put(x + dx, y + dy, EMPTY)
|
||||
elif result == REACHED_GOAL:
|
||||
put(x+dx, y+dy, GOAL)
|
||||
explore(x+dx, y+dy)
|
||||
put(x + dx, y + dy, GOAL)
|
||||
explore(x + dx, y + dy)
|
||||
intcode.inp.append(BACK[direction + 1])
|
||||
intcode.cont()
|
||||
intcode.out.pop(0)
|
||||
|
||||
*mem, = map(int, open("input.txt").read().split(","))
|
||||
|
||||
(*mem,) = map(int, input.split(","))
|
||||
intcode = IntCode(mem)
|
||||
intcode.start()
|
||||
explore(0, 0)
|
||||
|
@ -118,7 +185,7 @@ visited = set()
|
|||
max_dist = 0
|
||||
while Q:
|
||||
d, x, y = heapq.heappop(Q)
|
||||
|
||||
|
||||
if (x, y) in visited:
|
||||
continue
|
||||
visited.add((x, y))
|
||||
|
@ -126,6 +193,6 @@ while Q:
|
|||
max_dist = max(d, max_dist)
|
||||
|
||||
for dx, dy in DIRECTIONS:
|
||||
if get(x+dx, y+dy) != WALL:
|
||||
heapq.heappush(Q, (d + 1, x+dx, y+dy))
|
||||
if get(x + dx, y + dy) != WALL:
|
||||
heapq.heappush(Q, (d + 1, x + dx, y + dy))
|
||||
print(max_dist)
|
|
@ -1,127 +0,0 @@
|
|||
import heapq
|
||||
|
||||
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
|
||||
|
||||
NORTH, SOUTH, WEST, EAST = range(1, 5)
|
||||
DIRECTIONS = [(0, -1), (0, 1), (-1, 0), (1, 0)]
|
||||
BACK = {NORTH: SOUTH, SOUTH: NORTH, WEST: EAST, EAST: WEST}
|
||||
HIT_WALL, MOVED, REACHED_GOAL = range(3)
|
||||
UNKNOWN, EMPTY, WALL, GOAL = range(4)
|
||||
grid = {(0, 0): EMPTY}
|
||||
|
||||
def get(x, y):
|
||||
return grid.get((x, y), 0)
|
||||
|
||||
def put(x, y, v):
|
||||
grid[(x, y)] = v
|
||||
|
||||
def explore(x, y):
|
||||
for direction, (dx, dy) in enumerate(DIRECTIONS):
|
||||
if get(x+dx, y+dy):
|
||||
continue
|
||||
|
||||
intcode.inp.append(direction + 1)
|
||||
intcode.cont()
|
||||
result = intcode.out.pop(0)
|
||||
if result == HIT_WALL:
|
||||
put(x+dx, y+dy, WALL)
|
||||
continue
|
||||
elif result == MOVED:
|
||||
put(x+dx, y+dy, EMPTY)
|
||||
elif result == REACHED_GOAL:
|
||||
put(x+dx, y+dy, GOAL)
|
||||
explore(x+dx, y+dy)
|
||||
intcode.inp.append(BACK[direction + 1])
|
||||
intcode.cont()
|
||||
intcode.out.pop(0)
|
||||
|
||||
*mem, = map(int, open("input.txt").read().split(","))
|
||||
intcode = IntCode(mem)
|
||||
intcode.start()
|
||||
explore(0, 0)
|
||||
|
||||
Q = [(0, 0, 0)]
|
||||
visited = set()
|
||||
while Q:
|
||||
d, x, y = heapq.heappop(Q)
|
||||
|
||||
if (x, y) in visited:
|
||||
continue
|
||||
visited.add((x, y))
|
||||
|
||||
if get(x, y) == GOAL:
|
||||
print(d)
|
||||
break
|
||||
|
||||
for dx, dy in DIRECTIONS:
|
||||
if get(x+dx, y+dy) != WALL:
|
||||
heapq.heappush(Q, (d + 1, x+dx, y+dy))
|
|
@ -1,4 +1,8 @@
|
|||
*lst, = map(int, open("input.txt").read().strip())
|
||||
from lib import *
|
||||
|
||||
input = read_input(2019, 16)
|
||||
|
||||
(*lst,) = map(int, input.strip())
|
||||
n = len(lst)
|
||||
|
||||
for _ in range(100):
|
||||
|
@ -24,3 +28,19 @@ for _ in range(100):
|
|||
lst = out
|
||||
|
||||
print("".join(map(str, lst[:8])))
|
||||
|
||||
|
||||
(*lst,) = map(int, input.strip())
|
||||
offset = int("".join(map(str, lst[:7])))
|
||||
lst = (lst * 10_000)[: offset - 1 : -1]
|
||||
n = len(lst)
|
||||
|
||||
for _ in range(100):
|
||||
out = []
|
||||
s = 0
|
||||
for i in range(n):
|
||||
s = (s + lst[i]) % 10
|
||||
out.append(s)
|
||||
lst = out
|
||||
|
||||
print("".join(map(str, lst[:-9:-1])))
|
|
@ -1,15 +0,0 @@
|
|||
*lst, = map(int, open("input.txt").read().strip())
|
||||
offset = int("".join(map(str, lst[:7])))
|
||||
lst = (lst * 10_000)[:offset-1:-1]
|
||||
n = len(lst)
|
||||
|
||||
for _ in range(100):
|
||||
out = []
|
||||
s = 0
|
||||
for i in range(n):
|
||||
s = (s + lst[i]) % 10
|
||||
out.append(s)
|
||||
lst = out
|
||||
|
||||
print("".join(map(str, lst[:-9:-1])))
|
||||
|
|
@ -1,3 +1,8 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2019, 17)
|
||||
|
||||
|
||||
class IntCode:
|
||||
def __init__(self, mem):
|
||||
self.mem = {i: e for i, e in enumerate(mem)}
|
||||
|
@ -10,18 +15,18 @@ class IntCode:
|
|||
def start(self):
|
||||
self.running = True
|
||||
self.cont()
|
||||
|
||||
|
||||
def get_arg(self, i):
|
||||
mode = self.mem[self.pc] // (10 ** (i+1)) % 10
|
||||
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
|
||||
mode = self.mem[self.pc] // (10 ** (i + 1)) % 10
|
||||
pos = self.mem[self.pc + i]
|
||||
assert mode != 1
|
||||
if mode == 2:
|
||||
|
@ -31,7 +36,7 @@ class IntCode:
|
|||
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
|
||||
|
@ -69,19 +74,37 @@ class IntCode:
|
|||
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
|
||||
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, open("input.txt").read().split(","))
|
||||
(*mem,) = map(int, input.split(","))
|
||||
mem[0] = 2
|
||||
intcode = IntCode(mem)
|
||||
intcode.start()
|
||||
|
@ -114,6 +137,7 @@ while True:
|
|||
if cnt:
|
||||
instructions.append(inst + "," + str(cnt))
|
||||
|
||||
|
||||
def get_groups(start, groups):
|
||||
if start >= len(instructions):
|
||||
return groups
|
||||
|
@ -131,12 +155,13 @@ def get_groups(start, 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)]:
|
||||
if g == instructions[i : i + len(g)]:
|
||||
main.append("ABC"[j])
|
||||
i += len(g)
|
||||
break
|
|
@ -1,81 +0,0 @@
|
|||
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, open("input.txt").read().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)
|
185
Python/2019/18.py
Normal file
185
Python/2019/18.py
Normal file
|
@ -0,0 +1,185 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2019, 18)
|
||||
|
||||
|
||||
KEY_INDEX = {a: i for i, a in enumerate(string.ascii_lowercase)}
|
||||
|
||||
|
||||
def key_to_num(key):
|
||||
return 1 << KEY_INDEX[key.lower()]
|
||||
|
||||
|
||||
grid = []
|
||||
pos = None
|
||||
key_count = 0
|
||||
graph = {}
|
||||
nodes = {}
|
||||
for i, line in enumerate(input.splitlines()):
|
||||
for j, c in enumerate(line):
|
||||
if "a" <= c <= "z":
|
||||
key_count += 1
|
||||
graph[c] = {}
|
||||
nodes[c] = j, i
|
||||
elif "A" <= c <= "Z":
|
||||
graph[c] = {}
|
||||
nodes[c] = j, i
|
||||
elif c == "@":
|
||||
pos = j, i
|
||||
graph[c] = {}
|
||||
nodes[c] = j, i
|
||||
grid.append(line)
|
||||
|
||||
for src in graph:
|
||||
Q = [(*nodes[src], 0)]
|
||||
visited = set()
|
||||
while Q:
|
||||
x, y, d = Q.pop(0)
|
||||
|
||||
if (x, y) in visited:
|
||||
continue
|
||||
visited.add((x, y))
|
||||
|
||||
cell = grid[y][x]
|
||||
if cell != src and cell in graph:
|
||||
graph[src][cell] = min(d, graph[src].get(cell, 1e1337))
|
||||
continue
|
||||
|
||||
for dx, dy in [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)]:
|
||||
if not (dx in range(len(grid[0])) and dy in range(len(grid))):
|
||||
continue
|
||||
if grid[dy][dx] == "#":
|
||||
continue
|
||||
Q.append((dx, dy, d + 1))
|
||||
|
||||
visited = set()
|
||||
Q = [(0, "@", 0)]
|
||||
while Q:
|
||||
d, p, keys = heapq.heappop(Q)
|
||||
|
||||
if (p, keys) in visited:
|
||||
continue
|
||||
visited.add((p, keys))
|
||||
|
||||
if keys == (1 << key_count) - 1:
|
||||
print(d)
|
||||
break
|
||||
|
||||
j, i = nodes[p]
|
||||
cell = grid[i][j]
|
||||
if "a" <= cell <= "z" and not key_to_num(cell) & keys:
|
||||
heapq.heappush(Q, (d, p, keys | key_to_num(cell)))
|
||||
continue
|
||||
|
||||
for q, dist in graph[p].items():
|
||||
if "A" <= q <= "Z" and not key_to_num(q.lower()) & keys:
|
||||
continue
|
||||
heapq.heappush(Q, (d + dist, q, keys))
|
||||
|
||||
|
||||
grid = []
|
||||
pos = None
|
||||
key_count = 0
|
||||
graph = {str(i): {} for i in range(4)}
|
||||
nodes = {str(i): None for i in range(4)}
|
||||
for i, line in enumerate(input.splitlines()):
|
||||
line = list(line)
|
||||
for j, c in enumerate(line):
|
||||
if "a" <= c <= "z":
|
||||
key_count += 1
|
||||
graph[c] = {}
|
||||
nodes[c] = j, i
|
||||
elif "A" <= c <= "Z":
|
||||
graph[c] = {}
|
||||
nodes[c] = j, i
|
||||
elif c == "@":
|
||||
pos = j, i
|
||||
graph[c] = {}
|
||||
nodes[c] = j, i
|
||||
grid.append(line)
|
||||
|
||||
sector_keys = [
|
||||
set(grid[i][j] for i in range(len(grid) // 2) for j in range(len(grid[0]) // 2) if "a" <= grid[i][j] <= "z"),
|
||||
set(
|
||||
grid[i][j]
|
||||
for i in range(len(grid) // 2)
|
||||
for j in range(len(grid[0]) // 2, len(grid[0]))
|
||||
if "a" <= grid[i][j] <= "z"
|
||||
),
|
||||
set(
|
||||
grid[i][j]
|
||||
for i in range(len(grid) // 2, len(grid))
|
||||
for j in range(len(grid[0]) // 2)
|
||||
if "a" <= grid[i][j] <= "z"
|
||||
),
|
||||
set(
|
||||
grid[i][j]
|
||||
for i in range(len(grid) // 2, len(grid))
|
||||
for j in range(len(grid[0]) // 2, len(grid[0]))
|
||||
if "a" <= grid[i][j] <= "z"
|
||||
),
|
||||
]
|
||||
|
||||
j, i = pos
|
||||
del graph["@"]
|
||||
del nodes["@"]
|
||||
for i, j in [(i, j), (i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
|
||||
grid[i][j] = "#"
|
||||
j, i = pos
|
||||
grid[i - 1][j - 1] = "0"
|
||||
grid[i - 1][j + 1] = "1"
|
||||
grid[i + 1][j - 1] = "2"
|
||||
grid[i + 1][j + 1] = "3"
|
||||
nodes["0"] = j - 1, i - 1
|
||||
nodes["1"] = j + 1, i - 1
|
||||
nodes["2"] = j - 1, i + 1
|
||||
nodes["3"] = j + 1, i + 1
|
||||
|
||||
for src in graph:
|
||||
Q = [(*nodes[src], 0)]
|
||||
visited = set()
|
||||
while Q:
|
||||
x, y, d = Q.pop(0)
|
||||
|
||||
if (x, y) in visited:
|
||||
continue
|
||||
visited.add((x, y))
|
||||
|
||||
cell = grid[y][x]
|
||||
if cell != src and cell in graph:
|
||||
graph[src][cell] = min(d, graph[src].get(cell, 1e1337))
|
||||
continue
|
||||
|
||||
for dx, dy in [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)]:
|
||||
if not (dx in range(len(grid[0])) and dy in range(len(grid))):
|
||||
continue
|
||||
if grid[dy][dx] == "#":
|
||||
continue
|
||||
Q.append((dx, dy, d + 1))
|
||||
|
||||
out = 0
|
||||
for robot in range(4):
|
||||
visited = set()
|
||||
Q = [(0, str(robot), 0)]
|
||||
while Q:
|
||||
d, p, keys = heapq.heappop(Q)
|
||||
|
||||
if (p, keys) in visited:
|
||||
continue
|
||||
visited.add((p, keys))
|
||||
|
||||
if keys == sum(key_to_num(ek) for ek in sector_keys[robot]):
|
||||
out += d
|
||||
break
|
||||
|
||||
j, i = nodes[p]
|
||||
cell = grid[i][j]
|
||||
if "a" <= cell <= "z" and not key_to_num(cell) & keys:
|
||||
heapq.heappush(Q, (d, p, keys | key_to_num(cell)))
|
||||
continue
|
||||
|
||||
for q, dist in graph[p].items():
|
||||
if "A" <= q <= "Z" and not key_to_num(q.lower()) & keys and q in sector_keys[robot]:
|
||||
continue
|
||||
heapq.heappush(Q, (d + dist, q, keys))
|
||||
print(out)
|
|
@ -1,72 +0,0 @@
|
|||
from string import ascii_lowercase as letters
|
||||
import heapq
|
||||
|
||||
KEY_INDEX = {a: i for i, a in enumerate(letters)}
|
||||
def key_to_num(key):
|
||||
return 1 << KEY_INDEX[key.lower()]
|
||||
|
||||
grid = []
|
||||
pos = None
|
||||
key_count = 0
|
||||
graph = {}
|
||||
nodes = {}
|
||||
for i, line in enumerate(open("input.txt").read().splitlines()):
|
||||
for j, c in enumerate(line):
|
||||
if "a" <= c <= "z":
|
||||
key_count += 1
|
||||
graph[c] = {}
|
||||
nodes[c] = j, i
|
||||
elif "A" <= c <= "Z":
|
||||
graph[c] = {}
|
||||
nodes[c] = j, i
|
||||
elif c == "@":
|
||||
pos = j, i
|
||||
graph[c] = {}
|
||||
nodes[c] = j, i
|
||||
grid.append(line)
|
||||
|
||||
for src in graph:
|
||||
Q = [(*nodes[src], 0)]
|
||||
visited = set()
|
||||
while Q:
|
||||
x, y, d = Q.pop(0)
|
||||
|
||||
if (x, y) in visited:
|
||||
continue
|
||||
visited.add((x, y))
|
||||
|
||||
cell = grid[y][x]
|
||||
if cell != src and cell in graph:
|
||||
graph[src][cell] = min(d, graph[src].get(cell, 1e1337))
|
||||
continue
|
||||
|
||||
for dx, dy in [(x-1,y), (x+1,y), (x,y-1), (x,y+1)]:
|
||||
if not (dx in range(len(grid[0])) and dy in range(len(grid))):
|
||||
continue
|
||||
if grid[dy][dx] == "#":
|
||||
continue
|
||||
Q.append((dx, dy, d + 1))
|
||||
|
||||
visited = set()
|
||||
Q = [(0, "@", 0)]
|
||||
while Q:
|
||||
d, p, keys = heapq.heappop(Q)
|
||||
|
||||
if (p, keys) in visited:
|
||||
continue
|
||||
visited.add((p, keys))
|
||||
|
||||
if keys == (1<<key_count) - 1:
|
||||
print(d)
|
||||
break
|
||||
|
||||
j, i = nodes[p]
|
||||
cell = grid[i][j]
|
||||
if "a" <= cell <= "z" and not key_to_num(cell) & keys:
|
||||
heapq.heappush(Q, (d, p, keys | key_to_num(cell)))
|
||||
continue
|
||||
|
||||
for q, dist in graph[p].items():
|
||||
if "A" <= q <= "Z" and not key_to_num(q.lower()) & keys:
|
||||
continue
|
||||
heapq.heappush(Q, (d + dist, q, keys))
|
|
@ -1,98 +0,0 @@
|
|||
from string import ascii_lowercase as letters
|
||||
import heapq
|
||||
|
||||
KEY_INDEX = {a: i for i, a in enumerate(letters)}
|
||||
def key_to_num(key):
|
||||
return 1 << KEY_INDEX[key.lower()]
|
||||
|
||||
grid = []
|
||||
pos = None
|
||||
key_count = 0
|
||||
graph = {str(i): {} for i in range(4)}
|
||||
nodes = {str(i): None for i in range(4)}
|
||||
for i, line in enumerate(open("input.txt").read().splitlines()):
|
||||
line = list(line)
|
||||
for j, c in enumerate(line):
|
||||
if "a" <= c <= "z":
|
||||
key_count += 1
|
||||
graph[c] = {}
|
||||
nodes[c] = j, i
|
||||
elif "A" <= c <= "Z":
|
||||
graph[c] = {}
|
||||
nodes[c] = j, i
|
||||
elif c == "@":
|
||||
pos = j, i
|
||||
graph[c] = {}
|
||||
nodes[c] = j, i
|
||||
grid.append(line)
|
||||
|
||||
sector_keys = [
|
||||
set(grid[i][j] for i in range(len(grid) // 2) for j in range(len(grid[0]) // 2) if "a" <= grid[i][j] <= "z"),
|
||||
set(grid[i][j] for i in range(len(grid) // 2) for j in range(len(grid[0]) // 2, len(grid[0])) if "a" <= grid[i][j] <= "z"),
|
||||
set(grid[i][j] for i in range(len(grid) // 2, len(grid)) for j in range(len(grid[0]) // 2) if "a" <= grid[i][j] <= "z"),
|
||||
set(grid[i][j] for i in range(len(grid) // 2, len(grid)) for j in range(len(grid[0]) // 2, len(grid[0])) if "a" <= grid[i][j] <= "z")
|
||||
]
|
||||
|
||||
j, i = pos
|
||||
del graph["@"]
|
||||
del nodes["@"]
|
||||
for i, j in [(i, j), (i-1, j), (i+1, j), (i, j-1), (i, j+1)]:
|
||||
grid[i][j] = "#"
|
||||
j, i = pos
|
||||
grid[i-1][j-1] = "0"
|
||||
grid[i-1][j+1] = "1"
|
||||
grid[i+1][j-1] = "2"
|
||||
grid[i+1][j+1] = "3"
|
||||
nodes["0"] = j-1, i-1
|
||||
nodes["1"] = j+1, i-1
|
||||
nodes["2"] = j-1, i+1
|
||||
nodes["3"] = j+1, i+1
|
||||
|
||||
for src in graph:
|
||||
Q = [(*nodes[src], 0)]
|
||||
visited = set()
|
||||
while Q:
|
||||
x, y, d = Q.pop(0)
|
||||
|
||||
if (x, y) in visited:
|
||||
continue
|
||||
visited.add((x, y))
|
||||
|
||||
cell = grid[y][x]
|
||||
if cell != src and cell in graph:
|
||||
graph[src][cell] = min(d, graph[src].get(cell, 1e1337))
|
||||
continue
|
||||
|
||||
for dx, dy in [(x-1,y), (x+1,y), (x,y-1), (x,y+1)]:
|
||||
if not (dx in range(len(grid[0])) and dy in range(len(grid))):
|
||||
continue
|
||||
if grid[dy][dx] == "#":
|
||||
continue
|
||||
Q.append((dx, dy, d + 1))
|
||||
|
||||
out = 0
|
||||
for robot in range(4):
|
||||
visited = set()
|
||||
Q = [(0, str(robot), 0)]
|
||||
while Q:
|
||||
d, p, keys = heapq.heappop(Q)
|
||||
|
||||
if (p, keys) in visited:
|
||||
continue
|
||||
visited.add((p, keys))
|
||||
|
||||
if keys == sum(key_to_num(ek) for ek in sector_keys[robot]):
|
||||
out += d
|
||||
break
|
||||
|
||||
j, i = nodes[p]
|
||||
cell = grid[i][j]
|
||||
if "a" <= cell <= "z" and not key_to_num(cell) & keys:
|
||||
heapq.heappush(Q, (d, p, keys | key_to_num(cell)))
|
||||
continue
|
||||
|
||||
for q, dist in graph[p].items():
|
||||
if "A" <= q <= "Z" and not key_to_num(q.lower()) & keys and q in sector_keys[robot]:
|
||||
continue
|
||||
heapq.heappush(Q, (d + dist, q, keys))
|
||||
print(out)
|
|
@ -1,107 +1,129 @@
|
|||
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, open("input.txt").read().split(","))
|
||||
|
||||
dp = {}
|
||||
def test(x, y):
|
||||
if (x, y) not in dp:
|
||||
intcode = IntCode(mem)
|
||||
intcode.inp += [x, y]
|
||||
intcode.start()
|
||||
dp[(x, y)] = intcode.out.pop(0)
|
||||
return dp[(x, y)]
|
||||
|
||||
SIZE = 100
|
||||
x = 0
|
||||
y = 0
|
||||
done = False
|
||||
while not done:
|
||||
y += 1
|
||||
for x in range(y + 1):
|
||||
if test(x, y - x):
|
||||
y = y - x
|
||||
done = True
|
||||
break
|
||||
|
||||
|
||||
while True:
|
||||
while not test(x, y):
|
||||
y += 1
|
||||
while test(x, y + 1):
|
||||
y += 1
|
||||
|
||||
assert test(x, y)
|
||||
if y >= SIZE - 1 and test(x + SIZE - 1, y - (SIZE - 1)):
|
||||
print(x * 10000 + y - (SIZE - 1))
|
||||
break
|
||||
|
||||
x += 1
|
||||
from lib import *
|
||||
|
||||
input = read_input(2019, 19)
|
||||
|
||||
|
||||
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(","))
|
||||
|
||||
|
||||
def test(x, y):
|
||||
intcode = IntCode(mem)
|
||||
intcode.inp += [x, y]
|
||||
intcode.start()
|
||||
return intcode.out.pop(0)
|
||||
|
||||
|
||||
print(sum(test(i, j) for i in range(50) for j in range(50)))
|
||||
|
||||
|
||||
(*mem,) = map(int, input.split(","))
|
||||
|
||||
dp = {}
|
||||
|
||||
|
||||
def test(x, y):
|
||||
if (x, y) not in dp:
|
||||
intcode = IntCode(mem)
|
||||
intcode.inp += [x, y]
|
||||
intcode.start()
|
||||
dp[(x, y)] = intcode.out.pop(0)
|
||||
return dp[(x, y)]
|
||||
|
||||
|
||||
SIZE = 100
|
||||
x = 0
|
||||
y = 0
|
||||
done = False
|
||||
while not done:
|
||||
y += 1
|
||||
for x in range(y + 1):
|
||||
if test(x, y - x):
|
||||
y = y - x
|
||||
done = True
|
||||
break
|
||||
|
||||
|
||||
while True:
|
||||
while not test(x, y):
|
||||
y += 1
|
||||
while test(x, y + 1):
|
||||
y += 1
|
||||
|
||||
assert test(x, y)
|
||||
if y >= SIZE - 1 and test(x + SIZE - 1, y - (SIZE - 1)):
|
||||
print(x * 10000 + y - (SIZE - 1))
|
||||
break
|
||||
|
||||
x += 1
|
|
@ -1,80 +0,0 @@
|
|||
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, open("input.txt").read().split(","))
|
||||
|
||||
def test(x, y):
|
||||
intcode = IntCode(mem)
|
||||
intcode.inp += [x, y]
|
||||
intcode.start()
|
||||
return intcode.out.pop(0)
|
||||
|
||||
print(sum(test(i, j) for i in range(50) for j in range(50)))
|
103
Python/2019/20.py
Normal file
103
Python/2019/20.py
Normal file
|
@ -0,0 +1,103 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2019, 20)
|
||||
|
||||
|
||||
(*maze,) = map(list, input.splitlines())
|
||||
hei = len(maze)
|
||||
wid = len(maze[0])
|
||||
portals = {}
|
||||
links = {}
|
||||
for i in range(2, hei - 2):
|
||||
for j in range(2, wid - 2):
|
||||
if maze[i][j] != ".":
|
||||
continue
|
||||
if "A" <= maze[i][j - 1] <= "Z":
|
||||
maze[i][j] = (maze[i][j - 2] + maze[i][j - 1]).lower()
|
||||
if "A" <= maze[i][j + 1] <= "Z":
|
||||
maze[i][j] = (maze[i][j + 1] + maze[i][j + 2]).lower()
|
||||
if "A" <= maze[i - 1][j] <= "Z":
|
||||
maze[i][j] = (maze[i - 2][j] + maze[i - 1][j]).lower()
|
||||
if "A" <= maze[i + 1][j] <= "Z":
|
||||
maze[i][j] = (maze[i + 1][j] + maze[i + 2][j]).lower()
|
||||
|
||||
name = maze[i][j]
|
||||
if name == ".":
|
||||
continue
|
||||
|
||||
if name in portals:
|
||||
portals[name].append((i, j))
|
||||
links[portals[name][0]] = portals[name][1]
|
||||
links[portals[name][1]] = portals[name][0]
|
||||
else:
|
||||
portals[name] = [(i, j)]
|
||||
|
||||
visited = set()
|
||||
Q = [(0, *portals["aa"][0])]
|
||||
while Q:
|
||||
d, i, j = heapq.heappop(Q)
|
||||
|
||||
if (i, j) in visited:
|
||||
continue
|
||||
visited.add((i, j))
|
||||
|
||||
if maze[i][j] == "zz":
|
||||
print(d)
|
||||
break
|
||||
|
||||
if (i, j) in links:
|
||||
heapq.heappush(Q, (d + 1, *links[(i, j)]))
|
||||
for p, q in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
|
||||
if maze[p][q] == "." or "aa" <= maze[p][q] <= "zz":
|
||||
heapq.heappush(Q, (d + 1, p, q))
|
||||
|
||||
(*maze,) = map(list, input.splitlines())
|
||||
hei = len(maze)
|
||||
wid = len(maze[0])
|
||||
portals = {}
|
||||
links = {}
|
||||
for i in range(2, hei - 2):
|
||||
for j in range(2, wid - 2):
|
||||
if maze[i][j] != ".":
|
||||
continue
|
||||
if "A" <= maze[i][j - 1] <= "Z":
|
||||
maze[i][j] = (maze[i][j - 2] + maze[i][j - 1]).lower()
|
||||
if "A" <= maze[i][j + 1] <= "Z":
|
||||
maze[i][j] = (maze[i][j + 1] + maze[i][j + 2]).lower()
|
||||
if "A" <= maze[i - 1][j] <= "Z":
|
||||
maze[i][j] = (maze[i - 2][j] + maze[i - 1][j]).lower()
|
||||
if "A" <= maze[i + 1][j] <= "Z":
|
||||
maze[i][j] = (maze[i + 1][j] + maze[i + 2][j]).lower()
|
||||
|
||||
name = maze[i][j]
|
||||
if name == ".":
|
||||
continue
|
||||
|
||||
inner = i not in (2, hei - 3) and j not in (2, wid - 3)
|
||||
if name in portals:
|
||||
portals[name].append((i, j))
|
||||
links[portals[name][0]] = (portals[name][1], 1 - 2 * inner)
|
||||
links[portals[name][1]] = (portals[name][0], 2 * inner - 1)
|
||||
else:
|
||||
portals[name] = [(i, j)]
|
||||
|
||||
visited = set()
|
||||
Q = [(0, *portals["aa"][0], 0)]
|
||||
while Q:
|
||||
d, i, j, m = heapq.heappop(Q)
|
||||
|
||||
if (i, j, m) in visited:
|
||||
continue
|
||||
visited.add((i, j, m))
|
||||
|
||||
if maze[i][j] == "zz" and m == 0:
|
||||
print(d)
|
||||
break
|
||||
|
||||
if (i, j) in links:
|
||||
link, change = links[(i, j)]
|
||||
if m + change >= 0:
|
||||
heapq.heappush(Q, (d + 1, *link, m + change))
|
||||
for p, q in [(i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)]:
|
||||
if maze[p][q] == "." or "aa" <= maze[p][q] <= "zz":
|
||||
heapq.heappush(Q, (d + 1, p, q, m))
|
|
@ -1,49 +0,0 @@
|
|||
import heapq
|
||||
|
||||
*maze, = map(list, open("input.txt").read().splitlines())
|
||||
hei = len(maze)
|
||||
wid = len(maze[0])
|
||||
portals = {}
|
||||
links = {}
|
||||
for i in range(2, hei - 2):
|
||||
for j in range(2, wid - 2):
|
||||
if maze[i][j] != ".":
|
||||
continue
|
||||
if "A" <= maze[i][j-1] <= "Z":
|
||||
maze[i][j] = (maze[i][j-2] + maze[i][j-1]).lower()
|
||||
if "A" <= maze[i][j+1] <= "Z":
|
||||
maze[i][j] = (maze[i][j+1] + maze[i][j+2]).lower()
|
||||
if "A" <= maze[i-1][j] <= "Z":
|
||||
maze[i][j] = (maze[i-2][j] + maze[i-1][j]).lower()
|
||||
if "A" <= maze[i+1][j] <= "Z":
|
||||
maze[i][j] = (maze[i+1][j] + maze[i+2][j]).lower()
|
||||
|
||||
name = maze[i][j]
|
||||
if name == ".":
|
||||
continue
|
||||
|
||||
if name in portals:
|
||||
portals[name].append((i, j))
|
||||
links[portals[name][0]] = portals[name][1]
|
||||
links[portals[name][1]] = portals[name][0]
|
||||
else:
|
||||
portals[name] = [(i, j)]
|
||||
|
||||
visited = set()
|
||||
Q = [(0, *portals["aa"][0])]
|
||||
while Q:
|
||||
d, i, j = heapq.heappop(Q)
|
||||
|
||||
if (i, j) in visited:
|
||||
continue
|
||||
visited.add((i, j))
|
||||
|
||||
if maze[i][j] == "zz":
|
||||
print(d)
|
||||
break
|
||||
|
||||
if (i, j) in links:
|
||||
heapq.heappush(Q, (d + 1, *links[(i, j)]))
|
||||
for p, q in [(i-1,j), (i+1,j), (i,j-1), (i,j+1)]:
|
||||
if maze[p][q] == "." or "aa" <= maze[p][q] <= "zz":
|
||||
heapq.heappush(Q, (d + 1, p, q))
|
|
@ -1,52 +0,0 @@
|
|||
import heapq
|
||||
|
||||
*maze, = map(list, open("input.txt").read().splitlines())
|
||||
hei = len(maze)
|
||||
wid = len(maze[0])
|
||||
portals = {}
|
||||
links = {}
|
||||
for i in range(2, hei - 2):
|
||||
for j in range(2, wid - 2):
|
||||
if maze[i][j] != ".":
|
||||
continue
|
||||
if "A" <= maze[i][j-1] <= "Z":
|
||||
maze[i][j] = (maze[i][j-2] + maze[i][j-1]).lower()
|
||||
if "A" <= maze[i][j+1] <= "Z":
|
||||
maze[i][j] = (maze[i][j+1] + maze[i][j+2]).lower()
|
||||
if "A" <= maze[i-1][j] <= "Z":
|
||||
maze[i][j] = (maze[i-2][j] + maze[i-1][j]).lower()
|
||||
if "A" <= maze[i+1][j] <= "Z":
|
||||
maze[i][j] = (maze[i+1][j] + maze[i+2][j]).lower()
|
||||
|
||||
name = maze[i][j]
|
||||
if name == ".":
|
||||
continue
|
||||
|
||||
inner = i not in (2, hei - 3) and j not in (2, wid - 3)
|
||||
if name in portals:
|
||||
portals[name].append((i, j))
|
||||
links[portals[name][0]] = (portals[name][1], 1 - 2 * inner)
|
||||
links[portals[name][1]] = (portals[name][0], 2 * inner - 1)
|
||||
else:
|
||||
portals[name] = [(i, j)]
|
||||
|
||||
visited = set()
|
||||
Q = [(0, *portals["aa"][0], 0)]
|
||||
while Q:
|
||||
d, i, j, m = heapq.heappop(Q)
|
||||
|
||||
if (i, j, m) in visited:
|
||||
continue
|
||||
visited.add((i, j, m))
|
||||
|
||||
if maze[i][j] == "zz" and m == 0:
|
||||
print(d)
|
||||
break
|
||||
|
||||
if (i, j) in links:
|
||||
link, change = links[(i, j)]
|
||||
if m + change >= 0:
|
||||
heapq.heappush(Q, (d + 1, *link, m + change))
|
||||
for p, q in [(i-1,j), (i+1,j), (i,j-1), (i,j+1)]:
|
||||
if maze[p][q] == "." or "aa" <= maze[p][q] <= "zz":
|
||||
heapq.heappush(Q, (d + 1, p, q, m))
|
|
@ -1,3 +1,8 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2019, 21)
|
||||
|
||||
|
||||
class IntCode:
|
||||
def __init__(self, mem):
|
||||
self.mem = {i: e for i, e in enumerate(mem)}
|
||||
|
@ -10,18 +15,18 @@ class IntCode:
|
|||
def start(self):
|
||||
self.running = True
|
||||
self.cont()
|
||||
|
||||
|
||||
def get_arg(self, i):
|
||||
mode = self.mem[self.pc] // (10 ** (i+1)) % 10
|
||||
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
|
||||
mode = self.mem[self.pc] // (10 ** (i + 1)) % 10
|
||||
pos = self.mem[self.pc + i]
|
||||
assert mode != 1
|
||||
if mode == 2:
|
||||
|
@ -31,7 +36,7 @@ class IntCode:
|
|||
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
|
||||
|
@ -69,7 +74,18 @@ class IntCode:
|
|||
self.running = False
|
||||
return
|
||||
|
||||
*mem, = map(int, open("input.txt").read().split(","))
|
||||
|
||||
(*mem,) = map(int, input.split(","))
|
||||
intcode = IntCode(mem)
|
||||
intcode.start()
|
||||
intcode.out.clear()
|
||||
INSTRUCTIONS = ["NOT A J", "NOT B T", "OR T J", "NOT C T", "OR T J", "AND D J", "WALK"]
|
||||
intcode.inp += map(ord, "".join(i + "\n" for i in INSTRUCTIONS))
|
||||
intcode.cont()
|
||||
print(intcode.out[-1])
|
||||
|
||||
|
||||
(*mem,) = map(int, input.split(","))
|
||||
intcode = IntCode(mem)
|
||||
intcode.start()
|
||||
intcode.out.clear()
|
||||
|
@ -86,7 +102,7 @@ INSTRUCTIONS = [
|
|||
"AND E T",
|
||||
"OR H T",
|
||||
"AND T J",
|
||||
"RUN"
|
||||
"RUN",
|
||||
]
|
||||
intcode.inp += map(ord, "".join(i + "\n" for i in INSTRUCTIONS))
|
||||
intcode.cont()
|
|
@ -1,87 +0,0 @@
|
|||
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, open("input.txt").read().split(","))
|
||||
intcode = IntCode(mem)
|
||||
intcode.start()
|
||||
intcode.out.clear()
|
||||
INSTRUCTIONS = [
|
||||
"NOT A J",
|
||||
"NOT B T",
|
||||
"OR T J",
|
||||
"NOT C T",
|
||||
"OR T J",
|
||||
"AND D J",
|
||||
"WALK"
|
||||
]
|
||||
intcode.inp += map(ord, "".join(i + "\n" for i in INSTRUCTIONS))
|
||||
intcode.cont()
|
||||
print(intcode.out[-1])
|
|
@ -1,10 +1,29 @@
|
|||
import re
|
||||
from lib import *
|
||||
|
||||
input = read_input(2019, 22)
|
||||
|
||||
|
||||
DECK = 10007
|
||||
pos = 2019
|
||||
for line in input.splitlines():
|
||||
reverse = re.match(r"deal into new stack", line)
|
||||
cut = re.match(r"cut (-?\d+)", line)
|
||||
increment = re.match(r"deal with increment (\d+)", line)
|
||||
if reverse:
|
||||
pos = -pos - 1
|
||||
elif cut:
|
||||
pos -= int(cut.group(1))
|
||||
elif increment:
|
||||
pos *= int(increment.group(1))
|
||||
pos %= DECK
|
||||
|
||||
print(pos)
|
||||
|
||||
DECK = 119315717514047
|
||||
REP = 101741582076661
|
||||
first, inc = 0, 1
|
||||
|
||||
instructions = open("input.txt").read().splitlines()
|
||||
instructions = input.splitlines()
|
||||
for line in instructions:
|
||||
reverse = re.match(r"deal into new stack", line)
|
||||
cut = re.match(r"cut (-?\d+)", line)
|
|
@ -1,17 +0,0 @@
|
|||
import re
|
||||
|
||||
DECK = 10007
|
||||
pos = 2019
|
||||
for line in open("input.txt").read().splitlines():
|
||||
reverse = re.match(r"deal into new stack", line)
|
||||
cut = re.match(r"cut (-?\d+)", line)
|
||||
increment = re.match(r"deal with increment (\d+)", line)
|
||||
if reverse:
|
||||
pos = -pos - 1
|
||||
elif cut:
|
||||
pos -= int(cut.group(1))
|
||||
elif increment:
|
||||
pos *= int(increment.group(1))
|
||||
pos %= DECK
|
||||
|
||||
print(pos)
|
|
@ -1,3 +1,8 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2019, 23)
|
||||
|
||||
|
||||
class IntCode:
|
||||
def __init__(self, mem):
|
||||
self.mem = {i: e for i, e in enumerate(mem)}
|
||||
|
@ -10,18 +15,18 @@ class IntCode:
|
|||
def start(self):
|
||||
self.running = True
|
||||
self.cont()
|
||||
|
||||
|
||||
def get_arg(self, i):
|
||||
mode = self.mem[self.pc] // (10 ** (i+1)) % 10
|
||||
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
|
||||
mode = self.mem[self.pc] // (10 ** (i + 1)) % 10
|
||||
pos = self.mem[self.pc + i]
|
||||
assert mode != 1
|
||||
if mode == 2:
|
||||
|
@ -31,7 +36,7 @@ class IntCode:
|
|||
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
|
||||
|
@ -69,7 +74,25 @@ class IntCode:
|
|||
self.running = False
|
||||
return
|
||||
|
||||
*mem, = map(int, open("input.txt").read().split(","))
|
||||
|
||||
(*mem,) = map(int, input.split(","))
|
||||
nodes = [IntCode(mem) for _ in range(50)]
|
||||
for i, node in enumerate(nodes):
|
||||
node.inp.append(i)
|
||||
node.start()
|
||||
while True:
|
||||
for i, node in enumerate(nodes):
|
||||
while node.out:
|
||||
dest, x, y, *node.out = node.out
|
||||
if dest == 255:
|
||||
print(y)
|
||||
exit()
|
||||
nodes[dest].inp += [x, y]
|
||||
node.inp.append(-1)
|
||||
node.cont()
|
||||
|
||||
|
||||
(*mem,) = map(int, input.split(","))
|
||||
nodes = [IntCode(mem) for _ in range(50)]
|
||||
nat = None
|
||||
nat_history = set()
|
|
@ -1,86 +0,0 @@
|
|||
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, open("input.txt").read().split(","))
|
||||
nodes = [IntCode(mem) for _ in range(50)]
|
||||
for i, node in enumerate(nodes):
|
||||
node.inp.append(i)
|
||||
node.start()
|
||||
while True:
|
||||
for i, node in enumerate(nodes):
|
||||
while node.out:
|
||||
dest, x, y, *node.out = node.out
|
||||
if dest == 255:
|
||||
print(y)
|
||||
exit()
|
||||
nodes[dest].inp += [x, y]
|
||||
node.inp.append(-1)
|
||||
node.cont()
|
92
Python/2019/24.py
Normal file
92
Python/2019/24.py
Normal file
|
@ -0,0 +1,92 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2019, 24)
|
||||
|
||||
grid = sum((1 << i * 5 + j) * (c == "#") for i, line in enumerate(input.splitlines()) for j, c in enumerate(line))
|
||||
|
||||
|
||||
def get_adjacent(i, j):
|
||||
return sum(
|
||||
grid & (1 << i * 5 + j) > 0
|
||||
for i, j in [(i, j - 1), (i, j + 1), (i - 1, j), (i + 1, j)]
|
||||
if i in range(5) and j in range(5)
|
||||
)
|
||||
|
||||
|
||||
def simulate():
|
||||
out = 0
|
||||
for i in range(5):
|
||||
for j in range(5):
|
||||
if (grid & (1 << i * 5 + j) > 0 and get_adjacent(i, j) == 1) or (
|
||||
grid & (1 << i * 5 + j) == 0 and get_adjacent(i, j) in (1, 2)
|
||||
):
|
||||
out |= 1 << i * 5 + j
|
||||
return out
|
||||
|
||||
|
||||
history = set()
|
||||
while True:
|
||||
if grid in history:
|
||||
break
|
||||
history.add(grid)
|
||||
grid = simulate()
|
||||
print(grid)
|
||||
|
||||
|
||||
grid = {0: sum((1 << i * 5 + j) * (c == "#") for i, line in enumerate(input.splitlines()) for j, c in enumerate(line))}
|
||||
|
||||
|
||||
def is_alive(i, j, l):
|
||||
return grid.get(l, 0) & (1 << i * 5 + j) > 0
|
||||
|
||||
|
||||
def get_adjacent(i, j, l):
|
||||
if (i, j) == (2, 2):
|
||||
return 0
|
||||
out = 0
|
||||
for x, y in [(j - 1, i), (j + 1, i), (j, i - 1), (j, i + 1)]:
|
||||
outer = grid.get(l - 1, 0)
|
||||
layer = grid.get(l, 0)
|
||||
inner = grid.get(l + 1, 0)
|
||||
if (x, y) == (2, 2):
|
||||
for k in range(5):
|
||||
if i == 1:
|
||||
out += is_alive(0, k, l + 1)
|
||||
elif j == 1:
|
||||
out += is_alive(k, 0, l + 1)
|
||||
elif i == 3:
|
||||
out += is_alive(4, k, l + 1)
|
||||
elif j == 3:
|
||||
out += is_alive(k, 4, l + 1)
|
||||
else:
|
||||
if x == -1:
|
||||
out += is_alive(2, 1, l - 1)
|
||||
elif y == -1:
|
||||
out += is_alive(1, 2, l - 1)
|
||||
elif x == 5:
|
||||
out += is_alive(2, 3, l - 1)
|
||||
elif y == 5:
|
||||
out += is_alive(3, 2, l - 1)
|
||||
else:
|
||||
out += is_alive(y, x, l)
|
||||
return out
|
||||
|
||||
|
||||
def simulate():
|
||||
out = {}
|
||||
for l in range(min(grid) - 1, max(grid) + 2):
|
||||
lout = 0
|
||||
for i in range(5):
|
||||
for j in range(5):
|
||||
if (is_alive(i, j, l) and get_adjacent(i, j, l) == 1) or (
|
||||
not is_alive(i, j, l) and get_adjacent(i, j, l) in (1, 2)
|
||||
):
|
||||
lout |= 1 << i * 5 + j
|
||||
if lout:
|
||||
out[l] = lout
|
||||
return out
|
||||
|
||||
|
||||
for _ in range(200):
|
||||
grid = simulate()
|
||||
print(sum(bin(layer).count("1") for layer in grid.values()))
|
|
@ -1,20 +0,0 @@
|
|||
grid = sum((1<<i*5+j)*(c=="#") for i, line in enumerate(open("input.txt").read().splitlines()) for j, c in enumerate(line))
|
||||
|
||||
def get_adjacent(i, j):
|
||||
return sum(grid&(1<<i*5+j)>0 for i, j in [(i,j-1), (i,j+1), (i-1,j), (i+1,j)] if i in range(5) and j in range(5))
|
||||
|
||||
def simulate():
|
||||
out = 0
|
||||
for i in range(5):
|
||||
for j in range(5):
|
||||
if (grid&(1<<i*5+j)>0 and get_adjacent(i, j) == 1) or (grid&(1<<i*5+j)==0 and get_adjacent(i, j) in (1, 2)):
|
||||
out |= 1<<i*5+j
|
||||
return out
|
||||
|
||||
history = set()
|
||||
while True:
|
||||
if grid in history:
|
||||
break
|
||||
history.add(grid)
|
||||
grid = simulate()
|
||||
print(grid)
|
|
@ -1,42 +0,0 @@
|
|||
grid = {0: sum((1<<i*5+j)*(c=="#") for i, line in enumerate(open("input.txt").read().splitlines()) for j, c in enumerate(line))}
|
||||
|
||||
def is_alive(i, j, l):
|
||||
return grid.get(l, 0)&(1<<i*5+j) > 0
|
||||
|
||||
def get_adjacent(i, j, l):
|
||||
if (i, j) == (2, 2):
|
||||
return 0
|
||||
out = 0
|
||||
for x, y in [(j-1,i), (j+1,i), (j,i-1), (j,i+1)]:
|
||||
outer = grid.get(l - 1, 0)
|
||||
layer = grid.get(l, 0)
|
||||
inner = grid.get(l + 1, 0)
|
||||
if (x, y) == (2, 2):
|
||||
for k in range(5):
|
||||
if i == 1: out += is_alive(0, k, l + 1)
|
||||
elif j == 1: out += is_alive(k, 0, l + 1)
|
||||
elif i == 3: out += is_alive(4, k, l + 1)
|
||||
elif j == 3: out += is_alive(k, 4, l + 1)
|
||||
else:
|
||||
if x == -1: out += is_alive(2, 1, l - 1)
|
||||
elif y == -1: out += is_alive(1, 2, l - 1)
|
||||
elif x == 5: out += is_alive(2, 3, l - 1)
|
||||
elif y == 5: out += is_alive(3, 2, l - 1)
|
||||
else: out += is_alive(y, x, l)
|
||||
return out
|
||||
|
||||
def simulate():
|
||||
out = {}
|
||||
for l in range(min(grid) - 1, max(grid) + 2):
|
||||
lout = 0
|
||||
for i in range(5):
|
||||
for j in range(5):
|
||||
if (is_alive(i, j, l) and get_adjacent(i, j, l) == 1) or (not is_alive(i, j, l) and get_adjacent(i, j, l) in (1, 2)):
|
||||
lout |= 1<<i*5+j
|
||||
if lout:
|
||||
out[l] = lout
|
||||
return out
|
||||
|
||||
for _ in range(200):
|
||||
grid = simulate()
|
||||
print(sum(bin(layer).count("1") for layer in grid.values()))
|
|
@ -1,4 +1,7 @@
|
|||
import re
|
||||
from lib import *
|
||||
|
||||
input = read_input(2019, 25)
|
||||
|
||||
|
||||
class IntCode:
|
||||
def __init__(self, mem):
|
||||
|
@ -12,18 +15,18 @@ class IntCode:
|
|||
def start(self):
|
||||
self.running = True
|
||||
self.cont()
|
||||
|
||||
|
||||
def get_arg(self, i):
|
||||
mode = self.mem[self.pc] // (10 ** (i+1)) % 10
|
||||
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
|
||||
mode = self.mem[self.pc] // (10 ** (i + 1)) % 10
|
||||
pos = self.mem[self.pc + i]
|
||||
assert mode != 1
|
||||
if mode == 2:
|
||||
|
@ -33,7 +36,7 @@ class IntCode:
|
|||
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
|
||||
|
@ -80,6 +83,7 @@ class IntCode:
|
|||
self.inp += map(ord, inp + "\n")
|
||||
self.cont()
|
||||
|
||||
|
||||
class Bot(IntCode):
|
||||
def __init__(self, mem):
|
||||
super().__init__(mem)
|
||||
|
@ -100,13 +104,13 @@ class Bot(IntCode):
|
|||
if match:
|
||||
self.room = match.group(1)
|
||||
break
|
||||
out = out[out.index("Doors here lead:")+1:]
|
||||
self.directions = [d[2:] for d in out[:out.index("")]]
|
||||
out = out[out.index("Doors here lead:") + 1 :]
|
||||
self.directions = [d[2:] for d in out[: out.index("")]]
|
||||
if "Items here:" not in out:
|
||||
self.items.clear()
|
||||
return
|
||||
out = out[out.index("Items here:")+1:]
|
||||
self.items = [i[2:] for i in out[:out.index("")]]
|
||||
out = out[out.index("Items here:") + 1 :]
|
||||
self.items = [i[2:] for i in out[: out.index("")]]
|
||||
|
||||
def move(self, direction):
|
||||
self.input(direction)
|
||||
|
@ -125,29 +129,32 @@ class Bot(IntCode):
|
|||
out = self.output().split("\n")
|
||||
if "Items in your inventory:" not in out:
|
||||
return []
|
||||
out = out[out.index("Items in your inventory:")+1:]
|
||||
return [i[2:] for i in out[:out.index("")]]
|
||||
|
||||
out = out[out.index("Items in your inventory:") + 1 :]
|
||||
return [i[2:] for i in out[: out.index("")]]
|
||||
|
||||
def test(self, direction):
|
||||
assert self.room == "Security Checkpoint"
|
||||
self.input(direction)
|
||||
|
||||
orig = out = self.output().split("\n")
|
||||
out = out[out.index("Doors here lead:")+1:]
|
||||
out = out[out.index("")+1:]
|
||||
out = out[out.index("Doors here lead:") + 1 :]
|
||||
out = out[out.index("") + 1 :]
|
||||
res = "ejected back" not in out[0]
|
||||
if res:
|
||||
print(re.match(r"^.*?(\d+).*$", out[2]).group(1))
|
||||
return res
|
||||
|
||||
|
||||
BACK = {"north": "south", "south": "north", "east": "west", "west": "east"}
|
||||
|
||||
*mem, = map(int, open("input.txt").read().split(","))
|
||||
(*mem,) = map(int, input.split(","))
|
||||
bot = Bot(mem)
|
||||
bot.start()
|
||||
|
||||
items = []
|
||||
maze = {}
|
||||
|
||||
|
||||
def explore(r=None, came_from=None, indent=0):
|
||||
room = bot.room
|
||||
if r:
|
||||
|
@ -169,8 +176,10 @@ def explore(r=None, came_from=None, indent=0):
|
|||
explore(room, BACK[direction], indent + 1)
|
||||
bot.move(BACK[direction])
|
||||
|
||||
|
||||
explore()
|
||||
|
||||
|
||||
def make_path(room, dest, f=None):
|
||||
if room == dest:
|
||||
return []
|
||||
|
@ -182,9 +191,11 @@ def make_path(room, dest, f=None):
|
|||
if res is not None:
|
||||
return [d] + res
|
||||
|
||||
|
||||
for d in make_path(bot.room, "Security Checkpoint"):
|
||||
bot.move(d)
|
||||
dire, = maze[bot.room]
|
||||
(dire,) = maze[bot.room]
|
||||
|
||||
|
||||
def test_combination(i):
|
||||
for e in bot.inv():
|
||||
|
@ -194,6 +205,7 @@ def test_combination(i):
|
|||
bot.take(e)
|
||||
return bot.test(dire)
|
||||
|
||||
for i in range(1<<len(items)):
|
||||
|
||||
for i in range(1 << len(items)):
|
||||
if test_combination(i):
|
||||
break
|
|
@ -20,6 +20,7 @@ import math
|
|||
import operator
|
||||
import re
|
||||
import statistics
|
||||
import string
|
||||
from collections import Counter, deque
|
||||
from copy import deepcopy
|
||||
from dataclasses import dataclass
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue