[Python/2018] Move solutions into .py files
This commit is contained in:
parent
edb04277c6
commit
40e767096e
60 changed files with 1518 additions and 3541 deletions
23
Python/2018/01.py
Normal file
23
Python/2018/01.py
Normal file
|
@ -0,0 +1,23 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 1)
|
||||
|
||||
out = 0
|
||||
for line in input.splitlines():
|
||||
out += int(line)
|
||||
print(out)
|
||||
|
||||
lines = input.splitlines()
|
||||
freq = 0
|
||||
seen = {0}
|
||||
while True:
|
||||
for line in lines:
|
||||
freq += int(line)
|
||||
if freq in seen:
|
||||
print(freq)
|
||||
break
|
||||
else:
|
||||
seen.add(freq)
|
||||
else:
|
||||
continue
|
||||
break
|
|
@ -1,4 +0,0 @@
|
|||
out = 0
|
||||
for line in open("input.txt").read().splitlines():
|
||||
out += int(line)
|
||||
print(out)
|
|
@ -1,11 +0,0 @@
|
|||
lines = open("input.txt").read().splitlines()
|
||||
freq = 0
|
||||
seen = {0}
|
||||
while True:
|
||||
for line in lines:
|
||||
freq += int(line)
|
||||
if freq in seen:
|
||||
print(freq)
|
||||
exit()
|
||||
else:
|
||||
seen.add(freq)
|
30
Python/2018/02.py
Normal file
30
Python/2018/02.py
Normal file
|
@ -0,0 +1,30 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 2)
|
||||
|
||||
|
||||
def count(box, n):
|
||||
return any(box.count(c) == n for c in set(box))
|
||||
|
||||
|
||||
counter = {2: 0, 3: 0}
|
||||
for line in input.splitlines():
|
||||
counter[2] += count(line, 2)
|
||||
counter[3] += count(line, 3)
|
||||
|
||||
print(counter[2] * counter[3])
|
||||
|
||||
|
||||
def compare(a, b):
|
||||
return len(a) == len(b) and sum(x != y for x, y in zip(a, b)) == 1
|
||||
|
||||
|
||||
lines = input.splitlines()
|
||||
for a in lines:
|
||||
for b in lines:
|
||||
if compare(a, b):
|
||||
print("".join(x for x, y in zip(a, b) if x == y))
|
||||
break
|
||||
else:
|
||||
continue
|
||||
break
|
|
@ -1,9 +0,0 @@
|
|||
def count(box, n):
|
||||
return any(box.count(c) == n for c in set(box))
|
||||
|
||||
counter = {2: 0, 3: 0}
|
||||
for line in open("input.txt").read().splitlines():
|
||||
counter[2] += count(line, 2)
|
||||
counter[3] += count(line, 3)
|
||||
|
||||
print(counter[2] * counter[3])
|
|
@ -1,9 +0,0 @@
|
|||
def compare(a, b):
|
||||
return len(a) == len(b) and sum(x != y for x, y in zip(a, b)) == 1
|
||||
|
||||
lines = open("input.txt").read().splitlines()
|
||||
for a in lines:
|
||||
for b in lines:
|
||||
if compare(a, b):
|
||||
print("".join(x for x, y in zip(a, b) if x == y))
|
||||
exit()
|
|
@ -1,6 +1,19 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 3)
|
||||
|
||||
import re
|
||||
|
||||
claims = open("input.txt").read().splitlines()
|
||||
G = [[0 for _ in range(1000)] for _ in range(1000)]
|
||||
for line in input.splitlines():
|
||||
offx, offy, wid, hei = map(int, re.match("^#\d+ @ (\d+),(\d+): (\d+)x(\d+)$", line).groups())
|
||||
for x in range(wid):
|
||||
for y in range(hei):
|
||||
G[offx + x][offy + y] += 1
|
||||
print(sum(x >= 2 for row in G for x in row))
|
||||
|
||||
|
||||
claims = input.splitlines()
|
||||
|
||||
G = [[0 for _ in range(1000)] for _ in range(1000)]
|
||||
for line in claims:
|
||||
|
@ -12,3 +25,4 @@ for line in claims:
|
|||
id, offx, offy, wid, hei = map(int, re.match("^#(\d+) @ (\d+),(\d+): (\d+)x(\d+)$", line).groups())
|
||||
if all(G[offx + x][offy + y] == 1 for x in range(wid) for y in range(hei)):
|
||||
print(id)
|
||||
break
|
|
@ -1,9 +0,0 @@
|
|||
import re
|
||||
|
||||
G = [[0 for _ in range(1000)] for _ in range(1000)]
|
||||
for line in open("input.txt").read().splitlines():
|
||||
offx, offy, wid, hei = map(int, re.match("^#\d+ @ (\d+),(\d+): (\d+)x(\d+)$", line).groups())
|
||||
for x in range(wid):
|
||||
for y in range(hei):
|
||||
G[offx + x][offy + y] += 1
|
||||
print(sum(x>=2 for row in G for x in row))
|
81
Python/2018/04.py
Normal file
81
Python/2018/04.py
Normal file
|
@ -0,0 +1,81 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 4)
|
||||
|
||||
|
||||
days = {}
|
||||
for line in input.splitlines():
|
||||
day, hour, minute, action = re.match("^\[(\d\d\d\d-\d\d-\d\d) (\d\d):(\d\d)\] (.*)$", line).groups()
|
||||
day = date.fromisoformat(day)
|
||||
hour, minute = int(hour), int(minute)
|
||||
match = re.match(r"^Guard #(\d+) begins shift$", action)
|
||||
if match:
|
||||
guard = int(match.group(1))
|
||||
if hour == 23:
|
||||
day += timedelta(days=1)
|
||||
days.setdefault(day, [None, [None for _ in range(60)]])[0] = guard
|
||||
elif action == "wakes up":
|
||||
assert hour == 0
|
||||
assert 0 <= minute < 60
|
||||
days.setdefault(day, [None, [None for _ in range(60)]])[1][minute] = True
|
||||
elif action == "falls asleep":
|
||||
assert hour == 0
|
||||
assert 0 <= minute < 60
|
||||
days.setdefault(day, [None, [None for _ in range(60)]])[1][minute] = False
|
||||
else:
|
||||
assert False
|
||||
guards = {}
|
||||
for day, (guard, logs) in days.items():
|
||||
awake = True
|
||||
for i in range(60):
|
||||
if logs[i] is None:
|
||||
logs[i] = awake
|
||||
else:
|
||||
awake = logs[i]
|
||||
if not awake:
|
||||
guards.setdefault(guard, [0, {}])[0] += 1
|
||||
guards[guard][1][i] = guards[guard][1].get(i, 0) + 1
|
||||
guard = max(guards, key=lambda g: guards[g][0])
|
||||
print(guard * max(guards[guard][1], key=lambda d: guards[guard][1][d]))
|
||||
|
||||
|
||||
days = {}
|
||||
for line in input.splitlines():
|
||||
day, hour, minute, action = re.match("^\[(\d\d\d\d-\d\d-\d\d) (\d\d):(\d\d)\] (.*)$", line).groups()
|
||||
day = date.fromisoformat(day)
|
||||
hour, minute = int(hour), int(minute)
|
||||
match = re.match("^Guard #(\d+) begins shift$", action)
|
||||
if match:
|
||||
guard = int(match.group(1))
|
||||
if hour == 23:
|
||||
day += timedelta(days=1)
|
||||
days.setdefault(day, [None, [None for _ in range(60)]])[0] = guard
|
||||
elif action == "wakes up":
|
||||
assert hour == 0
|
||||
assert 0 <= minute < 60
|
||||
days.setdefault(day, [None, [None for _ in range(60)]])[1][minute] = True
|
||||
elif action == "falls asleep":
|
||||
assert hour == 0
|
||||
assert 0 <= minute < 60
|
||||
days.setdefault(day, [None, [None for _ in range(60)]])[1][minute] = False
|
||||
else:
|
||||
assert False
|
||||
guards = {}
|
||||
for day, (guard, logs) in days.items():
|
||||
awake = True
|
||||
for i in range(60):
|
||||
if logs[i] is None:
|
||||
logs[i] = awake
|
||||
else:
|
||||
awake = logs[i]
|
||||
if not awake:
|
||||
guards.setdefault(guard, [0, {}])[0] += 1
|
||||
guards[guard][1][i] = guards[guard][1].get(i, 0) + 1
|
||||
best_cnt = -1
|
||||
out = None
|
||||
for g in guards:
|
||||
cnt, best_minute = max((guards[g][1].get(i, 0), i) for i in range(60))
|
||||
if cnt > best_cnt:
|
||||
best_cnt = cnt
|
||||
out = best_minute * g
|
||||
print(out)
|
|
@ -1,37 +0,0 @@
|
|||
from datetime import date, timedelta
|
||||
import re
|
||||
|
||||
days = {}
|
||||
for line in open("input.txt").read().splitlines():
|
||||
day, hour, minute, action = re.match("^\[(\d\d\d\d-\d\d-\d\d) (\d\d):(\d\d)\] (.*)$", line).groups()
|
||||
day = date.fromisoformat(day)
|
||||
hour, minute = int(hour), int(minute)
|
||||
match = re.match("^Guard #(\d+) begins shift$", action)
|
||||
if match:
|
||||
guard = int(match.group(1))
|
||||
if hour == 23:
|
||||
day += timedelta(days=1)
|
||||
days.setdefault(day, [None, [None for _ in range(60)]])[0] = guard
|
||||
elif action == "wakes up":
|
||||
assert hour == 0
|
||||
assert 0 <= minute < 60
|
||||
days.setdefault(day, [None, [None for _ in range(60)]])[1][minute] = True
|
||||
elif action == "falls asleep":
|
||||
assert hour == 0
|
||||
assert 0 <= minute < 60
|
||||
days.setdefault(day, [None, [None for _ in range(60)]])[1][minute] = False
|
||||
else:
|
||||
assert False
|
||||
guards = {}
|
||||
for day, (guard, logs) in days.items():
|
||||
awake = True
|
||||
for i in range(60):
|
||||
if logs[i] is None:
|
||||
logs[i] = awake
|
||||
else:
|
||||
awake = logs[i]
|
||||
if not awake:
|
||||
guards.setdefault(guard, [0, {}])[0] += 1
|
||||
guards[guard][1][i] = guards[guard][1].get(i, 0) + 1
|
||||
guard = max(guards, key=lambda g: guards[g][0])
|
||||
print(guard * max(guards[guard][1], key=lambda d: guards[guard][1][d]))
|
|
@ -1,43 +0,0 @@
|
|||
from datetime import date, timedelta
|
||||
import re
|
||||
|
||||
days = {}
|
||||
for line in open("input.txt").read().splitlines():
|
||||
day, hour, minute, action = re.match("^\[(\d\d\d\d-\d\d-\d\d) (\d\d):(\d\d)\] (.*)$", line).groups()
|
||||
day = date.fromisoformat(day)
|
||||
hour, minute = int(hour), int(minute)
|
||||
match = re.match("^Guard #(\d+) begins shift$", action)
|
||||
if match:
|
||||
guard = int(match.group(1))
|
||||
if hour == 23:
|
||||
day += timedelta(days=1)
|
||||
days.setdefault(day, [None, [None for _ in range(60)]])[0] = guard
|
||||
elif action == "wakes up":
|
||||
assert hour == 0
|
||||
assert 0 <= minute < 60
|
||||
days.setdefault(day, [None, [None for _ in range(60)]])[1][minute] = True
|
||||
elif action == "falls asleep":
|
||||
assert hour == 0
|
||||
assert 0 <= minute < 60
|
||||
days.setdefault(day, [None, [None for _ in range(60)]])[1][minute] = False
|
||||
else:
|
||||
assert False
|
||||
guards = {}
|
||||
for day, (guard, logs) in days.items():
|
||||
awake = True
|
||||
for i in range(60):
|
||||
if logs[i] is None:
|
||||
logs[i] = awake
|
||||
else:
|
||||
awake = logs[i]
|
||||
if not awake:
|
||||
guards.setdefault(guard, [0, {}])[0] += 1
|
||||
guards[guard][1][i] = guards[guard][1].get(i, 0) + 1
|
||||
best_cnt = -1
|
||||
out = None
|
||||
for g in guards:
|
||||
cnt, best_minute = max((guards[g][1].get(i, 0), i) for i in range(60))
|
||||
if cnt > best_cnt:
|
||||
best_cnt = cnt
|
||||
out = best_minute * g
|
||||
print(out)
|
|
@ -1,3 +1,16 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 5)
|
||||
|
||||
stack = []
|
||||
for c in input.strip():
|
||||
if stack and stack[-1].lower() == c.lower() and stack[-1].islower() != c.islower():
|
||||
stack.pop()
|
||||
else:
|
||||
stack.append(c)
|
||||
print(len(stack))
|
||||
|
||||
|
||||
def react(poly, wo):
|
||||
stack = []
|
||||
for c in poly:
|
||||
|
@ -9,5 +22,6 @@ def react(poly, wo):
|
|||
stack.append(c)
|
||||
return len(stack)
|
||||
|
||||
inp = open("input.txt").read().strip()
|
||||
|
||||
inp = input.strip()
|
||||
print(min(react(inp, c) for c in set(inp.lower())))
|
|
@ -1,7 +0,0 @@
|
|||
stack = []
|
||||
for c in open("input.txt").read().strip():
|
||||
if stack and stack[-1].lower() == c.lower() and stack[-1].islower() != c.islower():
|
||||
stack.pop()
|
||||
else:
|
||||
stack.append(c)
|
||||
print(len(stack))
|
|
@ -1,19 +1,25 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 6)
|
||||
|
||||
width = 0
|
||||
height = 0
|
||||
coords = []
|
||||
for line in open("input.txt").read().splitlines():
|
||||
for line in input.splitlines():
|
||||
x, y = map(int, line.split(", "))
|
||||
coords.append((x, y))
|
||||
width = max(width, x + 1)
|
||||
height = max(height, y + 1)
|
||||
|
||||
|
||||
def find_nearest(x, y):
|
||||
distances = [abs(x-p) + abs(y-q) for p, q in coords]
|
||||
distances = [abs(x - p) + abs(y - q) for p, q in coords]
|
||||
best_distance = min(distances)
|
||||
if distances.count(best_distance) > 1:
|
||||
return None
|
||||
return distances.index(best_distance)
|
||||
|
||||
|
||||
counter = {}
|
||||
edge = set()
|
||||
for y in range(height):
|
||||
|
@ -24,3 +30,18 @@ for y in range(height):
|
|||
if x in (0, width - 1) or y in (0, height - 1):
|
||||
edge.add(nearest)
|
||||
print(max(counter[c] for c in counter if c not in edge))
|
||||
width = 0
|
||||
height = 0
|
||||
coords = []
|
||||
for line in input.splitlines():
|
||||
x, y = map(int, line.split(", "))
|
||||
coords.append((x, y))
|
||||
width = max(width, x + 1)
|
||||
height = max(height, y + 1)
|
||||
|
||||
|
||||
def measure(x, y):
|
||||
return sum(abs(x - p) + abs(y - q) for p, q in coords)
|
||||
|
||||
|
||||
print(sum(measure(x, y) < 10000 for x in range(width) for y in range(height)))
|
|
@ -1,13 +0,0 @@
|
|||
width = 0
|
||||
height = 0
|
||||
coords = []
|
||||
for line in open("input.txt").read().splitlines():
|
||||
x, y = map(int, line.split(", "))
|
||||
coords.append((x, y))
|
||||
width = max(width, x + 1)
|
||||
height = max(height, y + 1)
|
||||
|
||||
def measure(x, y):
|
||||
return sum(abs(x-p) + abs(y-q) for p, q in coords)
|
||||
|
||||
print(sum(measure(x, y) < 10000 for x in range(width) for y in range(height)))
|
|
@ -1,9 +1,35 @@
|
|||
import re
|
||||
from lib import *
|
||||
|
||||
input = read_input(2018, 7)
|
||||
|
||||
|
||||
unlocks = {}
|
||||
requirements = {}
|
||||
chars = set()
|
||||
for line in open("input.txt").read().splitlines():
|
||||
for line in input.splitlines():
|
||||
a, b = re.match("^Step (.) must be finished before step (.) can begin\.$", line).groups()
|
||||
chars |= {a, b}
|
||||
unlocks.setdefault(a, set()).add(b)
|
||||
requirements.setdefault(b, set()).add(a)
|
||||
|
||||
out = ""
|
||||
Q = [e for e in chars if e not in requirements]
|
||||
heapq.heapify(Q)
|
||||
while Q:
|
||||
p = heapq.heappop(Q)
|
||||
out += p
|
||||
|
||||
for q in unlocks.get(p, []):
|
||||
requirements[q].remove(p)
|
||||
if not requirements[q]:
|
||||
heapq.heappush(Q, q)
|
||||
print(out)
|
||||
|
||||
|
||||
unlocks = {}
|
||||
requirements = {}
|
||||
chars = set()
|
||||
for line in input.splitlines():
|
||||
a, b = re.match("^Step (.) must be finished before step (.) can begin\.$", line).groups()
|
||||
chars |= {a, b}
|
||||
unlocks.setdefault(a, set()).add(b)
|
||||
|
@ -11,19 +37,21 @@ for line in open("input.txt").read().splitlines():
|
|||
|
||||
Q = [e for e in chars if e not in requirements]
|
||||
seconds = 0
|
||||
|
||||
|
||||
|
||||
def get_task():
|
||||
if Q:
|
||||
task = Q.pop()
|
||||
return (task, ord(task) - 4)
|
||||
|
||||
|
||||
def finish_task(p):
|
||||
for q in unlocks.get(p, []):
|
||||
requirements[q].remove(p)
|
||||
if not requirements[q]:
|
||||
Q.append(q)
|
||||
|
||||
|
||||
def fast_forward():
|
||||
t = min((w[1] for w in workers if w is not None), default=0)
|
||||
for i in range(5):
|
||||
|
@ -35,6 +63,7 @@ def fast_forward():
|
|||
workers[i] = None
|
||||
return t
|
||||
|
||||
|
||||
workers = [None for _ in range(5)]
|
||||
while Q or any(workers):
|
||||
seconds += fast_forward()
|
|
@ -1,24 +0,0 @@
|
|||
import heapq
|
||||
import re
|
||||
|
||||
unlocks = {}
|
||||
requirements = {}
|
||||
chars = set()
|
||||
for line in open("input.txt").read().splitlines():
|
||||
a, b = re.match("^Step (.) must be finished before step (.) can begin\.$", line).groups()
|
||||
chars |= {a, b}
|
||||
unlocks.setdefault(a, set()).add(b)
|
||||
requirements.setdefault(b, set()).add(a)
|
||||
|
||||
out = ""
|
||||
Q = [e for e in chars if e not in requirements]
|
||||
heapq.heapify(Q)
|
||||
while Q:
|
||||
p = heapq.heappop(Q)
|
||||
out += p
|
||||
|
||||
for q in unlocks.get(p, []):
|
||||
requirements[q].remove(p)
|
||||
if not requirements[q]:
|
||||
heapq.heappush(Q, q)
|
||||
print(out)
|
41
Python/2018/08.py
Normal file
41
Python/2018/08.py
Normal file
|
@ -0,0 +1,41 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 8)
|
||||
|
||||
(*nums,) = map(int, input.split())
|
||||
|
||||
|
||||
def get_metadata_sum():
|
||||
child_count = nums.pop(0)
|
||||
meta_count = nums.pop(0)
|
||||
out = 0
|
||||
for _ in range(child_count):
|
||||
out += get_metadata_sum()
|
||||
for _ in range(meta_count):
|
||||
out += nums.pop(0)
|
||||
return out
|
||||
|
||||
|
||||
print(get_metadata_sum())
|
||||
|
||||
|
||||
(*nums,) = map(int, input.split())
|
||||
|
||||
|
||||
def get_value():
|
||||
child_count = nums.pop(0)
|
||||
meta_count = nums.pop(0)
|
||||
out = 0
|
||||
|
||||
childs = [get_value() for _ in range(child_count)]
|
||||
|
||||
for _ in range(meta_count):
|
||||
num = nums.pop(0)
|
||||
if not child_count:
|
||||
out += num
|
||||
elif 1 <= num <= child_count:
|
||||
out += childs[num - 1]
|
||||
return out
|
||||
|
||||
|
||||
print(get_value())
|
|
@ -1,13 +0,0 @@
|
|||
*nums, = map(int, open("input.txt").read().split())
|
||||
|
||||
def get_metadata_sum():
|
||||
child_count = nums.pop(0)
|
||||
meta_count = nums.pop(0)
|
||||
out = 0
|
||||
for _ in range(child_count):
|
||||
out += get_metadata_sum()
|
||||
for _ in range(meta_count):
|
||||
out += nums.pop(0)
|
||||
return out
|
||||
|
||||
print(get_metadata_sum())
|
|
@ -1,18 +0,0 @@
|
|||
*nums, = map(int, open("input.txt").read().split())
|
||||
|
||||
def get_value():
|
||||
child_count = nums.pop(0)
|
||||
meta_count = nums.pop(0)
|
||||
out = 0
|
||||
|
||||
childs = [get_value() for _ in range(child_count)]
|
||||
|
||||
for _ in range(meta_count):
|
||||
num = nums.pop(0)
|
||||
if not child_count:
|
||||
out += num
|
||||
elif 1 <= num <= child_count:
|
||||
out += childs[num - 1]
|
||||
return out
|
||||
|
||||
print(get_value())
|
34
Python/2018/09.py
Normal file
34
Python/2018/09.py
Normal file
|
@ -0,0 +1,34 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 9)
|
||||
|
||||
|
||||
players, n = map(int, re.match(r"^(\d+) players; last marble is worth (\d+) points$", input).groups())
|
||||
lst = deque([0])
|
||||
scores = [0 for _ in range(players)]
|
||||
for i in range(1, n + 1):
|
||||
p = i % players
|
||||
if i % 23:
|
||||
lst.rotate(-1)
|
||||
lst.append(i)
|
||||
else:
|
||||
lst.rotate(7)
|
||||
scores[p] += i + lst.pop()
|
||||
lst.rotate(-1)
|
||||
print(max(scores))
|
||||
|
||||
|
||||
players, n = map(int, re.match(r"^(\d+) players; last marble is worth (\d+) points$", input).groups())
|
||||
n *= 100
|
||||
lst = deque([0])
|
||||
scores = [0 for _ in range(players)]
|
||||
for i in range(1, n + 1):
|
||||
p = i % players
|
||||
if i % 23:
|
||||
lst.rotate(-1)
|
||||
lst.append(i)
|
||||
else:
|
||||
lst.rotate(7)
|
||||
scores[p] += i + lst.pop()
|
||||
lst.rotate(-1)
|
||||
print(max(scores))
|
|
@ -1,16 +0,0 @@
|
|||
from collections import deque
|
||||
import re
|
||||
|
||||
players, n = map(int, re.match(r"^(\d+) players; last marble is worth (\d+) points$", open("input.txt").read()).groups())
|
||||
lst = deque([0])
|
||||
scores = [0 for _ in range(players)]
|
||||
for i in range(1, n + 1):
|
||||
p = i % players
|
||||
if i % 23:
|
||||
lst.rotate(-1)
|
||||
lst.append(i)
|
||||
else:
|
||||
lst.rotate(7)
|
||||
scores[p] += i + lst.pop()
|
||||
lst.rotate(-1)
|
||||
print(max(scores))
|
|
@ -1,17 +0,0 @@
|
|||
from collections import deque
|
||||
import re
|
||||
|
||||
players, n = map(int, re.match(r"^(\d+) players; last marble is worth (\d+) points$", open("input.txt").read()).groups())
|
||||
n *= 100
|
||||
lst = deque([0])
|
||||
scores = [0 for _ in range(players)]
|
||||
for i in range(1, n + 1):
|
||||
p = i % players
|
||||
if i % 23:
|
||||
lst.rotate(-1)
|
||||
lst.append(i)
|
||||
else:
|
||||
lst.rotate(7)
|
||||
scores[p] += i + lst.pop()
|
||||
lst.rotate(-1)
|
||||
print(max(scores))
|
66
Python/2018/10.py
Normal file
66
Python/2018/10.py
Normal file
|
@ -0,0 +1,66 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 10)
|
||||
|
||||
|
||||
points = []
|
||||
for line in input.splitlines():
|
||||
x, y, vx, vy = map(int, re.match(r"^position=< *(-?\d+), *(-?\d+)> velocity=< *(-?\d+), *(-?\d+)>$", line).groups())
|
||||
points.append((x, y, vx, vy))
|
||||
|
||||
i = 0
|
||||
best = 1e1337
|
||||
prev = None
|
||||
while True:
|
||||
p = {}
|
||||
minx = miny = 1e1337
|
||||
maxx = maxy = -1e1337
|
||||
for x, y, vx, vy in points:
|
||||
x += vx * i
|
||||
y += vy * i
|
||||
minx = min(x, minx)
|
||||
maxx = max(x, maxx)
|
||||
miny = min(y, miny)
|
||||
maxy = max(y, maxy)
|
||||
p[(x, y)] = True
|
||||
dist = maxx - minx + maxy - miny
|
||||
|
||||
if dist < best:
|
||||
best = dist
|
||||
i += 1
|
||||
prev = p
|
||||
else:
|
||||
for y in range(miny, maxy + 1):
|
||||
print("".join(" #"[prev.get((x, y), False)] for x in range(minx, maxx + 1)))
|
||||
break
|
||||
|
||||
|
||||
points = []
|
||||
for line in input.splitlines():
|
||||
x, y, vx, vy = map(int, re.match(r"^position=< *(-?\d+), *(-?\d+)> velocity=< *(-?\d+), *(-?\d+)>$", line).groups())
|
||||
points.append((x, y, vx, vy))
|
||||
|
||||
i = 0
|
||||
best = 1e1337
|
||||
prev = None
|
||||
while True:
|
||||
p = {}
|
||||
minx = miny = 1e1337
|
||||
maxx = maxy = -1e1337
|
||||
for x, y, vx, vy in points:
|
||||
x += vx * i
|
||||
y += vy * i
|
||||
minx = min(x, minx)
|
||||
maxx = max(x, maxx)
|
||||
miny = min(y, miny)
|
||||
maxy = max(y, maxy)
|
||||
p[(x, y)] = True
|
||||
dist = maxx - minx + maxy - miny
|
||||
|
||||
if dist < best:
|
||||
best = dist
|
||||
i += 1
|
||||
prev = p
|
||||
else:
|
||||
print(i - 1)
|
||||
break
|
|
@ -1,32 +0,0 @@
|
|||
import re
|
||||
|
||||
points = []
|
||||
for line in open("input.txt").read().splitlines():
|
||||
x, y, vx, vy = map(int, re.match(r"^position=< *(-?\d+), *(-?\d+)> velocity=< *(-?\d+), *(-?\d+)>$", line).groups())
|
||||
points.append((x, y, vx, vy))
|
||||
|
||||
i = 0
|
||||
best = 1e1337
|
||||
prev = None
|
||||
while True:
|
||||
p = {}
|
||||
minx = miny = 1e1337
|
||||
maxx = maxy = -1e1337
|
||||
for x, y, vx, vy in points:
|
||||
x += vx * i
|
||||
y += vy * i
|
||||
minx = min(x, minx)
|
||||
maxx = max(x, maxx)
|
||||
miny = min(y, miny)
|
||||
maxy = max(y, maxy)
|
||||
p[(x, y)] = True
|
||||
dist = maxx - minx + maxy - miny
|
||||
|
||||
if dist < best:
|
||||
best = dist
|
||||
i += 1
|
||||
prev = p
|
||||
else:
|
||||
for y in range(miny, maxy + 1):
|
||||
print("".join(" #"[prev.get((x, y), False)] for x in range(minx, maxx + 1)))
|
||||
break
|
|
@ -1,31 +0,0 @@
|
|||
import re
|
||||
|
||||
points = []
|
||||
for line in open("input.txt").read().splitlines():
|
||||
x, y, vx, vy = map(int, re.match(r"^position=< *(-?\d+), *(-?\d+)> velocity=< *(-?\d+), *(-?\d+)>$", line).groups())
|
||||
points.append((x, y, vx, vy))
|
||||
|
||||
i = 0
|
||||
best = 1e1337
|
||||
prev = None
|
||||
while True:
|
||||
p = {}
|
||||
minx = miny = 1e1337
|
||||
maxx = maxy = -1e1337
|
||||
for x, y, vx, vy in points:
|
||||
x += vx * i
|
||||
y += vy * i
|
||||
minx = min(x, minx)
|
||||
maxx = max(x, maxx)
|
||||
miny = min(y, miny)
|
||||
maxy = max(y, maxy)
|
||||
p[(x, y)] = True
|
||||
dist = maxx - minx + maxy - miny
|
||||
|
||||
if dist < best:
|
||||
best = dist
|
||||
i += 1
|
||||
prev = p
|
||||
else:
|
||||
print(i - 1)
|
||||
break
|
|
@ -1,173 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"# Day 11"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import sys; sys.path.insert(0, \"..\")\n",
|
||||
"\n",
|
||||
"import aoc\n",
|
||||
"\n",
|
||||
"year, day = 2018, 11\n",
|
||||
"\n",
|
||||
"puzzle = aoc.setup(year, day)\n",
|
||||
"plines = puzzle.splitlines()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'243,72'"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def solve1():\n",
|
||||
" serial = int(puzzle)\n",
|
||||
" get = lambda x, y: ((((x+10)*y+serial)*(x+10))//100)%10 - 5\n",
|
||||
" \n",
|
||||
" return \",\".join(map(str, max(\n",
|
||||
" ((x, y)\n",
|
||||
" for x in range(1, 299)\n",
|
||||
" for y in range(1, 299)),\n",
|
||||
" key=lambda k: sum(get(k[0]+i, k[1]+j) for i in range(3) for j in range(3))\n",
|
||||
" )))\n",
|
||||
" \n",
|
||||
"solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"560 ms ± 72.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'229,192,11'"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def solve2():\n",
|
||||
" serial = int(puzzle)\n",
|
||||
" get = lambda x, y: ((((x+10)*y+serial)*(x+10))//100)%10 - 5\n",
|
||||
" ps = [[0] * 301]\n",
|
||||
" for i in range(1, 301):\n",
|
||||
" lst = [0]\n",
|
||||
" for j in range(1, 301):\n",
|
||||
" lst.append(get(j, i) + ps[i-1][j] + lst[j-1] - ps[i-1][j-1])\n",
|
||||
" ps.append(lst)\n",
|
||||
" \n",
|
||||
" sq = lambda x, y, s: ps[y+s-1][x+s-1] - ps[y-1][x+s-1] - ps[y+s-1][x-1] + ps[y-1][x-1]\n",
|
||||
" return \",\".join(map(str, max(\n",
|
||||
" (\n",
|
||||
" (i, j, s)\n",
|
||||
" for s in range(1, 301)\n",
|
||||
" for i in range(1, 302-s)\n",
|
||||
" for j in range(1, 302-s)\n",
|
||||
" ), key=lambda k: sq(*k)\n",
|
||||
" )))\n",
|
||||
"\n",
|
||||
"solve2()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"10.8 s ± 808 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve2()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
42
Python/2018/11.py
Normal file
42
Python/2018/11.py
Normal file
|
@ -0,0 +1,42 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 11)
|
||||
|
||||
|
||||
serial = int(input)
|
||||
get = lambda x, y: ((((x + 10) * y + serial) * (x + 10)) // 100) % 10 - 5
|
||||
print(
|
||||
",".join(
|
||||
map(
|
||||
str,
|
||||
max(
|
||||
((x, y) for x in range(1, 299) for y in range(1, 299)),
|
||||
key=lambda k: sum(get(k[0] + i, k[1] + j) for i in range(3) for j in range(3)),
|
||||
),
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
serial = int(input)
|
||||
get = lambda x, y: ((((x + 10) * y + serial) * (x + 10)) // 100) % 10 - 5
|
||||
ps = [[0] * 301]
|
||||
for i in range(1, 301):
|
||||
lst = [0]
|
||||
for j in range(1, 301):
|
||||
lst.append(get(j, i) + ps[i - 1][j] + lst[j - 1] - ps[i - 1][j - 1])
|
||||
ps.append(lst)
|
||||
|
||||
sq = lambda x, y, s: ps[y + s - 1][x + s - 1] - ps[y - 1][x + s - 1] - ps[y + s - 1][x - 1] + ps[y - 1][x - 1]
|
||||
|
||||
print(
|
||||
",".join(
|
||||
map(
|
||||
str,
|
||||
max(
|
||||
((i, j, s) for s in range(1, 301) for i in range(1, 302 - s) for j in range(1, 302 - s)),
|
||||
key=lambda k: sq(*k),
|
||||
),
|
||||
)
|
||||
)
|
||||
)
|
|
@ -1,155 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"# Day 12"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import sys; sys.path.insert(0, \"..\")\n",
|
||||
"\n",
|
||||
"import aoc\n",
|
||||
"\n",
|
||||
"year, day = 2018, 12\n",
|
||||
"\n",
|
||||
"puzzle = aoc.setup(year, day)\n",
|
||||
"plines = puzzle.splitlines()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 31,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"3230"
|
||||
]
|
||||
},
|
||||
"execution_count": 31,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def solve1():\n",
|
||||
" state, _, *rules = plines\n",
|
||||
" state = {i for i, x in enumerate(state.split()[-1]) if x == \"#\"}\n",
|
||||
" rules = [x.split()[-1] == \"#\" for x in sorted(rules, reverse=True)]\n",
|
||||
" \n",
|
||||
" for _ in range(20):\n",
|
||||
" nums = {k+i-2 for k in state for i in range(5)}\n",
|
||||
" state = {\n",
|
||||
" k\n",
|
||||
" for k in nums\n",
|
||||
" if rules[sum(((k+i-2) in state) * (2**(4-i)) for i in range(5))]\n",
|
||||
" }\n",
|
||||
" return sum(state)\n",
|
||||
"\n",
|
||||
"solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%timeit solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 42,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"4400000000304\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def solve2():\n",
|
||||
" state, _, *rules = plines\n",
|
||||
" state = {i for i, x in enumerate(state.split()[-1]) if x == \"#\"}\n",
|
||||
" rules = [x.split()[-1] == \"#\" for x in sorted(rules, reverse=True)]\n",
|
||||
" \n",
|
||||
" last = None\n",
|
||||
" for _ in range(200):\n",
|
||||
" nums = {k+i-2 for k in state for i in range(5)}\n",
|
||||
" state = {\n",
|
||||
" k\n",
|
||||
" for k in nums\n",
|
||||
" if rules[sum(((k+i-2) in state) * (2**(4-i)) for i in range(5))]\n",
|
||||
" }\n",
|
||||
" s = sum(state)\n",
|
||||
" step = s - last if last is not None else None\n",
|
||||
" last = s\n",
|
||||
" print(s + step * (50000000000 - 200))\n",
|
||||
"\n",
|
||||
"solve2()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"%timeit solve2()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
29
Python/2018/12.py
Normal file
29
Python/2018/12.py
Normal file
|
@ -0,0 +1,29 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 12)
|
||||
|
||||
lines = input.splitlines()
|
||||
|
||||
|
||||
state, _, *rules = lines
|
||||
state = {i for i, x in enumerate(state.split()[-1]) if x == "#"}
|
||||
rules = [x.split()[-1] == "#" for x in sorted(rules, reverse=True)]
|
||||
for _ in range(20):
|
||||
nums = {k + i - 2 for k in state for i in range(5)}
|
||||
state = {k for k in nums if rules[sum(((k + i - 2) in state) * (2 ** (4 - i)) for i in range(5))]}
|
||||
|
||||
print(sum(state))
|
||||
|
||||
|
||||
state, _, *rules = lines
|
||||
state = {i for i, x in enumerate(state.split()[-1]) if x == "#"}
|
||||
rules = [x.split()[-1] == "#" for x in sorted(rules, reverse=True)]
|
||||
last = None
|
||||
for _ in range(200):
|
||||
nums = {k + i - 2 for k in state for i in range(5)}
|
||||
state = {k for k in nums if rules[sum(((k + i - 2) in state) * (2 ** (4 - i)) for i in range(5))]}
|
||||
s = sum(state)
|
||||
step = s - last if last is not None else None
|
||||
last = s
|
||||
|
||||
print(s + step * (50000000000 - 200))
|
|
@ -1,242 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"# Day 13"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import sys; sys.path.insert(0, \"..\")\n",
|
||||
"\n",
|
||||
"import aoc\n",
|
||||
"\n",
|
||||
"year, day = 2018, 13\n",
|
||||
"\n",
|
||||
"puzzle = aoc.setup(year, day, strip=False)\n",
|
||||
"plines = puzzle.splitlines()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'38,57'"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def solve1():\n",
|
||||
" carts = []\n",
|
||||
" tracks = plines.copy()\n",
|
||||
" positions = set()\n",
|
||||
" for y, line in enumerate(tracks):\n",
|
||||
" for x in range(len(line)):\n",
|
||||
" c = line[x]\n",
|
||||
" if c == \"^\":\n",
|
||||
" carts.append([x, y, 0, -1, 0])\n",
|
||||
" positions.add((x, y))\n",
|
||||
" tracks[y] = line = line[:x] + \"|\" + line[x+1:]\n",
|
||||
" elif c == \"v\":\n",
|
||||
" carts.append([x, y, 0, 1, 0])\n",
|
||||
" positions.add((x, y))\n",
|
||||
" tracks[y] = line = line[:x] + \"|\" + line[x+1:]\n",
|
||||
" elif c == \"<\":\n",
|
||||
" carts.append([x, y, -1, 0, 0])\n",
|
||||
" positions.add((x, y))\n",
|
||||
" tracks[y] = line = line[:x] + \"-\" + line[x+1:]\n",
|
||||
" elif c == \">\":\n",
|
||||
" carts.append([x, y, 1, 0, 0])\n",
|
||||
" positions.add((x, y))\n",
|
||||
" tracks[y] = line = line[:x] + \"-\" + line[x+1:]\n",
|
||||
" \n",
|
||||
" while True:\n",
|
||||
" for cart in sorted(carts, key=lambda c: (c[1], c[0])):\n",
|
||||
" x, y, dx, dy, k = cart\n",
|
||||
" positions.remove((x, y))\n",
|
||||
" x += dx\n",
|
||||
" y += dy\n",
|
||||
" if (x, y) in positions:\n",
|
||||
" return f\"{x},{y}\"\n",
|
||||
" positions.add((x, y))\n",
|
||||
" \n",
|
||||
" if tracks[y][x] == \"/\":\n",
|
||||
" dx, dy = -dy, -dx\n",
|
||||
" elif tracks[y][x] == \"\\\\\":\n",
|
||||
" dx, dy = dy, dx\n",
|
||||
" elif tracks[y][x] == \"+\":\n",
|
||||
" if k == 0: dx, dy = dy, -dx\n",
|
||||
" elif k == 2: dx, dy = -dy, dx\n",
|
||||
" k = (k + 1) % 3\n",
|
||||
" \n",
|
||||
" cart[:] = x, y, dx, dy, k\n",
|
||||
"\n",
|
||||
"solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"10.1 ms ± 1.24 ms per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'4,92'"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def solve2():\n",
|
||||
" carts = []\n",
|
||||
" tracks = plines.copy()\n",
|
||||
" positions = {}\n",
|
||||
" crashed = set()\n",
|
||||
" for y, line in enumerate(tracks):\n",
|
||||
" for x in range(len(line)):\n",
|
||||
" c = line[x]\n",
|
||||
" if c == \"^\":\n",
|
||||
" carts.append([x*len(tracks)+y, x, y, 0, -1, 0])\n",
|
||||
" positions[(x, y)] = x*len(tracks)+y\n",
|
||||
" tracks[y] = line = line[:x] + \"|\" + line[x+1:]\n",
|
||||
" elif c == \"v\":\n",
|
||||
" carts.append([x*len(tracks)+y, x, y, 0, 1, 0])\n",
|
||||
" positions[(x, y)] = x*len(tracks)+y\n",
|
||||
" tracks[y] = line = line[:x] + \"|\" + line[x+1:]\n",
|
||||
" elif c == \"<\":\n",
|
||||
" carts.append([x*len(tracks)+y, x, y, -1, 0, 0])\n",
|
||||
" positions[(x, y)] = x*len(tracks)+y\n",
|
||||
" tracks[y] = line = line[:x] + \"-\" + line[x+1:]\n",
|
||||
" elif c == \">\":\n",
|
||||
" carts.append([x*len(tracks)+y, x, y, 1, 0, 0])\n",
|
||||
" positions[(x, y)] = x*len(tracks)+y\n",
|
||||
" tracks[y] = line = line[:x] + \"-\" + line[x+1:]\n",
|
||||
"\n",
|
||||
" while True:\n",
|
||||
" for cart in sorted(carts, key=lambda c: (c[2], c[1])):\n",
|
||||
" i, x, y, dx, dy, k = cart\n",
|
||||
" if i in crashed: continue\n",
|
||||
" \n",
|
||||
" positions.pop((x, y))\n",
|
||||
" x += dx\n",
|
||||
" y += dy\n",
|
||||
" if (x, y) in positions:\n",
|
||||
" crashed.add(i)\n",
|
||||
" crashed.add(positions.pop((x, y)))\n",
|
||||
" continue\n",
|
||||
" positions[(x, y)] = i\n",
|
||||
" \n",
|
||||
" if tracks[y][x] == \"/\":\n",
|
||||
" dx, dy = -dy, -dx\n",
|
||||
" elif tracks[y][x] == \"\\\\\":\n",
|
||||
" dx, dy = dy, dx\n",
|
||||
" elif tracks[y][x] == \"+\":\n",
|
||||
" if k == 0: dx, dy = dy, -dx\n",
|
||||
" elif k == 2: dx, dy = -dy, dx\n",
|
||||
" k = (k + 1) % 3\n",
|
||||
" \n",
|
||||
" cart[:] = i, x, y, dx, dy, k\n",
|
||||
" \n",
|
||||
" if len(carts) - len(crashed) == 1:\n",
|
||||
" for i, x, y, *_ in carts:\n",
|
||||
" if i not in crashed:\n",
|
||||
" return f\"{x},{y}\"\n",
|
||||
"\n",
|
||||
"solve2()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"180 ms ± 15.2 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve2()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
110
Python/2018/13.py
Normal file
110
Python/2018/13.py
Normal file
|
@ -0,0 +1,110 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 13)
|
||||
|
||||
|
||||
carts = []
|
||||
tracks = input.splitlines()
|
||||
positions = set()
|
||||
for y, line in enumerate(tracks):
|
||||
for x in range(len(line)):
|
||||
c = line[x]
|
||||
if c == "^":
|
||||
carts.append([x, y, 0, -1, 0])
|
||||
positions.add((x, y))
|
||||
tracks[y] = line = line[:x] + "|" + line[x + 1 :]
|
||||
elif c == "v":
|
||||
carts.append([x, y, 0, 1, 0])
|
||||
positions.add((x, y))
|
||||
tracks[y] = line = line[:x] + "|" + line[x + 1 :]
|
||||
elif c == "<":
|
||||
carts.append([x, y, -1, 0, 0])
|
||||
positions.add((x, y))
|
||||
tracks[y] = line = line[:x] + "-" + line[x + 1 :]
|
||||
elif c == ">":
|
||||
carts.append([x, y, 1, 0, 0])
|
||||
positions.add((x, y))
|
||||
tracks[y] = line = line[:x] + "-" + line[x + 1 :]
|
||||
|
||||
while True:
|
||||
for cart in sorted(carts, key=lambda c: (c[1], c[0])):
|
||||
x, y, dx, dy, k = cart
|
||||
positions.remove((x, y))
|
||||
x += dx
|
||||
y += dy
|
||||
if (x, y) in positions:
|
||||
print(f"{x},{y}")
|
||||
break
|
||||
positions.add((x, y))
|
||||
if tracks[y][x] == "/":
|
||||
dx, dy = -dy, -dx
|
||||
elif tracks[y][x] == "\\":
|
||||
dx, dy = dy, dx
|
||||
elif tracks[y][x] == "+":
|
||||
if k == 0:
|
||||
dx, dy = dy, -dx
|
||||
elif k == 2:
|
||||
dx, dy = -dy, dx
|
||||
k = (k + 1) % 3
|
||||
cart[:] = x, y, dx, dy, k
|
||||
else:
|
||||
continue
|
||||
break
|
||||
|
||||
|
||||
carts = []
|
||||
tracks = input.splitlines()
|
||||
positions = {}
|
||||
crashed = set()
|
||||
for y, line in enumerate(tracks):
|
||||
for x in range(len(line)):
|
||||
c = line[x]
|
||||
if c == "^":
|
||||
carts.append([x * len(tracks) + y, x, y, 0, -1, 0])
|
||||
positions[(x, y)] = x * len(tracks) + y
|
||||
tracks[y] = line = line[:x] + "|" + line[x + 1 :]
|
||||
elif c == "v":
|
||||
carts.append([x * len(tracks) + y, x, y, 0, 1, 0])
|
||||
positions[(x, y)] = x * len(tracks) + y
|
||||
tracks[y] = line = line[:x] + "|" + line[x + 1 :]
|
||||
elif c == "<":
|
||||
carts.append([x * len(tracks) + y, x, y, -1, 0, 0])
|
||||
positions[(x, y)] = x * len(tracks) + y
|
||||
tracks[y] = line = line[:x] + "-" + line[x + 1 :]
|
||||
elif c == ">":
|
||||
carts.append([x * len(tracks) + y, x, y, 1, 0, 0])
|
||||
positions[(x, y)] = x * len(tracks) + y
|
||||
tracks[y] = line = line[:x] + "-" + line[x + 1 :]
|
||||
|
||||
while True:
|
||||
for cart in sorted(carts, key=lambda c: (c[2], c[1])):
|
||||
i, x, y, dx, dy, k = cart
|
||||
if i in crashed:
|
||||
continue
|
||||
positions.pop((x, y))
|
||||
x += dx
|
||||
y += dy
|
||||
if (x, y) in positions:
|
||||
crashed.add(i)
|
||||
crashed.add(positions.pop((x, y)))
|
||||
continue
|
||||
positions[(x, y)] = i
|
||||
if tracks[y][x] == "/":
|
||||
dx, dy = -dy, -dx
|
||||
elif tracks[y][x] == "\\":
|
||||
dx, dy = dy, dx
|
||||
elif tracks[y][x] == "+":
|
||||
if k == 0:
|
||||
dx, dy = dy, -dx
|
||||
elif k == 2:
|
||||
dx, dy = -dy, dx
|
||||
k = (k + 1) % 3
|
||||
cart[:] = i, x, y, dx, dy, k
|
||||
if len(carts) - len(crashed) == 1:
|
||||
for i, x, y, *_ in carts:
|
||||
if i not in crashed:
|
||||
print(f"{x},{y}")
|
||||
break
|
||||
else:
|
||||
continue
|
||||
break
|
|
@ -1,177 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"# Day 14"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import sys; sys.path.insert(0, \"..\")\n",
|
||||
"\n",
|
||||
"import aoc\n",
|
||||
"\n",
|
||||
"year, day = 2018, 14\n",
|
||||
"\n",
|
||||
"puzzle = aoc.setup(year, day)\n",
|
||||
"plines = puzzle.splitlines()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"'1052903161'"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def solve1():\n",
|
||||
" r = [3, 7]\n",
|
||||
" p = 0\n",
|
||||
" q = 1\n",
|
||||
" n = int(puzzle)\n",
|
||||
" while len(r) < n + 10:\n",
|
||||
" r += [*map(int, str(r[p] + r[q]))]\n",
|
||||
" p = (p + r[p] + 1) % len(r)\n",
|
||||
" q = (q + r[q] + 1) % len(r)\n",
|
||||
" return \"\".join(map(str, r[n:n+10]))\n",
|
||||
"\n",
|
||||
"solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"414 ms ± 31.2 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"20165504"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def gen():\n",
|
||||
" r = [3, 7]\n",
|
||||
" p = 0\n",
|
||||
" q = 1\n",
|
||||
" yield from r\n",
|
||||
" while True:\n",
|
||||
" x = [*map(int, str(r[p] + r[q]))]\n",
|
||||
" yield from x\n",
|
||||
" r += x\n",
|
||||
" p = (p + r[p] + 1) % len(r)\n",
|
||||
" q = (q + r[q] + 1) % len(r)\n",
|
||||
"\n",
|
||||
"def solve2():\n",
|
||||
" n = [*map(int, puzzle)]\n",
|
||||
" g = gen()\n",
|
||||
" lst = [i for _, i in zip(n, g)]\n",
|
||||
" cnt = 0\n",
|
||||
" for num in g:\n",
|
||||
" if lst == n:\n",
|
||||
" return cnt\n",
|
||||
" lst.pop(0)\n",
|
||||
" lst.append(num)\n",
|
||||
" cnt += 1\n",
|
||||
"\n",
|
||||
"solve2()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"26.1 s ± 955 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve2()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
40
Python/2018/14.py
Normal file
40
Python/2018/14.py
Normal file
|
@ -0,0 +1,40 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 14)
|
||||
|
||||
|
||||
r = [3, 7]
|
||||
p = 0
|
||||
q = 1
|
||||
n = int(input)
|
||||
while len(r) < n + 10:
|
||||
r += [*map(int, str(r[p] + r[q]))]
|
||||
p = (p + r[p] + 1) % len(r)
|
||||
q = (q + r[q] + 1) % len(r)
|
||||
print("".join(map(str, r[n : n + 10])))
|
||||
|
||||
|
||||
def gen():
|
||||
r = [3, 7]
|
||||
p = 0
|
||||
q = 1
|
||||
yield from r
|
||||
while True:
|
||||
x = [*map(int, str(r[p] + r[q]))]
|
||||
yield from x
|
||||
r += x
|
||||
p = (p + r[p] + 1) % len(r)
|
||||
q = (q + r[q] + 1) % len(r)
|
||||
|
||||
|
||||
n = [*map(int, input.strip())]
|
||||
g = gen()
|
||||
lst = [i for _, i in zip(n, g)]
|
||||
cnt = 0
|
||||
for num in g:
|
||||
if lst == n:
|
||||
print(cnt)
|
||||
break
|
||||
lst.pop(0)
|
||||
lst.append(num)
|
||||
cnt += 1
|
|
@ -1,340 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"# Day 15"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import sys; sys.path.insert(0, \"..\")\n",
|
||||
"\n",
|
||||
"import aoc\n",
|
||||
"\n",
|
||||
"year, day = 2018, 15\n",
|
||||
"\n",
|
||||
"puzzle = aoc.setup(year, day)\n",
|
||||
"plines = puzzle.splitlines()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"237490"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def adj(x, y): return [(x,y-1),(x-1,y),(x+1,y),(x,y+1)]\n",
|
||||
"\n",
|
||||
"def solve1():\n",
|
||||
" entities = {}\n",
|
||||
" walls = set()\n",
|
||||
" idx = 0\n",
|
||||
" for i, line in enumerate(plines):\n",
|
||||
" for j, c in enumerate(line):\n",
|
||||
" if c == \"#\": walls.add((j, i))\n",
|
||||
" elif c != \".\":\n",
|
||||
" entities[(j, i)] = ((idx, c == \"E\", 200))\n",
|
||||
" idx += 1\n",
|
||||
" \n",
|
||||
" rnd = 0\n",
|
||||
" while True:\n",
|
||||
" done = False\n",
|
||||
" orig = entities.copy()\n",
|
||||
" for x, y in sorted(entities, key=lambda a: a[::-1]):\n",
|
||||
" if (x, y) not in entities: continue\n",
|
||||
" idx, elf, hp = entities[(x, y)]\n",
|
||||
" if idx != orig[(x, y)][0]: continue\n",
|
||||
" \n",
|
||||
" if not any(q[1] != elf for q in entities.values()):\n",
|
||||
" done = True\n",
|
||||
" break\n",
|
||||
"\n",
|
||||
" in_range = [(p, q) for p in adj(x, y) if (q := entities.get(p)) and q[1] != elf]\n",
|
||||
" if not in_range:\n",
|
||||
" queue = [(0, x, y)]\n",
|
||||
" visited = set()\n",
|
||||
" dist = None\n",
|
||||
" nearest = []\n",
|
||||
" while queue:\n",
|
||||
" d, p, q = queue.pop(0)\n",
|
||||
" \n",
|
||||
" if (p, q) in visited: continue\n",
|
||||
" visited.add((p, q))\n",
|
||||
" \n",
|
||||
" if any(e[1] != elf for r in adj(p, q) if (e := entities.get(r))):\n",
|
||||
" if dist is None:\n",
|
||||
" dist = d\n",
|
||||
" elif d > dist: break\n",
|
||||
" nearest.append((p, q))\n",
|
||||
" \n",
|
||||
" for r in adj(p, q):\n",
|
||||
" if r in walls: continue\n",
|
||||
" if (e := entities.get(r)) and e[1] == elf: continue\n",
|
||||
" queue.append((d + 1, *r))\n",
|
||||
" \n",
|
||||
" if not nearest: continue\n",
|
||||
" \n",
|
||||
" target = min(nearest, key=lambda a: a[::-1]) \n",
|
||||
" \n",
|
||||
" queue = [(0, *target)]\n",
|
||||
" visited = set()\n",
|
||||
" dist = None\n",
|
||||
" nearest = []\n",
|
||||
" while queue:\n",
|
||||
" d, p, q = queue.pop(0)\n",
|
||||
" \n",
|
||||
" if (p, q) in visited: continue\n",
|
||||
" visited.add((p, q))\n",
|
||||
" \n",
|
||||
" if (x, y) in adj(p, q):\n",
|
||||
" if dist is None:\n",
|
||||
" dist = d\n",
|
||||
" elif d > dist: break\n",
|
||||
" nearest.append((p, q))\n",
|
||||
" \n",
|
||||
" for r in adj(p, q):\n",
|
||||
" if r in walls: continue\n",
|
||||
" if (e := entities.get(r)) and e[1] == elf: continue\n",
|
||||
" queue.append((d + 1, *r))\n",
|
||||
"\n",
|
||||
" if not nearest: continue\n",
|
||||
" \n",
|
||||
" g = min(nearest, key=lambda a: a[::-1]) \n",
|
||||
" \n",
|
||||
" entities[g] = entities.pop((x, y))\n",
|
||||
" x, y = g\n",
|
||||
" \n",
|
||||
" in_range = [(p, q) for p in adj(x, y) if (q := entities.get(p)) and q[1] != elf]\n",
|
||||
" if in_range:\n",
|
||||
" in_range.sort(key=lambda a: (a[1][2], a[0][::-1]))\n",
|
||||
" p, (idx2, elf2, hp2) = in_range[0]\n",
|
||||
" hp2 -= 3\n",
|
||||
" if hp2 <= 0:\n",
|
||||
" entities.pop(p)\n",
|
||||
" else:\n",
|
||||
" entities[p] = idx2, elf2, hp2\n",
|
||||
" \n",
|
||||
" if done: break\n",
|
||||
" \n",
|
||||
" rnd += 1\n",
|
||||
"\n",
|
||||
" return rnd * sum(e[2] for e in entities.values())\n",
|
||||
"\n",
|
||||
"solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1.33 s ± 164 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"38424"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def simulate(ap):\n",
|
||||
" entities = {}\n",
|
||||
" walls = set()\n",
|
||||
" idx = 0\n",
|
||||
" for i, line in enumerate(plines):\n",
|
||||
" for j, c in enumerate(line):\n",
|
||||
" if c == \"#\": walls.add((j, i))\n",
|
||||
" elif c != \".\":\n",
|
||||
" entities[(j, i)] = ((idx, c == \"E\", 200))\n",
|
||||
" idx += 1\n",
|
||||
" \n",
|
||||
" rnd = 0\n",
|
||||
" while True:\n",
|
||||
" done = False\n",
|
||||
" orig = entities.copy()\n",
|
||||
" for x, y in sorted(entities, key=lambda a: a[::-1]):\n",
|
||||
" if (x, y) not in entities: continue\n",
|
||||
" idx, elf, hp = entities[(x, y)]\n",
|
||||
" if idx != orig[(x, y)][0]: continue\n",
|
||||
" \n",
|
||||
" if not any(q[1] != elf for q in entities.values()):\n",
|
||||
" done = True\n",
|
||||
" break\n",
|
||||
"\n",
|
||||
" in_range = [(p, q) for p in adj(x, y) if (q := entities.get(p)) and q[1] != elf]\n",
|
||||
" if not in_range:\n",
|
||||
" queue = [(0, x, y)]\n",
|
||||
" visited = set()\n",
|
||||
" dist = None\n",
|
||||
" nearest = []\n",
|
||||
" while queue:\n",
|
||||
" d, p, q = queue.pop(0)\n",
|
||||
" \n",
|
||||
" if (p, q) in visited: continue\n",
|
||||
" visited.add((p, q))\n",
|
||||
" \n",
|
||||
" if any(e[1] != elf for r in adj(p, q) if (e := entities.get(r))):\n",
|
||||
" if dist is None:\n",
|
||||
" dist = d\n",
|
||||
" elif d > dist: break\n",
|
||||
" nearest.append((p, q))\n",
|
||||
" \n",
|
||||
" for r in adj(p, q):\n",
|
||||
" if r in walls: continue\n",
|
||||
" if (e := entities.get(r)) and e[1] == elf: continue\n",
|
||||
" queue.append((d + 1, *r))\n",
|
||||
" \n",
|
||||
" if not nearest: continue\n",
|
||||
" \n",
|
||||
" target = min(nearest, key=lambda a: a[::-1]) \n",
|
||||
" \n",
|
||||
" queue = [(0, *target)]\n",
|
||||
" visited = set()\n",
|
||||
" dist = None\n",
|
||||
" nearest = []\n",
|
||||
" while queue:\n",
|
||||
" d, p, q = queue.pop(0)\n",
|
||||
" \n",
|
||||
" if (p, q) in visited: continue\n",
|
||||
" visited.add((p, q))\n",
|
||||
" \n",
|
||||
" if (x, y) in adj(p, q):\n",
|
||||
" if dist is None:\n",
|
||||
" dist = d\n",
|
||||
" elif d > dist: break\n",
|
||||
" nearest.append((p, q))\n",
|
||||
" \n",
|
||||
" for r in adj(p, q):\n",
|
||||
" if r in walls: continue\n",
|
||||
" if (e := entities.get(r)) and e[1] == elf: continue\n",
|
||||
" queue.append((d + 1, *r))\n",
|
||||
"\n",
|
||||
" if not nearest: continue\n",
|
||||
" \n",
|
||||
" g = min(nearest, key=lambda a: a[::-1]) \n",
|
||||
" \n",
|
||||
" entities[g] = entities.pop((x, y))\n",
|
||||
" x, y = g\n",
|
||||
" \n",
|
||||
" in_range = [(p, q) for p in adj(x, y) if (q := entities.get(p)) and q[1] != elf]\n",
|
||||
" if in_range:\n",
|
||||
" in_range.sort(key=lambda a: (a[1][2], a[0][::-1]))\n",
|
||||
" p, (idx2, elf2, hp2) = in_range[0]\n",
|
||||
" hp2 -= ap if elf else 3\n",
|
||||
" if hp2 <= 0:\n",
|
||||
" if elf2: return -1\n",
|
||||
" entities.pop(p)\n",
|
||||
" else:\n",
|
||||
" entities[p] = idx2, elf2, hp2\n",
|
||||
" \n",
|
||||
" if done: break\n",
|
||||
" \n",
|
||||
" rnd += 1\n",
|
||||
"\n",
|
||||
" return rnd * sum(e[2] for e in entities.values())\n",
|
||||
"\n",
|
||||
"def solve2():\n",
|
||||
" ap = 4\n",
|
||||
" while (res := simulate(ap)) < 0: ap += 1\n",
|
||||
" return res\n",
|
||||
"\n",
|
||||
"solve2()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"6.33 s ± 358 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve2()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
233
Python/2018/15.py
Normal file
233
Python/2018/15.py
Normal file
|
@ -0,0 +1,233 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 15)
|
||||
|
||||
lines = input.splitlines()
|
||||
|
||||
|
||||
def adj(x, y):
|
||||
return [(x, y - 1), (x - 1, y), (x + 1, y), (x, y + 1)]
|
||||
|
||||
|
||||
entities = {}
|
||||
walls = set()
|
||||
idx = 0
|
||||
for i, line in enumerate(lines):
|
||||
for j, c in enumerate(line):
|
||||
if c == "#":
|
||||
walls.add((j, i))
|
||||
elif c != ".":
|
||||
entities[(j, i)] = (idx, c == "E", 200)
|
||||
idx += 1
|
||||
|
||||
rnd = 0
|
||||
while True:
|
||||
done = False
|
||||
orig = entities.copy()
|
||||
for x, y in sorted(entities, key=lambda a: a[::-1]):
|
||||
if (x, y) not in entities:
|
||||
continue
|
||||
idx, elf, hp = entities[(x, y)]
|
||||
if idx != orig[(x, y)][0]:
|
||||
continue
|
||||
if not any(q[1] != elf for q in entities.values()):
|
||||
done = True
|
||||
break
|
||||
|
||||
in_range = [(p, q) for p in adj(x, y) if (q := entities.get(p)) and q[1] != elf]
|
||||
if not in_range:
|
||||
queue = [(0, x, y)]
|
||||
visited = set()
|
||||
dist = None
|
||||
nearest = []
|
||||
while queue:
|
||||
d, p, q = queue.pop(0)
|
||||
if (p, q) in visited:
|
||||
continue
|
||||
|
||||
visited.add((p, q))
|
||||
if any(e[1] != elf for r in adj(p, q) if (e := entities.get(r))):
|
||||
if dist is None:
|
||||
dist = d
|
||||
elif d > dist:
|
||||
break
|
||||
nearest.append((p, q))
|
||||
|
||||
for r in adj(p, q):
|
||||
if r in walls:
|
||||
continue
|
||||
if (e := entities.get(r)) and e[1] == elf:
|
||||
continue
|
||||
queue.append((d + 1, *r))
|
||||
|
||||
if not nearest:
|
||||
continue
|
||||
|
||||
target = min(nearest, key=lambda a: a[::-1])
|
||||
queue = [(0, *target)]
|
||||
visited = set()
|
||||
dist = None
|
||||
nearest = []
|
||||
while queue:
|
||||
d, p, q = queue.pop(0)
|
||||
if (p, q) in visited:
|
||||
continue
|
||||
|
||||
visited.add((p, q))
|
||||
if (x, y) in adj(p, q):
|
||||
if dist is None:
|
||||
dist = d
|
||||
elif d > dist:
|
||||
break
|
||||
|
||||
nearest.append((p, q))
|
||||
|
||||
for r in adj(p, q):
|
||||
if r in walls:
|
||||
continue
|
||||
if (e := entities.get(r)) and e[1] == elf:
|
||||
continue
|
||||
|
||||
queue.append((d + 1, *r))
|
||||
|
||||
if not nearest:
|
||||
continue
|
||||
|
||||
g = min(nearest, key=lambda a: a[::-1])
|
||||
entities[g] = entities.pop((x, y))
|
||||
x, y = g
|
||||
|
||||
in_range = [(p, q) for p in adj(x, y) if (q := entities.get(p)) and q[1] != elf]
|
||||
|
||||
if in_range:
|
||||
in_range.sort(key=lambda a: (a[1][2], a[0][::-1]))
|
||||
p, (idx2, elf2, hp2) = in_range[0]
|
||||
hp2 -= 3
|
||||
if hp2 <= 0:
|
||||
entities.pop(p)
|
||||
else:
|
||||
entities[p] = idx2, elf2, hp2
|
||||
|
||||
if done:
|
||||
break
|
||||
|
||||
rnd += 1
|
||||
|
||||
print(rnd * sum(e[2] for e in entities.values()))
|
||||
|
||||
|
||||
def simulate(ap):
|
||||
entities = {}
|
||||
walls = set()
|
||||
idx = 0
|
||||
for i, line in enumerate(lines):
|
||||
for j, c in enumerate(line):
|
||||
if c == "#":
|
||||
walls.add((j, i))
|
||||
elif c != ".":
|
||||
entities[(j, i)] = (idx, c == "E", 200)
|
||||
idx += 1
|
||||
|
||||
rnd = 0
|
||||
while True:
|
||||
done = False
|
||||
|
||||
orig = entities.copy()
|
||||
for x, y in sorted(entities, key=lambda a: a[::-1]):
|
||||
if (x, y) not in entities:
|
||||
continue
|
||||
|
||||
idx, elf, hp = entities[(x, y)]
|
||||
if idx != orig[(x, y)][0]:
|
||||
continue
|
||||
|
||||
if not any(q[1] != elf for q in entities.values()):
|
||||
done = True
|
||||
break
|
||||
|
||||
in_range = [(p, q) for p in adj(x, y) if (q := entities.get(p)) and q[1] != elf]
|
||||
if not in_range:
|
||||
queue = [(0, x, y)]
|
||||
visited = set()
|
||||
dist = None
|
||||
nearest = []
|
||||
while queue:
|
||||
d, p, q = queue.pop(0)
|
||||
if (p, q) in visited:
|
||||
continue
|
||||
|
||||
visited.add((p, q))
|
||||
if any(e[1] != elf for r in adj(p, q) if (e := entities.get(r))):
|
||||
if dist is None:
|
||||
dist = d
|
||||
elif d > dist:
|
||||
break
|
||||
nearest.append((p, q))
|
||||
for r in adj(p, q):
|
||||
if r in walls:
|
||||
continue
|
||||
if (e := entities.get(r)) and e[1] == elf:
|
||||
continue
|
||||
|
||||
queue.append((d + 1, *r))
|
||||
|
||||
if not nearest:
|
||||
continue
|
||||
|
||||
target = min(nearest, key=lambda a: a[::-1])
|
||||
queue = [(0, *target)]
|
||||
visited = set()
|
||||
dist = None
|
||||
nearest = []
|
||||
while queue:
|
||||
d, p, q = queue.pop(0)
|
||||
if (p, q) in visited:
|
||||
continue
|
||||
|
||||
visited.add((p, q))
|
||||
if (x, y) in adj(p, q):
|
||||
if dist is None:
|
||||
dist = d
|
||||
elif d > dist:
|
||||
break
|
||||
nearest.append((p, q))
|
||||
|
||||
for r in adj(p, q):
|
||||
if r in walls:
|
||||
continue
|
||||
if (e := entities.get(r)) and e[1] == elf:
|
||||
continue
|
||||
queue.append((d + 1, *r))
|
||||
|
||||
if not nearest:
|
||||
continue
|
||||
|
||||
g = min(nearest, key=lambda a: a[::-1])
|
||||
entities[g] = entities.pop((x, y))
|
||||
x, y = g
|
||||
|
||||
in_range = [(p, q) for p in adj(x, y) if (q := entities.get(p)) and q[1] != elf]
|
||||
if in_range:
|
||||
in_range.sort(key=lambda a: (a[1][2], a[0][::-1]))
|
||||
p, (idx2, elf2, hp2) = in_range[0]
|
||||
hp2 -= ap if elf else 3
|
||||
if hp2 <= 0:
|
||||
if elf2:
|
||||
return -1
|
||||
|
||||
entities.pop(p)
|
||||
else:
|
||||
entities[p] = idx2, elf2, hp2
|
||||
|
||||
if done:
|
||||
break
|
||||
|
||||
rnd += 1
|
||||
|
||||
return rnd * sum(e[2] for e in entities.values())
|
||||
|
||||
|
||||
ap = 4
|
||||
while (res := simulate(ap)) < 0:
|
||||
ap += 1
|
||||
print(res)
|
|
@ -1,208 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"# Day 16"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import sys; sys.path.insert(0, \"..\")\n",
|
||||
"\n",
|
||||
"import aoc\n",
|
||||
"\n",
|
||||
"year, day = 2018, 16\n",
|
||||
"\n",
|
||||
"puzzle = aoc.setup(year, day)\n",
|
||||
"plines = puzzle.splitlines()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"651"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"opcodes = [\n",
|
||||
" lambda reg, a, b: reg[a] + reg[b], # addr\n",
|
||||
" lambda reg, a, b: reg[a] + b, # addi\n",
|
||||
" lambda reg, a, b: reg[a] * reg[b], # mulr\n",
|
||||
" lambda reg, a, b: reg[a] * b, # muli\n",
|
||||
" lambda reg, a, b: reg[a] & reg[b], # banr\n",
|
||||
" lambda reg, a, b: reg[a] & b, # bani\n",
|
||||
" lambda reg, a, b: reg[a] | reg[b], # borr\n",
|
||||
" lambda reg, a, b: reg[a] | b, # bori\n",
|
||||
" lambda reg, a, b: reg[a], # setr\n",
|
||||
" lambda reg, a, b: a, # seti\n",
|
||||
" lambda reg, a, b: a > reg[b], # gtir\n",
|
||||
" lambda reg, a, b: reg[a] > b, # gtri\n",
|
||||
" lambda reg, a, b: reg[a] > reg[b], # gtrr\n",
|
||||
" lambda reg, a, b: a == reg[b], # eqir\n",
|
||||
" lambda reg, a, b: reg[a] == b, # eqri\n",
|
||||
" lambda reg, a, b: reg[a] == reg[b], # eqrr\n",
|
||||
"]\n",
|
||||
"\n",
|
||||
"def exec_opcode(reg, op, a, b, c):\n",
|
||||
" reg[c] = int(op(reg, a, b))\n",
|
||||
" \n",
|
||||
"def test_opcode(before, after, op, a, b, c):\n",
|
||||
" before = [*before]\n",
|
||||
" exec_opcode(before, op, a, b, c)\n",
|
||||
" return before == after\n",
|
||||
"\n",
|
||||
"def solve1():\n",
|
||||
" out = 0\n",
|
||||
" for before, instruction, after in map(str.splitlines, puzzle.split(\"\\n\\n\\n\")[0].split(\"\\n\\n\")):\n",
|
||||
" before = eval(before.split(\": \")[1])\n",
|
||||
" _, a, b, c = map(int, instruction.split())\n",
|
||||
" after = eval(after.split(\": \")[1])\n",
|
||||
" out += sum(test_opcode(before, after, op, a, b, c) for op in opcodes) >= 3\n",
|
||||
" return out\n",
|
||||
"\n",
|
||||
"solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"33.4 ms ± 2.03 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"706"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def solve2():\n",
|
||||
" codes = [opcodes.copy() for _ in range(16)]\n",
|
||||
" m = [None] * 16\n",
|
||||
" for before, instruction, after in map(str.splitlines, puzzle.split(\"\\n\\n\\n\")[0].split(\"\\n\\n\")):\n",
|
||||
" before = eval(before.split(\": \")[1])\n",
|
||||
" op, a, b, c = map(int, instruction.split())\n",
|
||||
" after = eval(after.split(\": \")[1])\n",
|
||||
" \n",
|
||||
" for o in [*codes[op]]:\n",
|
||||
" if not test_opcode(before, after, o, a, b, c):\n",
|
||||
" codes[op].remove(o)\n",
|
||||
" if len(codes[op]) == 1:\n",
|
||||
" m[op] = codes[op][0]\n",
|
||||
" \n",
|
||||
" q = [x for x in m if x]\n",
|
||||
" while q:\n",
|
||||
" x = q.pop()\n",
|
||||
" for i, lst in enumerate(codes):\n",
|
||||
" if x in lst:\n",
|
||||
" lst.remove(x)\n",
|
||||
" if len(lst) == 1:\n",
|
||||
" m[i] = lst[0]\n",
|
||||
" q.append(m[i])\n",
|
||||
"\n",
|
||||
" reg = [0] * 4\n",
|
||||
" for line in puzzle.split(\"\\n\\n\\n\\n\")[1].splitlines():\n",
|
||||
" op, a, b, c = map(int, line.split())\n",
|
||||
" exec_opcode(reg, m[op], a, b, c)\n",
|
||||
" return reg[0]\n",
|
||||
"\n",
|
||||
"solve2()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"31.7 ms ± 7.67 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve2()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
75
Python/2018/16.py
Normal file
75
Python/2018/16.py
Normal file
|
@ -0,0 +1,75 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 16)
|
||||
|
||||
opcodes = [
|
||||
lambda reg, a, b: reg[a] + reg[b], # addr
|
||||
lambda reg, a, b: reg[a] + b, # addi
|
||||
lambda reg, a, b: reg[a] * reg[b], # mulr
|
||||
lambda reg, a, b: reg[a] * b, # muli
|
||||
lambda reg, a, b: reg[a] & reg[b], # banr
|
||||
lambda reg, a, b: reg[a] & b, # bani
|
||||
lambda reg, a, b: reg[a] | reg[b], # borr
|
||||
lambda reg, a, b: reg[a] | b, # bori
|
||||
lambda reg, a, b: reg[a], # setr
|
||||
lambda reg, a, b: a, # seti
|
||||
lambda reg, a, b: a > reg[b], # gtir
|
||||
lambda reg, a, b: reg[a] > b, # gtri
|
||||
lambda reg, a, b: reg[a] > reg[b], # gtrr
|
||||
lambda reg, a, b: a == reg[b], # eqir
|
||||
lambda reg, a, b: reg[a] == b, # eqri
|
||||
lambda reg, a, b: reg[a] == reg[b], # eqrr
|
||||
]
|
||||
|
||||
|
||||
def exec_opcode(reg, op, a, b, c):
|
||||
reg[c] = int(op(reg, a, b))
|
||||
|
||||
|
||||
def test_opcode(before, after, op, a, b, c):
|
||||
before = [*before]
|
||||
|
||||
exec_opcode(before, op, a, b, c)
|
||||
|
||||
return before == after
|
||||
|
||||
|
||||
out = 0
|
||||
for before, instruction, after in map(str.splitlines, input.split("\n\n\n")[0].split("\n\n")):
|
||||
before = eval(before.split(": ")[1])
|
||||
_, a, b, c = map(int, instruction.split())
|
||||
after = eval(after.split(": ")[1])
|
||||
out += sum(test_opcode(before, after, op, a, b, c) for op in opcodes) >= 3
|
||||
|
||||
print(out)
|
||||
|
||||
|
||||
codes = [opcodes.copy() for _ in range(16)]
|
||||
m = [None] * 16
|
||||
for before, instruction, after in map(str.splitlines, input.split("\n\n\n")[0].split("\n\n")):
|
||||
before = eval(before.split(": ")[1])
|
||||
op, a, b, c = map(int, instruction.split())
|
||||
after = eval(after.split(": ")[1])
|
||||
for o in [*codes[op]]:
|
||||
if not test_opcode(before, after, o, a, b, c):
|
||||
codes[op].remove(o)
|
||||
if len(codes[op]) == 1:
|
||||
m[op] = codes[op][0]
|
||||
|
||||
q = [x for x in m if x]
|
||||
while q:
|
||||
x = q.pop()
|
||||
for i, lst in enumerate(codes):
|
||||
if x in lst:
|
||||
lst.remove(x)
|
||||
if len(lst) == 1:
|
||||
m[i] = lst[0]
|
||||
q.append(m[i])
|
||||
|
||||
reg = [0] * 4
|
||||
|
||||
for line in input.split("\n\n\n\n")[1].splitlines():
|
||||
op, a, b, c = map(int, line.split())
|
||||
exec_opcode(reg, m[op], a, b, c)
|
||||
|
||||
print(reg[0])
|
|
@ -1,260 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"# Day 17"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import sys; sys.path.insert(0, \"..\")\n",
|
||||
"\n",
|
||||
"import aoc\n",
|
||||
"\n",
|
||||
"year, day = 2018, 17\n",
|
||||
"\n",
|
||||
"puzzle = aoc.setup(year, day)\n",
|
||||
"plines = puzzle.splitlines()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"37858"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def solve1():\n",
|
||||
" clay = set()\n",
|
||||
" miny = 1e1337\n",
|
||||
" maxy = 0\n",
|
||||
" for line in plines:\n",
|
||||
" a, b = line.split(\", \")\n",
|
||||
" a = int(a.split(\"=\")[1])\n",
|
||||
" b1, b2 = map(int, b.split(\"=\")[1].split(\"..\"))\n",
|
||||
" for i in range(b1, b2+1):\n",
|
||||
" if line[0] == \"x\": x, y = a, i\n",
|
||||
" else: x, y = i, a\n",
|
||||
" clay.add((x, y))\n",
|
||||
" miny = min(y, miny)\n",
|
||||
" maxy = max(y, maxy)\n",
|
||||
" \n",
|
||||
" reachable = set()\n",
|
||||
" water = set()\n",
|
||||
" dp = {}\n",
|
||||
" def flow(x, y):\n",
|
||||
" if y > maxy: return False\n",
|
||||
" if (x, y) in clay: return True\n",
|
||||
" if (x, y) in dp:\n",
|
||||
" return dp[(x, y)]\n",
|
||||
" \n",
|
||||
" reachable.add((x, y))\n",
|
||||
" \n",
|
||||
" if not flow(x, y + 1):\n",
|
||||
" dp[(x, y)] = False\n",
|
||||
" return False\n",
|
||||
"\n",
|
||||
" add = set()\n",
|
||||
" ok = True\n",
|
||||
" \n",
|
||||
" k = x\n",
|
||||
" while (k, y) not in clay:\n",
|
||||
" add.add((k, y))\n",
|
||||
" if not flow(k, y + 1):\n",
|
||||
" ok = False\n",
|
||||
" break\n",
|
||||
" k -= 1\n",
|
||||
" \n",
|
||||
" k = x\n",
|
||||
" while (k, y) not in clay:\n",
|
||||
" add.add((k, y))\n",
|
||||
" if not flow(k, y + 1):\n",
|
||||
" ok = False\n",
|
||||
" break\n",
|
||||
" k += 1\n",
|
||||
" \n",
|
||||
" reachable.update(add)\n",
|
||||
" if ok: water.update(add)\n",
|
||||
" \n",
|
||||
" dp[(x, y)] = ok\n",
|
||||
" return ok\n",
|
||||
" \n",
|
||||
" flow(500, 0)\n",
|
||||
" \n",
|
||||
" return sum((x, y) != (500, 0) and y in range(miny, maxy+1) for x, y in reachable)\n",
|
||||
"\n",
|
||||
"solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1.83 s ± 283 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"30410"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def solve2():\n",
|
||||
" clay = set()\n",
|
||||
" miny = 1e1337\n",
|
||||
" maxy = 0\n",
|
||||
" for line in plines:\n",
|
||||
" a, b = line.split(\", \")\n",
|
||||
" a = int(a.split(\"=\")[1])\n",
|
||||
" b1, b2 = map(int, b.split(\"=\")[1].split(\"..\"))\n",
|
||||
" for i in range(b1, b2+1):\n",
|
||||
" if line[0] == \"x\": x, y = a, i\n",
|
||||
" else: x, y = i, a\n",
|
||||
" clay.add((x, y))\n",
|
||||
" miny = min(y, miny)\n",
|
||||
" maxy = max(y, maxy)\n",
|
||||
" \n",
|
||||
" reachable = set()\n",
|
||||
" water = set()\n",
|
||||
" dp = {}\n",
|
||||
" def flow(x, y):\n",
|
||||
" if y > maxy: return False\n",
|
||||
" if (x, y) in clay: return True\n",
|
||||
" if (x, y) in dp:\n",
|
||||
" return dp[(x, y)]\n",
|
||||
" \n",
|
||||
" reachable.add((x, y))\n",
|
||||
" \n",
|
||||
" if not flow(x, y + 1):\n",
|
||||
" dp[(x, y)] = False\n",
|
||||
" return False\n",
|
||||
"\n",
|
||||
" add = set()\n",
|
||||
" ok = True\n",
|
||||
" \n",
|
||||
" k = x\n",
|
||||
" while (k, y) not in clay:\n",
|
||||
" add.add((k, y))\n",
|
||||
" if not flow(k, y + 1):\n",
|
||||
" ok = False\n",
|
||||
" break\n",
|
||||
" k -= 1\n",
|
||||
" \n",
|
||||
" k = x\n",
|
||||
" while (k, y) not in clay:\n",
|
||||
" add.add((k, y))\n",
|
||||
" if not flow(k, y + 1):\n",
|
||||
" ok = False\n",
|
||||
" break\n",
|
||||
" k += 1\n",
|
||||
" \n",
|
||||
" reachable.update(add)\n",
|
||||
" if ok: water.update(add)\n",
|
||||
" \n",
|
||||
" dp[(x, y)] = ok\n",
|
||||
" return ok\n",
|
||||
" \n",
|
||||
" flow(500, 0)\n",
|
||||
" \n",
|
||||
" return len(water)\n",
|
||||
"\n",
|
||||
"solve2()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1.71 s ± 239 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve2()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
138
Python/2018/17.py
Normal file
138
Python/2018/17.py
Normal file
|
@ -0,0 +1,138 @@
|
|||
import sys
|
||||
|
||||
from lib import *
|
||||
|
||||
sys.setrecursionlimit(10000)
|
||||
|
||||
input = read_input(2018, 17)
|
||||
|
||||
lines = input.splitlines()
|
||||
|
||||
|
||||
clay = set()
|
||||
miny = 1e1337
|
||||
maxy = 0
|
||||
for line in lines:
|
||||
a, b = line.split(", ")
|
||||
a = int(a.split("=")[1])
|
||||
b1, b2 = map(int, b.split("=")[1].split(".."))
|
||||
for i in range(b1, b2 + 1):
|
||||
if line[0] == "x":
|
||||
x, y = a, i
|
||||
else:
|
||||
x, y = i, a
|
||||
clay.add((x, y))
|
||||
miny = min(y, miny)
|
||||
maxy = max(y, maxy)
|
||||
|
||||
reachable = set()
|
||||
water = set()
|
||||
dp = {}
|
||||
|
||||
|
||||
def flow(x, y):
|
||||
if y > maxy:
|
||||
return False
|
||||
if (x, y) in clay:
|
||||
return True
|
||||
if (x, y) in dp:
|
||||
return dp[(x, y)]
|
||||
reachable.add((x, y))
|
||||
|
||||
if not flow(x, y + 1):
|
||||
dp[(x, y)] = False
|
||||
return False
|
||||
|
||||
add = set()
|
||||
ok = True
|
||||
k = x
|
||||
while (k, y) not in clay:
|
||||
add.add((k, y))
|
||||
if not flow(k, y + 1):
|
||||
ok = False
|
||||
break
|
||||
k -= 1
|
||||
|
||||
k = x
|
||||
while (k, y) not in clay:
|
||||
add.add((k, y))
|
||||
if not flow(k, y + 1):
|
||||
ok = False
|
||||
break
|
||||
k += 1
|
||||
|
||||
reachable.update(add)
|
||||
if ok:
|
||||
water.update(add)
|
||||
dp[(x, y)] = ok
|
||||
return ok
|
||||
|
||||
|
||||
flow(500, 0)
|
||||
|
||||
print(sum((x, y) != (500, 0) and y in range(miny, maxy + 1) for x, y in reachable))
|
||||
|
||||
|
||||
clay = set()
|
||||
miny = 1e1337
|
||||
maxy = 0
|
||||
for line in lines:
|
||||
a, b = line.split(", ")
|
||||
a = int(a.split("=")[1])
|
||||
b1, b2 = map(int, b.split("=")[1].split(".."))
|
||||
for i in range(b1, b2 + 1):
|
||||
if line[0] == "x":
|
||||
x, y = a, i
|
||||
else:
|
||||
x, y = i, a
|
||||
clay.add((x, y))
|
||||
miny = min(y, miny)
|
||||
maxy = max(y, maxy)
|
||||
|
||||
reachable = set()
|
||||
water = set()
|
||||
dp = {}
|
||||
|
||||
|
||||
def flow(x, y):
|
||||
if y > maxy:
|
||||
return False
|
||||
if (x, y) in clay:
|
||||
return True
|
||||
if (x, y) in dp:
|
||||
return dp[(x, y)]
|
||||
|
||||
reachable.add((x, y))
|
||||
if not flow(x, y + 1):
|
||||
dp[(x, y)] = False
|
||||
return False
|
||||
|
||||
add = set()
|
||||
ok = True
|
||||
k = x
|
||||
while (k, y) not in clay:
|
||||
add.add((k, y))
|
||||
if not flow(k, y + 1):
|
||||
ok = False
|
||||
break
|
||||
k -= 1
|
||||
|
||||
k = x
|
||||
while (k, y) not in clay:
|
||||
add.add((k, y))
|
||||
if not flow(k, y + 1):
|
||||
ok = False
|
||||
break
|
||||
|
||||
k += 1
|
||||
reachable.update(add)
|
||||
if ok:
|
||||
water.update(add)
|
||||
|
||||
dp[(x, y)] = ok
|
||||
return ok
|
||||
|
||||
|
||||
flow(500, 0)
|
||||
|
||||
print(len(water))
|
|
@ -1,193 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"# Day 18"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import sys; sys.path.insert(0, \"..\")\n",
|
||||
"\n",
|
||||
"import aoc\n",
|
||||
"\n",
|
||||
"year, day = 2018, 18\n",
|
||||
"\n",
|
||||
"puzzle = aoc.setup(year, day)\n",
|
||||
"plines = puzzle.splitlines()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"594712"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def cntAdj(grid, y, x, t):\n",
|
||||
" return sum(grid[i][j] == t for i in range(y-1, y+2) for j in range(x-1, x+2) if (i, j) != (y, x) and i in range(len(grid)) and j in range(len(grid[i])))\n",
|
||||
"\n",
|
||||
"def solve1():\n",
|
||||
" grid = plines\n",
|
||||
" for _ in range(10):\n",
|
||||
" new_grid = []\n",
|
||||
" for i, line in enumerate(grid):\n",
|
||||
" new_line = \"\"\n",
|
||||
" for j, c in enumerate(line):\n",
|
||||
" if c == \".\" and cntAdj(grid, i, j, \"|\") >= 3: new_line += \"|\"\n",
|
||||
" elif c == \"|\" and cntAdj(grid, i, j, \"#\") >= 3: new_line += \"#\"\n",
|
||||
" elif c == \"#\" and not (cntAdj(grid, i, j, \"#\") >= 1 and cntAdj(grid, i, j, \"|\") >= 1): new_line += \".\"\n",
|
||||
" else: new_line += c\n",
|
||||
" new_grid.append(new_line)\n",
|
||||
" grid = new_grid\n",
|
||||
" \n",
|
||||
" a = sum(line.count(\"|\") for line in grid)\n",
|
||||
" b = sum(line.count(\"#\") for line in grid)\n",
|
||||
" return a * b\n",
|
||||
"\n",
|
||||
"solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"294 ms ± 69.5 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Puzzle 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"203138"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def next_iteration(grid):\n",
|
||||
" new_grid = []\n",
|
||||
" for i, line in enumerate(grid):\n",
|
||||
" new_line = \"\"\n",
|
||||
" for j, c in enumerate(line):\n",
|
||||
" if c == \".\" and cntAdj(grid, i, j, \"|\") >= 3: new_line += \"|\"\n",
|
||||
" elif c == \"|\" and cntAdj(grid, i, j, \"#\") >= 3: new_line += \"#\"\n",
|
||||
" elif c == \"#\" and not (cntAdj(grid, i, j, \"#\") >= 1 and cntAdj(grid, i, j, \"|\") >= 1): new_line += \".\"\n",
|
||||
" else: new_line += c\n",
|
||||
" new_grid.append(new_line)\n",
|
||||
" return new_grid\n",
|
||||
"\n",
|
||||
"def solve2():\n",
|
||||
" grid = plines\n",
|
||||
" seen = {}\n",
|
||||
" i = 0\n",
|
||||
" while tuple(grid) not in seen:\n",
|
||||
" seen[tuple(grid)] = i\n",
|
||||
" grid = next_iteration(grid)\n",
|
||||
" i += 1\n",
|
||||
" \n",
|
||||
" cycle = i - seen[tuple(grid)]\n",
|
||||
" \n",
|
||||
" for _ in range((1000000000 - i) % cycle):\n",
|
||||
" grid = next_iteration(grid)\n",
|
||||
" \n",
|
||||
" a = sum(line.count(\"|\") for line in grid)\n",
|
||||
" b = sum(line.count(\"#\") for line in grid)\n",
|
||||
" return a * b\n",
|
||||
"\n",
|
||||
"solve2()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"13.1 s ± 634 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve2()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
68
Python/2018/18.py
Normal file
68
Python/2018/18.py
Normal file
|
@ -0,0 +1,68 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 18)
|
||||
|
||||
|
||||
def cntAdj(grid, y, x, t):
|
||||
return sum(
|
||||
grid[i][j] == t
|
||||
for i in range(y - 1, y + 2)
|
||||
for j in range(x - 1, x + 2)
|
||||
if (i, j) != (y, x) and i in range(len(grid)) and j in range(len(grid[i]))
|
||||
)
|
||||
|
||||
|
||||
grid = input.splitlines()
|
||||
for _ in range(10):
|
||||
new_grid = []
|
||||
for i, line in enumerate(grid):
|
||||
new_line = ""
|
||||
for j, c in enumerate(line):
|
||||
if c == "." and cntAdj(grid, i, j, "|") >= 3:
|
||||
new_line += "|"
|
||||
elif c == "|" and cntAdj(grid, i, j, "#") >= 3:
|
||||
new_line += "#"
|
||||
elif c == "#" and not (cntAdj(grid, i, j, "#") >= 1 and cntAdj(grid, i, j, "|") >= 1):
|
||||
new_line += "."
|
||||
else:
|
||||
new_line += c
|
||||
new_grid.append(new_line)
|
||||
grid = new_grid
|
||||
|
||||
a = sum(line.count("|") for line in grid)
|
||||
b = sum(line.count("#") for line in grid)
|
||||
print(a * b)
|
||||
|
||||
|
||||
def next_iteration(grid):
|
||||
new_grid = []
|
||||
for i, line in enumerate(grid):
|
||||
new_line = ""
|
||||
for j, c in enumerate(line):
|
||||
if c == "." and cntAdj(grid, i, j, "|") >= 3:
|
||||
new_line += "|"
|
||||
elif c == "|" and cntAdj(grid, i, j, "#") >= 3:
|
||||
new_line += "#"
|
||||
elif c == "#" and not (cntAdj(grid, i, j, "#") >= 1 and cntAdj(grid, i, j, "|") >= 1):
|
||||
new_line += "."
|
||||
else:
|
||||
new_line += c
|
||||
new_grid.append(new_line)
|
||||
return new_grid
|
||||
|
||||
|
||||
grid = input.splitlines()
|
||||
seen = {}
|
||||
i = 0
|
||||
while tuple(grid) not in seen:
|
||||
seen[tuple(grid)] = i
|
||||
grid = next_iteration(grid)
|
||||
i += 1
|
||||
|
||||
cycle = i - seen[tuple(grid)]
|
||||
for _ in range((1000000000 - i) % cycle):
|
||||
grid = next_iteration(grid)
|
||||
|
||||
a = sum(line.count("|") for line in grid)
|
||||
b = sum(line.count("#") for line in grid)
|
||||
print(a * b)
|
|
@ -1,242 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"# Day 19"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import sys; sys.path.insert(0, \"..\")\n",
|
||||
"\n",
|
||||
"import aoc\n",
|
||||
"\n",
|
||||
"year, day = 2018, 19\n",
|
||||
"\n",
|
||||
"puzzle = aoc.setup(year, day)\n",
|
||||
"plines = puzzle.splitlines()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"opcodes = {\n",
|
||||
" \"addr\": lambda reg, a, b: reg[a] + reg[b], # addr\n",
|
||||
" \"addi\": lambda reg, a, b: reg[a] + b, # addi\n",
|
||||
" \"mulr\": lambda reg, a, b: reg[a] * reg[b], # mulr\n",
|
||||
" \"muli\": lambda reg, a, b: reg[a] * b, # muli\n",
|
||||
" \"banr\": lambda reg, a, b: reg[a] & reg[b], # banr\n",
|
||||
" \"bani\": lambda reg, a, b: reg[a] & b, # bani\n",
|
||||
" \"borr\": lambda reg, a, b: reg[a] | reg[b], # borr\n",
|
||||
" \"bori\": lambda reg, a, b: reg[a] | b, # bori\n",
|
||||
" \"setr\": lambda reg, a, b: reg[a], # setr\n",
|
||||
" \"seti\": lambda reg, a, b: a, # seti\n",
|
||||
" \"gtir\": lambda reg, a, b: a > reg[b], # gtir\n",
|
||||
" \"gtri\": lambda reg, a, b: reg[a] > b, # gtri\n",
|
||||
" \"gtrr\": lambda reg, a, b: reg[a] > reg[b], # gtrr\n",
|
||||
" \"eqir\": lambda reg, a, b: a == reg[b], # eqir\n",
|
||||
" \"eqri\": lambda reg, a, b: reg[a] == b, # eqri\n",
|
||||
" \"eqrr\": lambda reg, a, b: reg[a] == reg[b], # eqrr\n",
|
||||
"}\n",
|
||||
"\n",
|
||||
"def exec_opcode(reg, op, a, b, c):\n",
|
||||
" reg[c] = int(opcodes[op](reg, a, b))"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"1568"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def solve1():\n",
|
||||
" ip, *instructions = plines\n",
|
||||
" ip = int(ip.split()[1])\n",
|
||||
" reg = [0] * 6\n",
|
||||
" while reg[ip] in range(len(instructions)):\n",
|
||||
" op, a, b, c = instructions[reg[ip]].split()\n",
|
||||
" exec_opcode(reg, op, *map(int, [a,b,c]))\n",
|
||||
" reg[ip] += 1\n",
|
||||
" return reg[0]\n",
|
||||
"\n",
|
||||
"solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"13.5 s ± 619 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"000| ip += 16\n",
|
||||
"001| r5 = 1\n",
|
||||
"002| r3 = 1\n",
|
||||
"003| r4 = r5 * r3\n",
|
||||
"004| r4 = r4 == r1\n",
|
||||
"005| ip += r4\n",
|
||||
"006| ip += 1\n",
|
||||
"007| r0 += r5\n",
|
||||
"008| r3 += 1\n",
|
||||
"009| r4 = r3 > r1\n",
|
||||
"010| ip += r4\n",
|
||||
"011| ip = 2\n",
|
||||
"012| r5 += 1\n",
|
||||
"013| r4 = r5 > r1\n",
|
||||
"014| ip += r4\n",
|
||||
"015| ip = 1\n",
|
||||
"016| ip *= ip\n",
|
||||
"017| r1 += 2\n",
|
||||
"018| r1 *= r1\n",
|
||||
"019| r1 *= ip\n",
|
||||
"020| r1 *= 11\n",
|
||||
"021| r4 += 2\n",
|
||||
"022| r4 *= ip\n",
|
||||
"023| r4 += 12\n",
|
||||
"024| r1 += r4\n",
|
||||
"025| ip += r0\n",
|
||||
"026| ip = 0\n",
|
||||
"027| r4 = ip\n",
|
||||
"028| r4 *= ip\n",
|
||||
"029| r4 += ip\n",
|
||||
"030| r4 *= ip\n",
|
||||
"031| r4 *= 14\n",
|
||||
"032| r4 *= ip\n",
|
||||
"033| r1 += r4\n",
|
||||
"034| r0 = 0\n",
|
||||
"035| ip = 0\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"ip, *instructions = plines\n",
|
||||
"ip = int(ip.split()[1])\n",
|
||||
"\n",
|
||||
"reg = lambda i: \"ip\" if i == ip else f\"r{i}\"\n",
|
||||
"\n",
|
||||
"for i, (op, a, b, c) in enumerate(map(str.split, instructions)):\n",
|
||||
" a, b, c = map(int, [a, b, c])\n",
|
||||
" if op[:2] in [\"eq\", \"gt\"]:\n",
|
||||
" print(f\"{i:03}| {reg(c)} = {reg(a) if op[2]=='r' else a} { {'eq':'==','gt':'>'}[op[:2]]} {reg(b) if op[3]=='r' else b}\")\n",
|
||||
" elif op[:3] == \"set\":\n",
|
||||
" print(f\"{i:03}| {reg(c)} = {reg(a) if op[-1]=='r' else a}\")\n",
|
||||
" else:\n",
|
||||
" if a == c:\n",
|
||||
" print(f\"{i:03}| {reg(c)} { {'add':'+','mul':'*','ban':'&','bor':'|'}[op[:3]]}= {reg(b) if op[-1]=='r' else b}\") \n",
|
||||
" elif b == c and op[-1] == \"r\":\n",
|
||||
" print(f\"{i:03}| {reg(c)} { {'add':'+','mul':'*','ban':'&','bor':'|'}[op[:3]]}= {reg(a)}\") \n",
|
||||
" else:\n",
|
||||
" print(f\"{i:03}| {reg(c)} = {reg(a)} { {'add':'+','mul':'*','ban':'&','bor':'|'}[op[:3]]} {reg(b) if op[-1]=='r' else b}\") \n",
|
||||
" "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"19030032"
|
||||
]
|
||||
},
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"r1 = 2 * 2 * 19 * 11 + 2 * 22 + 12 + (27 * 28 + 29) * 30 * 14 * 32\n",
|
||||
"r0 = 0\n",
|
||||
"\n",
|
||||
"for r5 in range(1, r1 + 1):\n",
|
||||
" if r1 % r5 == 0: r0 += r5\n",
|
||||
"# for r3 in range(1, r1 + 1):\n",
|
||||
"# if r3 == r1 / r5: r0 += r5\n",
|
||||
"\n",
|
||||
"r0"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
48
Python/2018/19.py
Normal file
48
Python/2018/19.py
Normal file
|
@ -0,0 +1,48 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 19)
|
||||
|
||||
lines = input.splitlines()
|
||||
|
||||
opcodes = {
|
||||
"addr": lambda reg, a, b: reg[a] + reg[b],
|
||||
"addi": lambda reg, a, b: reg[a] + b,
|
||||
"mulr": lambda reg, a, b: reg[a] * reg[b],
|
||||
"muli": lambda reg, a, b: reg[a] * b,
|
||||
"banr": lambda reg, a, b: reg[a] & reg[b],
|
||||
"bani": lambda reg, a, b: reg[a] & b,
|
||||
"borr": lambda reg, a, b: reg[a] | reg[b],
|
||||
"bori": lambda reg, a, b: reg[a] | b,
|
||||
"setr": lambda reg, a, b: reg[a],
|
||||
"seti": lambda reg, a, b: a,
|
||||
"gtir": lambda reg, a, b: a > reg[b],
|
||||
"gtri": lambda reg, a, b: reg[a] > b,
|
||||
"gtrr": lambda reg, a, b: reg[a] > reg[b],
|
||||
"eqir": lambda reg, a, b: a == reg[b],
|
||||
"eqri": lambda reg, a, b: reg[a] == b,
|
||||
"eqrr": lambda reg, a, b: reg[a] == reg[b],
|
||||
}
|
||||
|
||||
|
||||
def exec_opcode(reg, op, a, b, c):
|
||||
reg[c] = int(opcodes[op](reg, a, b))
|
||||
|
||||
|
||||
ip, *instructions = lines
|
||||
ip = int(ip.split()[1])
|
||||
reg = [0] * 6
|
||||
while reg[ip] in range(len(instructions)):
|
||||
op, a, b, c = instructions[reg[ip]].split()
|
||||
exec_opcode(reg, op, *map(int, [a, b, c]))
|
||||
reg[ip] += 1
|
||||
|
||||
print(reg[0])
|
||||
|
||||
|
||||
r1 = 2 * 2 * 19 * 11 + 2 * 22 + 12 + (27 * 28 + 29) * 30 * 14 * 32
|
||||
r0 = 0
|
||||
for r5 in range(1, r1 + 1):
|
||||
if r1 % r5 == 0:
|
||||
r0 += r5
|
||||
|
||||
print(r0)
|
|
@ -1,239 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"# Day 20"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import sys; sys.path.insert(0, \"..\")\n",
|
||||
"\n",
|
||||
"import aoc\n",
|
||||
"\n",
|
||||
"year, day = 2018, 20\n",
|
||||
"\n",
|
||||
"puzzle = aoc.setup(year, day)\n",
|
||||
"plines = puzzle.splitlines()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"3545"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def parse_regex(regex):\n",
|
||||
" regex = regex.strip(\"^$\")\n",
|
||||
" stack = [[]]\n",
|
||||
" \n",
|
||||
" for c in regex:\n",
|
||||
" if c == \"(\":\n",
|
||||
" stack.append([])\n",
|
||||
" stack.append([])\n",
|
||||
" elif c == \")\":\n",
|
||||
" x = stack.pop()\n",
|
||||
" y = stack.pop()\n",
|
||||
" y.append(x)\n",
|
||||
" stack[-1].append(tuple(y))\n",
|
||||
" elif c == \"|\":\n",
|
||||
" x = stack.pop()\n",
|
||||
" stack[-1].append(x)\n",
|
||||
" stack.append([])\n",
|
||||
" else:\n",
|
||||
" stack[-1].append(c)\n",
|
||||
" \n",
|
||||
" return stack[0]\n",
|
||||
"\n",
|
||||
"dp = set()\n",
|
||||
"\n",
|
||||
"def traverse(graph, regex, x, y, decisions=None, pop_after=None):\n",
|
||||
" decisions = decisions or ()\n",
|
||||
" if (x, y, decisions) in dp: return\n",
|
||||
" dp.add((x, y, decisions))\n",
|
||||
" \n",
|
||||
" i = 0\n",
|
||||
" while i < len(regex):\n",
|
||||
" if i == pop_after: decisions = (*decisions[:-1], None)\n",
|
||||
" \n",
|
||||
" elem = regex[i]\n",
|
||||
" prev = x, y\n",
|
||||
" if isinstance(elem, tuple):\n",
|
||||
" for j, option in enumerate(elem):\n",
|
||||
" traverse(graph, option + regex[i+1:], x, y, (*decisions, j), len(option))\n",
|
||||
" break\n",
|
||||
" elif elem == \"N\":\n",
|
||||
" y -= 1\n",
|
||||
" elif elem == \"E\":\n",
|
||||
" x += 1\n",
|
||||
" elif elem == \"S\":\n",
|
||||
" y += 1\n",
|
||||
" elif elem == \"W\":\n",
|
||||
" x -= 1\n",
|
||||
" \n",
|
||||
" graph.setdefault(prev, set()).add((x, y))\n",
|
||||
" graph.setdefault((x, y), set()).add(prev)\n",
|
||||
" \n",
|
||||
" i += 1\n",
|
||||
"\n",
|
||||
"def solve1():\n",
|
||||
" dp.clear()\n",
|
||||
" regex = parse_regex(puzzle)\n",
|
||||
" graph = {}\n",
|
||||
" traverse(graph, regex, 0, 0)\n",
|
||||
" \n",
|
||||
" queue = [(0, 0, 0)]\n",
|
||||
" visited = set()\n",
|
||||
" out = 0\n",
|
||||
" while queue:\n",
|
||||
" d, x, y = queue.pop(0)\n",
|
||||
" \n",
|
||||
" if (x, y) in visited: continue\n",
|
||||
" visited.add((x, y))\n",
|
||||
" \n",
|
||||
" out = max(out, d)\n",
|
||||
" \n",
|
||||
" for p, q in graph.get((x, y), []):\n",
|
||||
" if (p, q) not in visited: queue.append((d+1, p, q))\n",
|
||||
" \n",
|
||||
" return out\n",
|
||||
"\n",
|
||||
"solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"67.1 ms ± 12.6 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"7838"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def solve2():\n",
|
||||
" dp.clear()\n",
|
||||
" regex = parse_regex(puzzle)\n",
|
||||
" graph = {}\n",
|
||||
" traverse(graph, regex, 0, 0)\n",
|
||||
" \n",
|
||||
" queue = [(0, 0, 0)]\n",
|
||||
" visited = set()\n",
|
||||
" out = 0\n",
|
||||
" while queue:\n",
|
||||
" d, x, y = queue.pop(0)\n",
|
||||
" \n",
|
||||
" if (x, y) in visited: continue\n",
|
||||
" visited.add((x, y))\n",
|
||||
" \n",
|
||||
" if d >= 1000: out += 1\n",
|
||||
" \n",
|
||||
" for p, q in graph.get((x, y), []):\n",
|
||||
" if (p, q) not in visited: queue.append((d+1, p, q))\n",
|
||||
" \n",
|
||||
" return out\n",
|
||||
"\n",
|
||||
"solve2()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"65 ms ± 14.4 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve2()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
101
Python/2018/20.py
Normal file
101
Python/2018/20.py
Normal file
|
@ -0,0 +1,101 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 20)
|
||||
|
||||
|
||||
def parse_regex(regex):
|
||||
regex = regex.strip("^$")
|
||||
stack = [[]]
|
||||
for c in regex:
|
||||
if c == "(":
|
||||
stack.append([])
|
||||
stack.append([])
|
||||
elif c == ")":
|
||||
x = stack.pop()
|
||||
y = stack.pop()
|
||||
y.append(x)
|
||||
stack[-1].append(tuple(y))
|
||||
elif c == "|":
|
||||
x = stack.pop()
|
||||
stack[-1].append(x)
|
||||
stack.append([])
|
||||
else:
|
||||
stack[-1].append(c)
|
||||
return stack[0]
|
||||
|
||||
|
||||
dp = set()
|
||||
|
||||
|
||||
def traverse(graph, regex, x, y, decisions=None, pop_after=None):
|
||||
decisions = decisions or ()
|
||||
if (x, y, decisions) in dp:
|
||||
return
|
||||
|
||||
dp.add((x, y, decisions))
|
||||
i = 0
|
||||
while i < len(regex):
|
||||
if i == pop_after:
|
||||
decisions = (*decisions[:-1], None)
|
||||
|
||||
elem = regex[i]
|
||||
prev = x, y
|
||||
if isinstance(elem, tuple):
|
||||
for j, option in enumerate(elem):
|
||||
traverse(graph, option + regex[i + 1 :], x, y, (*decisions, j), len(option))
|
||||
break
|
||||
|
||||
elif elem == "N":
|
||||
y -= 1
|
||||
elif elem == "E":
|
||||
x += 1
|
||||
elif elem == "S":
|
||||
y += 1
|
||||
elif elem == "W":
|
||||
x -= 1
|
||||
graph.setdefault(prev, set()).add((x, y))
|
||||
graph.setdefault((x, y), set()).add(prev)
|
||||
i += 1
|
||||
|
||||
|
||||
regex = parse_regex(input)
|
||||
graph = {}
|
||||
traverse(graph, regex, 0, 0)
|
||||
queue = [(0, 0, 0)]
|
||||
visited = set()
|
||||
out = 0
|
||||
while queue:
|
||||
d, x, y = queue.pop(0)
|
||||
if (x, y) in visited:
|
||||
continue
|
||||
|
||||
visited.add((x, y))
|
||||
out = max(out, d)
|
||||
for p, q in graph.get((x, y), []):
|
||||
if (p, q) not in visited:
|
||||
queue.append((d + 1, p, q))
|
||||
|
||||
print(out)
|
||||
|
||||
|
||||
dp.clear()
|
||||
regex = parse_regex(input)
|
||||
graph = {}
|
||||
traverse(graph, regex, 0, 0)
|
||||
queue = [(0, 0, 0)]
|
||||
visited = set()
|
||||
out = 0
|
||||
while queue:
|
||||
d, x, y = queue.pop(0)
|
||||
if (x, y) in visited:
|
||||
continue
|
||||
|
||||
visited.add((x, y))
|
||||
if d >= 1000:
|
||||
out += 1
|
||||
|
||||
for p, q in graph.get((x, y), []):
|
||||
if (p, q) not in visited:
|
||||
queue.append((d + 1, p, q))
|
||||
|
||||
print(out)
|
|
@ -1,263 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"# Day 21"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import sys; sys.path.insert(0, \"..\")\n",
|
||||
"\n",
|
||||
"import aoc\n",
|
||||
"\n",
|
||||
"year, day = 2018, 21\n",
|
||||
"\n",
|
||||
"puzzle = aoc.setup(year, day)\n",
|
||||
"plines = puzzle.splitlines()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"000| r1 = 123\n",
|
||||
"001| r1 &= 456\n",
|
||||
"002| r1 = r1 == 72\n",
|
||||
"003| ip += r1\n",
|
||||
"004| ip = 0\n",
|
||||
"005| r1 = 0\n",
|
||||
"006| r5 = r1 | 65536\n",
|
||||
"007| r1 = 8586263\n",
|
||||
"008| r2 = r5 & 255\n",
|
||||
"009| r1 += r2\n",
|
||||
"010| r1 &= 16777215\n",
|
||||
"011| r1 *= 65899\n",
|
||||
"012| r1 &= 16777215\n",
|
||||
"013| r2 = 256 > r5\n",
|
||||
"014| ip += r2\n",
|
||||
"015| ip += 1\n",
|
||||
"016| ip = 27\n",
|
||||
"017| r2 = 0\n",
|
||||
"018| r3 = r2 + 1\n",
|
||||
"019| r3 *= 256\n",
|
||||
"020| r3 = r3 > r5\n",
|
||||
"021| ip += r3\n",
|
||||
"022| ip += 1\n",
|
||||
"023| ip = 25\n",
|
||||
"024| r2 += 1\n",
|
||||
"025| ip = 17\n",
|
||||
"026| r5 = r2\n",
|
||||
"027| ip = 7\n",
|
||||
"028| r2 = r1 == r0\n",
|
||||
"029| ip += r2\n",
|
||||
"030| ip = 5\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"ip, *instructions = plines\n",
|
||||
"ip = int(ip.split()[1])\n",
|
||||
"\n",
|
||||
"reg = lambda i: \"ip\" if i == ip else f\"r{i}\"\n",
|
||||
"\n",
|
||||
"for i, (op, a, b, c) in enumerate(map(str.split, instructions)):\n",
|
||||
" a, b, c = map(int, [a, b, c])\n",
|
||||
" if op[:2] in [\"eq\", \"gt\"]:\n",
|
||||
" print(f\"{i:03}| {reg(c)} = {reg(a) if op[2]=='r' else a} { {'eq':'==','gt':'>'}[op[:2]]} {reg(b) if op[3]=='r' else b}\")\n",
|
||||
" elif op[:3] == \"set\":\n",
|
||||
" print(f\"{i:03}| {reg(c)} = {reg(a) if op[-1]=='r' else a}\")\n",
|
||||
" else:\n",
|
||||
" if a == c:\n",
|
||||
" print(f\"{i:03}| {reg(c)} { {'add':'+','mul':'*','ban':'&','bor':'|'}[op[:3]]}= {reg(b) if op[-1]=='r' else b}\") \n",
|
||||
" elif b == c and op[-1] == \"r\":\n",
|
||||
" print(f\"{i:03}| {reg(c)} { {'add':'+','mul':'*','ban':'&','bor':'|'}[op[:3]]}= {reg(a)}\") \n",
|
||||
" else:\n",
|
||||
" print(f\"{i:03}| {reg(c)} = {reg(a)} { {'add':'+','mul':'*','ban':'&','bor':'|'}[op[:3]]} {reg(b) if op[-1]=='r' else b}\") "
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "raw",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"assert 123 & 456 == 72\n",
|
||||
"\n",
|
||||
"r1 = 0\n",
|
||||
"\n",
|
||||
"while True:\n",
|
||||
" r5 = r1 | 65536\n",
|
||||
" r1 = 8586263\n",
|
||||
"\n",
|
||||
" while r5:\n",
|
||||
" r1 += r5 & 255\n",
|
||||
" r1 &= 16777215\n",
|
||||
" r1 *= 65899\n",
|
||||
" r1 &= 16777215\n",
|
||||
" \n",
|
||||
" r5 //= 256\n",
|
||||
"\n",
|
||||
" if r1 == r0: break"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"5970144"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def solve1():\n",
|
||||
" r1 = 0\n",
|
||||
" r5 = r1 | 65536\n",
|
||||
" r1 = 8586263\n",
|
||||
"\n",
|
||||
" while r5:\n",
|
||||
" r1 += r5 & 255\n",
|
||||
" r1 &= 16777215\n",
|
||||
" r1 *= 65899\n",
|
||||
" r1 &= 16777215\n",
|
||||
"\n",
|
||||
" r5 //= 256\n",
|
||||
" return r1\n",
|
||||
"\n",
|
||||
"solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1.08 µs ± 60.8 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"13943296"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def solve2():\n",
|
||||
" r1 = 0\n",
|
||||
" seen = set()\n",
|
||||
" out = r1\n",
|
||||
" while r1 not in seen:\n",
|
||||
" out = r1\n",
|
||||
" seen.add(r1)\n",
|
||||
" r5 = r1 | 65536\n",
|
||||
" r1 = 8586263\n",
|
||||
"\n",
|
||||
" while r5:\n",
|
||||
" r1 += r5 & 255\n",
|
||||
" r1 &= 16777215\n",
|
||||
" r1 *= 65899\n",
|
||||
" r1 &= 16777215\n",
|
||||
"\n",
|
||||
" r5 //= 256\n",
|
||||
"\n",
|
||||
" return out\n",
|
||||
"\n",
|
||||
"solve2()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"13.4 ms ± 877 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve2()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
28
Python/2018/21.py
Normal file
28
Python/2018/21.py
Normal file
|
@ -0,0 +1,28 @@
|
|||
r1 = 0
|
||||
r5 = r1 | 65536
|
||||
r1 = 8586263
|
||||
while r5:
|
||||
r1 += r5 & 255
|
||||
r1 &= 16777215
|
||||
r1 *= 65899
|
||||
r1 &= 16777215
|
||||
r5 //= 256
|
||||
print(r1)
|
||||
|
||||
|
||||
r1 = 0
|
||||
seen = set()
|
||||
out = r1
|
||||
while r1 not in seen:
|
||||
out = r1
|
||||
seen.add(r1)
|
||||
r5 = r1 | 65536
|
||||
r1 = 8586263
|
||||
while r5:
|
||||
r1 += r5 & 255
|
||||
r1 &= 16777215
|
||||
r1 *= 65899
|
||||
r1 &= 16777215
|
||||
r5 //= 256
|
||||
|
||||
print(out)
|
|
@ -1,183 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"# Day 22"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import sys; sys.path.insert(0, \"..\")\n",
|
||||
"\n",
|
||||
"import aoc\n",
|
||||
"\n",
|
||||
"year, day = 2018, 22\n",
|
||||
"\n",
|
||||
"puzzle = aoc.setup(year, day)\n",
|
||||
"plines = puzzle.splitlines()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"7743"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"depth = int(plines[0].split()[1])\n",
|
||||
"tx, ty = map(int, plines[1].split()[1].split(\",\"))\n",
|
||||
"\n",
|
||||
"dp = {}\n",
|
||||
"def get_geologic_index(x, y):\n",
|
||||
" if (x, y) == (tx, ty): return 0\n",
|
||||
" if y == 0: return x * 16807\n",
|
||||
" if x == 0: return y * 48271\n",
|
||||
" if (x, y) not in dp: dp[(x, y)] = get_erosion_level(x-1, y) * get_erosion_level(x, y-1)\n",
|
||||
" return dp[(x, y)]\n",
|
||||
"\n",
|
||||
"def get_erosion_level(x, y):\n",
|
||||
" return (get_geologic_index(x, y) + depth) % 20183\n",
|
||||
"\n",
|
||||
"def solve1():\n",
|
||||
" return sum(get_erosion_level(x, y) % 3 for y in range(ty+1) for x in range(tx+1))\n",
|
||||
"\n",
|
||||
"solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"6.58 ms ± 456 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"1029"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import heapq\n",
|
||||
"\n",
|
||||
"def solve2():\n",
|
||||
" queue = [(0, 0, 0, 1)]\n",
|
||||
" visited = set()\n",
|
||||
" while queue:\n",
|
||||
" d, x, y, e = heapq.heappop(queue)\n",
|
||||
" \n",
|
||||
" if (x, y, e) in visited: continue\n",
|
||||
" visited.add((x, y, e))\n",
|
||||
" \n",
|
||||
" if (x, y, e) == (tx, ty, 1):\n",
|
||||
" return d\n",
|
||||
" \n",
|
||||
" t = get_erosion_level(x, y) % 3\n",
|
||||
" \n",
|
||||
" heapq.heappush(queue, (d + 7, x, y, (-e-t)%3))\n",
|
||||
" \n",
|
||||
" for p, q in [(x-1, y), (x+1, y), (x, y-1), (x, y+1)]:\n",
|
||||
" if p < 0 or q < 0: continue\n",
|
||||
" t = get_erosion_level(p, q) % 3\n",
|
||||
" if t == e: continue\n",
|
||||
" heapq.heappush(queue, (d + 1, p, q, e))\n",
|
||||
"\n",
|
||||
"solve2()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"18.4 s ± 659 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve2()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
56
Python/2018/22.py
Normal file
56
Python/2018/22.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 22)
|
||||
|
||||
lines = input.splitlines()
|
||||
|
||||
depth = int(lines[0].split()[1])
|
||||
|
||||
tx, ty = map(int, lines[1].split()[1].split(","))
|
||||
|
||||
|
||||
dp = {}
|
||||
|
||||
|
||||
def get_geologic_index(x, y):
|
||||
if (x, y) == (tx, ty):
|
||||
return 0
|
||||
if y == 0:
|
||||
return x * 16807
|
||||
if x == 0:
|
||||
return y * 48271
|
||||
if (x, y) not in dp:
|
||||
dp[(x, y)] = get_erosion_level(x - 1, y) * get_erosion_level(x, y - 1)
|
||||
return dp[(x, y)]
|
||||
|
||||
|
||||
def get_erosion_level(x, y):
|
||||
return (get_geologic_index(x, y) + depth) % 20183
|
||||
|
||||
|
||||
print(sum(get_erosion_level(x, y) % 3 for y in range(ty + 1) for x in range(tx + 1)))
|
||||
|
||||
|
||||
queue = [(0, 0, 0, 1)]
|
||||
visited = set()
|
||||
while queue:
|
||||
d, x, y, e = heapq.heappop(queue)
|
||||
if (x, y, e) in visited:
|
||||
continue
|
||||
|
||||
visited.add((x, y, e))
|
||||
if (x, y, e) == (tx, ty, 1):
|
||||
print(d)
|
||||
break
|
||||
|
||||
t = get_erosion_level(x, y) % 3
|
||||
heapq.heappush(queue, (d + 7, x, y, (-e - t) % 3))
|
||||
for p, q in [(x - 1, y), (x + 1, y), (x, y - 1), (x, y + 1)]:
|
||||
if p < 0 or q < 0:
|
||||
continue
|
||||
|
||||
t = get_erosion_level(p, q) % 3
|
||||
if t == e:
|
||||
continue
|
||||
|
||||
heapq.heappush(queue, (d + 1, p, q, e))
|
|
@ -1,185 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"# Day 23"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import sys; sys.path.insert(0, \"..\")\n",
|
||||
"\n",
|
||||
"import aoc\n",
|
||||
"\n",
|
||||
"year, day = 2018, 23\n",
|
||||
"\n",
|
||||
"puzzle = aoc.setup(year, day)\n",
|
||||
"plines = puzzle.splitlines()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"730"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def solve1():\n",
|
||||
" bots = []\n",
|
||||
" for pos, r in map(str.split, plines):\n",
|
||||
" x, y, z = map(int, pos.split(\"<\")[1].strip(\">,\").split(\",\"))\n",
|
||||
" r = int(r.split(\"=\")[1])\n",
|
||||
" bots.append((x, y, z, r))\n",
|
||||
" \n",
|
||||
" sx, sy, sz, sr = max(bots, key=lambda a: a[3])\n",
|
||||
" return sum(abs(x-sx)+abs(y-sy)+abs(z-sz) <= sr for x, y, z, _ in bots)\n",
|
||||
"\n",
|
||||
"solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"2.38 ms ± 225 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"48202279"
|
||||
],
|
||||
"text/plain": [
|
||||
"48202279"
|
||||
]
|
||||
},
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"from z3 import *\n",
|
||||
"\n",
|
||||
"def solve2():\n",
|
||||
" bots = []\n",
|
||||
" for pos, r in map(str.split, plines):\n",
|
||||
" x, y, z = map(int, pos.split(\"<\")[1].strip(\">,\").split(\",\"))\n",
|
||||
" r = int(r.split(\"=\")[1])\n",
|
||||
" bots.append((x, y, z, r))\n",
|
||||
"\n",
|
||||
" zabs = lambda x: If(x >= 0, x, -x)\n",
|
||||
"\n",
|
||||
" x, y, z = Ints(\"x y z\")\n",
|
||||
" in_ranges = [Int(f\"in_range_{i}\") for i in range(len(bots))]\n",
|
||||
" range_count = Int(\"sum\")\n",
|
||||
" \n",
|
||||
" o = Optimize()\n",
|
||||
" for (nx, ny, nz, nr), ir in zip(bots, in_ranges):\n",
|
||||
" o.add(ir == If(zabs(x - nx) + zabs(y - ny) + zabs(z - nz) <= nr, 1, 0))\n",
|
||||
"\n",
|
||||
" o.add(range_count == sum(in_ranges))\n",
|
||||
" \n",
|
||||
" dist_from_zero = Int(\"dist\")\n",
|
||||
" o.add(dist_from_zero == zabs(x) + zabs(y) + zabs(z))\n",
|
||||
" \n",
|
||||
" h1 = o.maximize(range_count)\n",
|
||||
" h2 = o.minimize(dist_from_zero)\n",
|
||||
"\n",
|
||||
" o.check()\n",
|
||||
" return o.lower(h2)\n",
|
||||
"\n",
|
||||
"solve2()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1min 31s ± 15.4 s per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve2()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
39
Python/2018/23.py
Normal file
39
Python/2018/23.py
Normal file
|
@ -0,0 +1,39 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 23)
|
||||
|
||||
lines = input.splitlines()
|
||||
|
||||
|
||||
bots = []
|
||||
for pos, r in map(str.split, lines):
|
||||
x, y, z = map(int, pos.split("<")[1].strip(">,").split(","))
|
||||
r = int(r.split("=")[1])
|
||||
bots.append((x, y, z, r))
|
||||
sx, sy, sz, sr = max(bots, key=lambda a: a[3])
|
||||
|
||||
print(sum(abs(x - sx) + abs(y - sy) + abs(z - sz) <= sr for x, y, z, _ in bots))
|
||||
|
||||
|
||||
bots = []
|
||||
for pos, r in map(str.split, lines):
|
||||
x, y, z = map(int, pos.split("<")[1].strip(">,").split(","))
|
||||
r = int(r.split("=")[1])
|
||||
bots.append((x, y, z, r))
|
||||
|
||||
zabs = lambda x: z3.If(x >= 0, x, -x)
|
||||
x, y, z = z3.Ints("x y z")
|
||||
in_ranges = [z3.Int(f"in_range_{i}") for i in range(len(bots))]
|
||||
range_count = z3.Int("sum")
|
||||
o = z3.Optimize()
|
||||
for (nx, ny, nz, nr), ir in zip(bots, in_ranges):
|
||||
o.add(ir == z3.If(zabs(x - nx) + zabs(y - ny) + zabs(z - nz) <= nr, 1, 0))
|
||||
|
||||
o.add(range_count == sum(in_ranges))
|
||||
dist_from_zero = z3.Int("dist")
|
||||
o.add(dist_from_zero == zabs(x) + zabs(y) + zabs(z))
|
||||
h1 = o.maximize(range_count)
|
||||
h2 = o.minimize(dist_from_zero)
|
||||
o.check()
|
||||
|
||||
print(o.lower(h2))
|
|
@ -1,253 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"# Day 24"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import sys; sys.path.insert(0, \"..\")\n",
|
||||
"\n",
|
||||
"import aoc\n",
|
||||
"\n",
|
||||
"year, day = 2018, 24\n",
|
||||
"\n",
|
||||
"puzzle = aoc.setup(year, day)\n",
|
||||
"plines = puzzle.splitlines()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"from dataclasses import dataclass\n",
|
||||
"import re\n",
|
||||
"\n",
|
||||
"@dataclass\n",
|
||||
"class Group:\n",
|
||||
" army: int\n",
|
||||
" units: int\n",
|
||||
" hp: int\n",
|
||||
" ap: int\n",
|
||||
" at: str\n",
|
||||
" init: int\n",
|
||||
" weak: set[str]\n",
|
||||
" immune: set[str]\n",
|
||||
" \n",
|
||||
" def __hash__(self): return id(self)\n",
|
||||
" \n",
|
||||
" @staticmethod\n",
|
||||
" def parse(army, line, boost=0):\n",
|
||||
" units, hp, _, extra, ap, at, init = re.match(r\"^(\\d+) units each with (\\d+) hit points( \\((.*)\\))? with an attack that does (\\d+) (\\w+) damage at initiative (\\d+)$\", line).groups()\n",
|
||||
" \n",
|
||||
" weak = set()\n",
|
||||
" immune = set()\n",
|
||||
" for part in extra.split(\"; \") if extra else []:\n",
|
||||
" t, _, *xs = part.split()\n",
|
||||
" {\"weak\": weak, \"immune\": immune}[t].update(x.strip(\",\") for x in xs)\n",
|
||||
" \n",
|
||||
" return Group(army, int(units), int(hp), int(ap) + boost, at, int(init), weak, immune)\n",
|
||||
" \n",
|
||||
" @property\n",
|
||||
" def ep(self):\n",
|
||||
" return self.units * self.ap\n",
|
||||
" \n",
|
||||
" @property\n",
|
||||
" def dead(self):\n",
|
||||
" return self.units <= 0\n",
|
||||
" \n",
|
||||
" def calc_damage(self, target):\n",
|
||||
" if self.at in target.immune: return 0\n",
|
||||
" mul = 2 if self.at in target.weak else 1\n",
|
||||
" return self.ep * mul\n",
|
||||
" \n",
|
||||
" def attack(self, target):\n",
|
||||
" damage = self.calc_damage(target) // target.hp\n",
|
||||
" target.units -= damage\n",
|
||||
" return damage"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"22996"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def solve1():\n",
|
||||
" immune, infect = [[Group.parse(i, group) for group in army.splitlines()[1:]] for i, army in enumerate(puzzle.split(\"\\n\\n\"))]\n",
|
||||
" \n",
|
||||
" while immune and infect:\n",
|
||||
" targets = {}\n",
|
||||
" imm_att = set(immune)\n",
|
||||
" inf_att = set(infect)\n",
|
||||
" \n",
|
||||
" for group in sorted(immune + infect, key=lambda g: (-g.ep, -g.init)):\n",
|
||||
" attackable = [inf_att, imm_att][group.army]\n",
|
||||
" if not attackable: continue\n",
|
||||
" target = max(attackable, key=lambda g: (group.calc_damage(g), g.ep, g.init))\n",
|
||||
" if not group.calc_damage(target): continue\n",
|
||||
" attackable.remove(target)\n",
|
||||
" targets[group] = target\n",
|
||||
" \n",
|
||||
" for group, target in sorted(targets.items(), key=lambda a: -a[0].init):\n",
|
||||
" if group.dead: continue\n",
|
||||
" group.attack(target)\n",
|
||||
" \n",
|
||||
" immune, infect = [[g for g in x if not g.dead] for x in [immune, infect]]\n",
|
||||
" \n",
|
||||
" return sum(g.units for g in immune + infect)\n",
|
||||
"\n",
|
||||
"solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"49.2 ms ± 15.7 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"4327"
|
||||
]
|
||||
},
|
||||
"execution_count": 5,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"def test(boost):\n",
|
||||
" immune, infect = [[Group.parse(i, group, boost if i == 0 else 0) for group in army.splitlines()[1:]] for i, army in enumerate(puzzle.split(\"\\n\\n\"))]\n",
|
||||
" \n",
|
||||
" while immune and infect:\n",
|
||||
" targets = {}\n",
|
||||
" imm_att = set(immune)\n",
|
||||
" inf_att = set(infect)\n",
|
||||
" \n",
|
||||
" for group in sorted(immune + infect, key=lambda g: (-g.ep, -g.init)):\n",
|
||||
" attackable = [inf_att, imm_att][group.army]\n",
|
||||
" if not attackable: continue\n",
|
||||
" target = max(attackable, key=lambda g: (group.calc_damage(g), g.ep, g.init))\n",
|
||||
" if not group.calc_damage(target): continue\n",
|
||||
" attackable.remove(target)\n",
|
||||
" targets[group] = target\n",
|
||||
" \n",
|
||||
" ok = False\n",
|
||||
" for group, target in sorted(targets.items(), key=lambda a: -a[0].init):\n",
|
||||
" if group.dead: continue\n",
|
||||
" if group.attack(target): ok = True\n",
|
||||
" \n",
|
||||
" if not ok:\n",
|
||||
" break\n",
|
||||
" \n",
|
||||
" immune, infect = [[g for g in x if not g.dead] for x in [immune, infect]]\n",
|
||||
" \n",
|
||||
" if infect: return None\n",
|
||||
" return sum(g.units for g in immune)\n",
|
||||
"\n",
|
||||
"def solve2():\n",
|
||||
" boost = 0\n",
|
||||
" while not (out := test(boost)): boost += 1\n",
|
||||
" return out\n",
|
||||
"\n",
|
||||
"solve2()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"3.63 s ± 289 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve2()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
128
Python/2018/24.py
Normal file
128
Python/2018/24.py
Normal file
|
@ -0,0 +1,128 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 24)
|
||||
|
||||
|
||||
@dataclass
|
||||
class Group:
|
||||
army: int
|
||||
units: int
|
||||
hp: int
|
||||
ap: int
|
||||
at: str
|
||||
init: int
|
||||
weak: set[str]
|
||||
immune: set[str]
|
||||
|
||||
def __hash__(self):
|
||||
return id(self)
|
||||
|
||||
@staticmethod
|
||||
def parse(army, line, boost=0):
|
||||
units, hp, _, extra, ap, at, init = re.match(
|
||||
r"^(\d+) units each with (\d+) hit points( \((.*)\))? with an attack that does (\d+) (\w+) damage at initiative (\d+)$",
|
||||
line,
|
||||
).groups()
|
||||
weak = set()
|
||||
immune = set()
|
||||
for part in extra.split("; ") if extra else []:
|
||||
t, _, *xs = part.split()
|
||||
{"weak": weak, "immune": immune}[t].update(x.strip(",") for x in xs)
|
||||
|
||||
return Group(army, int(units), int(hp), int(ap) + boost, at, int(init), weak, immune)
|
||||
|
||||
@property
|
||||
def ep(self):
|
||||
return self.units * self.ap
|
||||
|
||||
@property
|
||||
def dead(self):
|
||||
return self.units <= 0
|
||||
|
||||
def calc_damage(self, target):
|
||||
if self.at in target.immune:
|
||||
return 0
|
||||
mul = 2 if self.at in target.weak else 1
|
||||
return self.ep * mul
|
||||
|
||||
def attack(self, target):
|
||||
damage = self.calc_damage(target) // target.hp
|
||||
target.units -= damage
|
||||
return damage
|
||||
|
||||
|
||||
immune, infect = [
|
||||
[Group.parse(i, group) for group in army.splitlines()[1:]] for i, army in enumerate(input.split("\n\n"))
|
||||
]
|
||||
|
||||
while immune and infect:
|
||||
targets = {}
|
||||
imm_att = set(immune)
|
||||
inf_att = set(infect)
|
||||
for group in sorted(immune + infect, key=lambda g: (-g.ep, -g.init)):
|
||||
attackable = [inf_att, imm_att][group.army]
|
||||
if not attackable:
|
||||
continue
|
||||
|
||||
target = max(attackable, key=lambda g: (group.calc_damage(g), g.ep, g.init))
|
||||
if not group.calc_damage(target):
|
||||
continue
|
||||
|
||||
attackable.remove(target)
|
||||
targets[group] = target
|
||||
|
||||
for group, target in sorted(targets.items(), key=lambda a: -a[0].init):
|
||||
if group.dead:
|
||||
continue
|
||||
group.attack(target)
|
||||
|
||||
immune, infect = [[g for g in x if not g.dead] for x in [immune, infect]]
|
||||
|
||||
print(sum(g.units for g in immune + infect))
|
||||
|
||||
|
||||
def test(boost):
|
||||
immune, infect = [
|
||||
[Group.parse(i, group, boost if i == 0 else 0) for group in army.splitlines()[1:]]
|
||||
for i, army in enumerate(input.split("\n\n"))
|
||||
]
|
||||
|
||||
while immune and infect:
|
||||
targets = {}
|
||||
imm_att = set(immune)
|
||||
inf_att = set(infect)
|
||||
for group in sorted(immune + infect, key=lambda g: (-g.ep, -g.init)):
|
||||
attackable = [inf_att, imm_att][group.army]
|
||||
if not attackable:
|
||||
continue
|
||||
|
||||
target = max(attackable, key=lambda g: (group.calc_damage(g), g.ep, g.init))
|
||||
if not group.calc_damage(target):
|
||||
continue
|
||||
|
||||
attackable.remove(target)
|
||||
targets[group] = target
|
||||
|
||||
ok = False
|
||||
for group, target in sorted(targets.items(), key=lambda a: -a[0].init):
|
||||
if group.dead:
|
||||
continue
|
||||
|
||||
if group.attack(target):
|
||||
ok = True
|
||||
|
||||
if not ok:
|
||||
break
|
||||
|
||||
immune, infect = [[g for g in x if not g.dead] for x in [immune, infect]]
|
||||
|
||||
if infect:
|
||||
return None
|
||||
|
||||
return sum(g.units for g in immune)
|
||||
|
||||
|
||||
boost = 0
|
||||
while not (out := test(boost)):
|
||||
boost += 1
|
||||
print(out)
|
|
@ -1,121 +0,0 @@
|
|||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/markdown": [
|
||||
"# Day 25"
|
||||
],
|
||||
"text/plain": [
|
||||
"<IPython.core.display.Markdown object>"
|
||||
]
|
||||
},
|
||||
"metadata": {},
|
||||
"output_type": "display_data"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"import sys; sys.path.insert(0, \"..\")\n",
|
||||
"\n",
|
||||
"import aoc\n",
|
||||
"\n",
|
||||
"year, day = 2018, 25\n",
|
||||
"\n",
|
||||
"puzzle = aoc.setup(year, day)\n",
|
||||
"plines = puzzle.splitlines()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Puzzle 1"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/plain": [
|
||||
"394"
|
||||
]
|
||||
},
|
||||
"execution_count": 2,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"class UnionFind:\n",
|
||||
" def __init__(self, n):\n",
|
||||
" self.parents = list(range(n))\n",
|
||||
" \n",
|
||||
" def find(self, x):\n",
|
||||
" if self.parents[x] == x: return x\n",
|
||||
" self.parents[x] = self.find(self.parents[x])\n",
|
||||
" return self.parents[x]\n",
|
||||
" \n",
|
||||
" def merge(self, x, y):\n",
|
||||
" x = self.find(x)\n",
|
||||
" y = self.find(y)\n",
|
||||
" self.parents[x] = y\n",
|
||||
"\n",
|
||||
"def solve1():\n",
|
||||
" coords = [tuple(map(int, line.split(\",\"))) for line in plines]\n",
|
||||
" uf = UnionFind(len(coords))\n",
|
||||
" for i in range(len(coords)):\n",
|
||||
" for j in range(i+1, len(coords)):\n",
|
||||
" if sum(abs(a-b) for a, b in zip(coords[i], coords[j])) <= 3:\n",
|
||||
" uf.merge(i, j)\n",
|
||||
" return len(set(map(uf.find, range(len(coords)))))\n",
|
||||
" \n",
|
||||
"solve1()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"1.37 s ± 129 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"%timeit solve1()"
|
||||
]
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.9.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 4
|
||||
}
|
13
Python/2018/25.py
Normal file
13
Python/2018/25.py
Normal file
|
@ -0,0 +1,13 @@
|
|||
from lib import *
|
||||
|
||||
input = read_input(2018, 25)
|
||||
|
||||
|
||||
coords = [tuple(map(int, line.split(","))) for line in input.splitlines()]
|
||||
uf = UnionFind(len(coords))
|
||||
for i in range(len(coords)):
|
||||
for j in range(i + 1, len(coords)):
|
||||
if sum(abs(a - b) for a, b in zip(coords[i], coords[j])) <= 3:
|
||||
uf.merge(i, j)
|
||||
|
||||
print(len(set(map(uf.find, range(len(coords))))))
|
|
@ -20,15 +20,17 @@ import math
|
|||
import operator
|
||||
import re
|
||||
import statistics
|
||||
from collections import Counter
|
||||
from collections import Counter, deque
|
||||
from copy import deepcopy
|
||||
from dataclasses import dataclass
|
||||
from datetime import date, datetime, time, timedelta
|
||||
from functools import cache, partial, reduce
|
||||
from heapq import heapify, heappop, heappush
|
||||
from pathlib import Path
|
||||
|
||||
import numpy as np
|
||||
import pyperclip
|
||||
import z3
|
||||
|
||||
|
||||
def read_input(year: int, day: int) -> str:
|
||||
|
|
10
README.md
10
README.md
|
@ -41,11 +41,11 @@
|
|||
## [2018](https://adventofcode.com/2018) ([<img height=18 src=".assets/py.svg"> Python](Python/2018): 25/25)
|
||||
|Mo|Tu|We|Th|Fr|Sa|Su|
|
||||
|-|-|-|-|-|-|-|
|
||||
||||||[**1**](https://adventofcode.com/2018/day/1) [<img height=12 src=".assets/py.svg">](Python/2018/01 "Python solution for 2018/01")|[**2**](https://adventofcode.com/2018/day/2) [<img height=12 src=".assets/py.svg">](Python/2018/02 "Python solution for 2018/02")|
|
||||
|[**3**](https://adventofcode.com/2018/day/3) [<img height=12 src=".assets/py.svg">](Python/2018/03 "Python solution for 2018/03")|[**4**](https://adventofcode.com/2018/day/4) [<img height=12 src=".assets/py.svg">](Python/2018/04 "Python solution for 2018/04")|[**5**](https://adventofcode.com/2018/day/5) [<img height=12 src=".assets/py.svg">](Python/2018/05 "Python solution for 2018/05")|[**6**](https://adventofcode.com/2018/day/6) [<img height=12 src=".assets/py.svg">](Python/2018/06 "Python solution for 2018/06")|[**7**](https://adventofcode.com/2018/day/7) [<img height=12 src=".assets/py.svg">](Python/2018/07 "Python solution for 2018/07")|[**8**](https://adventofcode.com/2018/day/8) [<img height=12 src=".assets/py.svg">](Python/2018/08 "Python solution for 2018/08")|[**9**](https://adventofcode.com/2018/day/9) [<img height=12 src=".assets/py.svg">](Python/2018/09 "Python solution for 2018/09")|
|
||||
|[**10**](https://adventofcode.com/2018/day/10) [<img height=12 src=".assets/py.svg">](Python/2018/10 "Python solution for 2018/10")|[**11**](https://adventofcode.com/2018/day/11) [<img height=12 src=".assets/py.svg">](Python/2018/11.ipynb "Python solution for 2018/11")|[**12**](https://adventofcode.com/2018/day/12) [<img height=12 src=".assets/py.svg">](Python/2018/12.ipynb "Python solution for 2018/12")|[**13**](https://adventofcode.com/2018/day/13) [<img height=12 src=".assets/py.svg">](Python/2018/13.ipynb "Python solution for 2018/13")|[**14**](https://adventofcode.com/2018/day/14) [<img height=12 src=".assets/py.svg">](Python/2018/14.ipynb "Python solution for 2018/14")|[**15**](https://adventofcode.com/2018/day/15) [<img height=12 src=".assets/py.svg">](Python/2018/15.ipynb "Python solution for 2018/15")|[**16**](https://adventofcode.com/2018/day/16) [<img height=12 src=".assets/py.svg">](Python/2018/16.ipynb "Python solution for 2018/16")|
|
||||
|[**17**](https://adventofcode.com/2018/day/17) [<img height=12 src=".assets/py.svg">](Python/2018/17.ipynb "Python solution for 2018/17")|[**18**](https://adventofcode.com/2018/day/18) [<img height=12 src=".assets/py.svg">](Python/2018/18.ipynb "Python solution for 2018/18")|[**19**](https://adventofcode.com/2018/day/19) [<img height=12 src=".assets/py.svg">](Python/2018/19.ipynb "Python solution for 2018/19")|[**20**](https://adventofcode.com/2018/day/20) [<img height=12 src=".assets/py.svg">](Python/2018/20.ipynb "Python solution for 2018/20")|[**21**](https://adventofcode.com/2018/day/21) [<img height=12 src=".assets/py.svg">](Python/2018/21.ipynb "Python solution for 2018/21")|[**22**](https://adventofcode.com/2018/day/22) [<img height=12 src=".assets/py.svg">](Python/2018/22.ipynb "Python solution for 2018/22")|[**23**](https://adventofcode.com/2018/day/23) [<img height=12 src=".assets/py.svg">](Python/2018/23.ipynb "Python solution for 2018/23")|
|
||||
|[**24**](https://adventofcode.com/2018/day/24) [<img height=12 src=".assets/py.svg">](Python/2018/24.ipynb "Python solution for 2018/24")|[**25**](https://adventofcode.com/2018/day/25) [<img height=12 src=".assets/py.svg">](Python/2018/25.ipynb "Python solution for 2018/25")|26|27|28|29|30|
|
||||
||||||[**1**](https://adventofcode.com/2018/day/1) [<img height=12 src=".assets/py.svg">](Python/2018/01.py "Python solution for 2018/01")|[**2**](https://adventofcode.com/2018/day/2) [<img height=12 src=".assets/py.svg">](Python/2018/02.py "Python solution for 2018/02")|
|
||||
|[**3**](https://adventofcode.com/2018/day/3) [<img height=12 src=".assets/py.svg">](Python/2018/03.py "Python solution for 2018/03")|[**4**](https://adventofcode.com/2018/day/4) [<img height=12 src=".assets/py.svg">](Python/2018/04.py "Python solution for 2018/04")|[**5**](https://adventofcode.com/2018/day/5) [<img height=12 src=".assets/py.svg">](Python/2018/05.py "Python solution for 2018/05")|[**6**](https://adventofcode.com/2018/day/6) [<img height=12 src=".assets/py.svg">](Python/2018/06.py "Python solution for 2018/06")|[**7**](https://adventofcode.com/2018/day/7) [<img height=12 src=".assets/py.svg">](Python/2018/07.py "Python solution for 2018/07")|[**8**](https://adventofcode.com/2018/day/8) [<img height=12 src=".assets/py.svg">](Python/2018/08.py "Python solution for 2018/08")|[**9**](https://adventofcode.com/2018/day/9) [<img height=12 src=".assets/py.svg">](Python/2018/09.py "Python solution for 2018/09")|
|
||||
|[**10**](https://adventofcode.com/2018/day/10) [<img height=12 src=".assets/py.svg">](Python/2018/10.py "Python solution for 2018/10")|[**11**](https://adventofcode.com/2018/day/11) [<img height=12 src=".assets/py.svg">](Python/2018/11.py "Python solution for 2018/11")|[**12**](https://adventofcode.com/2018/day/12) [<img height=12 src=".assets/py.svg">](Python/2018/12.py "Python solution for 2018/12")|[**13**](https://adventofcode.com/2018/day/13) [<img height=12 src=".assets/py.svg">](Python/2018/13.py "Python solution for 2018/13")|[**14**](https://adventofcode.com/2018/day/14) [<img height=12 src=".assets/py.svg">](Python/2018/14.py "Python solution for 2018/14")|[**15**](https://adventofcode.com/2018/day/15) [<img height=12 src=".assets/py.svg">](Python/2018/15.py "Python solution for 2018/15")|[**16**](https://adventofcode.com/2018/day/16) [<img height=12 src=".assets/py.svg">](Python/2018/16.py "Python solution for 2018/16")|
|
||||
|[**17**](https://adventofcode.com/2018/day/17) [<img height=12 src=".assets/py.svg">](Python/2018/17.py "Python solution for 2018/17")|[**18**](https://adventofcode.com/2018/day/18) [<img height=12 src=".assets/py.svg">](Python/2018/18.py "Python solution for 2018/18")|[**19**](https://adventofcode.com/2018/day/19) [<img height=12 src=".assets/py.svg">](Python/2018/19.py "Python solution for 2018/19")|[**20**](https://adventofcode.com/2018/day/20) [<img height=12 src=".assets/py.svg">](Python/2018/20.py "Python solution for 2018/20")|[**21**](https://adventofcode.com/2018/day/21) [<img height=12 src=".assets/py.svg">](Python/2018/21.py "Python solution for 2018/21")|[**22**](https://adventofcode.com/2018/day/22) [<img height=12 src=".assets/py.svg">](Python/2018/22.py "Python solution for 2018/22")|[**23**](https://adventofcode.com/2018/day/23) [<img height=12 src=".assets/py.svg">](Python/2018/23.py "Python solution for 2018/23")|
|
||||
|[**24**](https://adventofcode.com/2018/day/24) [<img height=12 src=".assets/py.svg">](Python/2018/24.py "Python solution for 2018/24")|[**25**](https://adventofcode.com/2018/day/25) [<img height=12 src=".assets/py.svg">](Python/2018/25.py "Python solution for 2018/25")|26|27|28|29|30|
|
||||
|31|||||||
|
||||
|
||||
## [2017](https://adventofcode.com/2017) ([<img height=18 src=".assets/py.svg"> Python](Python/2017): 25/25)
|
||||
|
|
|
@ -54,6 +54,7 @@
|
|||
# Python
|
||||
(python311.withPackages (p:
|
||||
with p; [
|
||||
z3
|
||||
numpy
|
||||
pyperclip
|
||||
]))
|
||||
|
|
|
@ -3,7 +3,7 @@ from datetime import date
|
|||
from pathlib import Path
|
||||
|
||||
names = {"rs": "Rust", "hs": "Haskell", "py": "Python", "apl": "APL"}
|
||||
exts = {"rs": [".rs"], "hs": [".hs"], "py": [".py", ".ipynb", ""], "apl": [".apl"]}
|
||||
exts = {"rs": [".rs"], "hs": [".hs"], "py": [".py", ""], "apl": [".apl"]}
|
||||
|
||||
|
||||
def logo(lang, height=12):
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue