Add days 10, 12, 13 and 14
This commit is contained in:
parent
d85b305f87
commit
2fc461d579
5 changed files with 346 additions and 0 deletions
77
Day10/Day10A.py
Normal file
77
Day10/Day10A.py
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
import numpy
|
||||||
|
import fileinput
|
||||||
|
import re
|
||||||
|
|
||||||
|
class Star:
|
||||||
|
def __init__(self, sx, sy, vx, vy):
|
||||||
|
self.sx = sx
|
||||||
|
self.sy = sy
|
||||||
|
self.vx = vx
|
||||||
|
self.vy = vy
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f"pos: ({self.sx:>2d}, {self.sy:>2d}), vel: ({self.vx:>2d}, {self.vy:>2d})"
|
||||||
|
|
||||||
|
def step(self):
|
||||||
|
self.sx += self.vx
|
||||||
|
self.sy += self.vy
|
||||||
|
|
||||||
|
def step_back(self):
|
||||||
|
self.sx -= self.vx
|
||||||
|
self.sy -= self.vy
|
||||||
|
|
||||||
|
last_stars = []
|
||||||
|
stars = []
|
||||||
|
|
||||||
|
sxs = []
|
||||||
|
sys = []
|
||||||
|
vxs = []
|
||||||
|
vys = []
|
||||||
|
count = 0
|
||||||
|
|
||||||
|
RE = re.compile("^position=< ?([\d\-]+), ?([\d\-]+)> velocity=< ?([\d\-]+), ?([\d\-]+)>$")
|
||||||
|
for line in fileinput.input():
|
||||||
|
match = RE.match(line)
|
||||||
|
sxs.append(int(match.group(1)))
|
||||||
|
sys.append(int(match.group(2)))
|
||||||
|
vxs.append(int(match.group(3)))
|
||||||
|
vys.append(int(match.group(4)))
|
||||||
|
count += 1
|
||||||
|
|
||||||
|
sxs = numpy.array(sxs)
|
||||||
|
sys = numpy.array(sys)
|
||||||
|
vxs = numpy.array(vxs)
|
||||||
|
vys = numpy.array(vys)
|
||||||
|
|
||||||
|
last_dy = 10000000000
|
||||||
|
steps = 0
|
||||||
|
while True:
|
||||||
|
# get the min-y and max-y
|
||||||
|
min_y = sys.min()
|
||||||
|
delta_y = sys.max() - min_y
|
||||||
|
|
||||||
|
if delta_y > last_dy:
|
||||||
|
sxs -= vxs
|
||||||
|
sys -= vys
|
||||||
|
|
||||||
|
min_x = sxs.min()
|
||||||
|
delta_x = sxs.max() - min_x
|
||||||
|
|
||||||
|
grid = numpy.zeros((delta_y + 1, delta_x + 1))
|
||||||
|
grid[sys - min_y, sxs - min_x] = 1
|
||||||
|
|
||||||
|
for y in range(delta_y + 1):
|
||||||
|
for x in range(delta_x + 1):
|
||||||
|
print('#' if grid[y][x] else '.', end='')
|
||||||
|
|
||||||
|
print()
|
||||||
|
|
||||||
|
print(steps - 1)
|
||||||
|
break
|
||||||
|
|
||||||
|
last_dy = delta_y
|
||||||
|
|
||||||
|
sxs += vxs
|
||||||
|
sys += vys
|
||||||
|
|
||||||
|
steps += 1
|
41
Day12/Day12A.py
Normal file
41
Day12/Day12A.py
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
import fileinput
|
||||||
|
import numpy
|
||||||
|
from matplotlib import pyplot
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
|
PADDING = (16, 256)
|
||||||
|
SIM_GENS = 150
|
||||||
|
EXTRAPOLATE_GENS = -SIM_GENS + 50000000000
|
||||||
|
|
||||||
|
def convert(line):
|
||||||
|
return numpy.array([True if x == "#" else False for x in line])
|
||||||
|
|
||||||
|
inp = fileinput.input()
|
||||||
|
|
||||||
|
# Read the initial state
|
||||||
|
pots = convert(next(inp).split()[-1])
|
||||||
|
next(inp)
|
||||||
|
|
||||||
|
rules = {}
|
||||||
|
for line in inp:
|
||||||
|
x, y = [convert(s) for s in line.split(" => ")]
|
||||||
|
rules[tuple(x)] = y[0]
|
||||||
|
|
||||||
|
output = numpy.zeros((SIM_GENS + 1, len(pots) + PADDING[0] + PADDING[1]), dtype=bool)
|
||||||
|
output[0] = numpy.pad(pots, (PADDING[0], PADDING[1]), "constant")
|
||||||
|
|
||||||
|
for y in range(SIM_GENS):
|
||||||
|
for i in range(output.shape[1] - 2):
|
||||||
|
key = tuple(output[y, i:i+5])
|
||||||
|
output[y + 1][i + 2] = rules.get(key, 0)
|
||||||
|
|
||||||
|
numbers = numpy.arange(-PADDING[0], pots.shape[0] + PADDING[1])
|
||||||
|
|
||||||
|
sum_a = numbers[output[-2]].sum()
|
||||||
|
sum_b = numbers[output[-1]].sum()
|
||||||
|
delta = sum_b - sum_a
|
||||||
|
print(EXTRAPOLATE_GENS * delta + sum_b)
|
||||||
|
|
||||||
|
pyplot.gray()
|
||||||
|
pyplot.imshow(1 - output)
|
||||||
|
pyplot.show()
|
139
Day13/Day13A.py
Normal file
139
Day13/Day13A.py
Normal file
|
@ -0,0 +1,139 @@
|
||||||
|
import fileinput
|
||||||
|
import numpy
|
||||||
|
|
||||||
|
DIRS = ["^", ">", "v", "<"]
|
||||||
|
NORTH = 0
|
||||||
|
EAST = 1
|
||||||
|
SOUTH = 2
|
||||||
|
WEST = 3
|
||||||
|
|
||||||
|
TURN_LEFT = 0
|
||||||
|
TURN_STRAIGHT = 1
|
||||||
|
TURN_RIGHT = 2
|
||||||
|
|
||||||
|
carts = 0
|
||||||
|
cart_pos = []
|
||||||
|
cart_dirs = []
|
||||||
|
cart_turns = []
|
||||||
|
|
||||||
|
def get_cart(x, y):
|
||||||
|
try:
|
||||||
|
pos = cart_pos.index((x, y))
|
||||||
|
return pos
|
||||||
|
except ValueError:
|
||||||
|
raise IndexError
|
||||||
|
|
||||||
|
def move_cart(cart, dx, dy):
|
||||||
|
x, y = cart_pos[cart]
|
||||||
|
cart_pos[cart] = (x + dx, y + dy)
|
||||||
|
|
||||||
|
def remove_cart(cart):
|
||||||
|
global carts
|
||||||
|
carts -= 1
|
||||||
|
|
||||||
|
cart_pos.pop(cart)
|
||||||
|
cart_dirs.pop(cart)
|
||||||
|
cart_turns.pop(cart)
|
||||||
|
|
||||||
|
def add_cart(x, y, dir_, turn=TURN_LEFT):
|
||||||
|
global carts
|
||||||
|
carts += 1
|
||||||
|
|
||||||
|
cart_pos.append((x, y))
|
||||||
|
cart_dirs.append(dir_)
|
||||||
|
cart_turns.append(turn)
|
||||||
|
|
||||||
|
def print_field(field):
|
||||||
|
for y, row in enumerate(field):
|
||||||
|
for x, value in enumerate(row.decode("ascii")):
|
||||||
|
try:
|
||||||
|
cart = get_cart(x, y)
|
||||||
|
print("\033[31;1;4m" + DIRS[cart_dirs[cart]], end="\033[0m")
|
||||||
|
if value == '-':
|
||||||
|
print("\u0335", end="")
|
||||||
|
elif value == '|':
|
||||||
|
print("\u20D2", end="")
|
||||||
|
except IndexError:
|
||||||
|
print(value, end="")
|
||||||
|
print()
|
||||||
|
|
||||||
|
print()
|
||||||
|
for cart in range(carts):
|
||||||
|
x, y = cart_pos[cart]
|
||||||
|
dir_ = DIRS[cart_dirs[cart]]
|
||||||
|
turn = cart_turns[cart]
|
||||||
|
print(f"- ({x:>3d}, {y:>3d}) {dir_} {turn}")
|
||||||
|
print()
|
||||||
|
|
||||||
|
inp = []
|
||||||
|
for y, line in enumerate(fileinput.input()):
|
||||||
|
row = []
|
||||||
|
for x, value in enumerate(line.rstrip("\n")):
|
||||||
|
if value == "^": add_cart(x, y, NORTH); row.append("|")
|
||||||
|
elif value == ">": add_cart(x, y, EAST); row.append("-")
|
||||||
|
elif value == "v": add_cart(x, y, SOUTH); row.append("|")
|
||||||
|
elif value == "<": add_cart(x, y, WEST); row.append("-")
|
||||||
|
else:
|
||||||
|
row.append(value)
|
||||||
|
|
||||||
|
inp.append(row)
|
||||||
|
|
||||||
|
field = numpy.chararray((len(inp), len(inp[0])))
|
||||||
|
field[:] = inp
|
||||||
|
|
||||||
|
one_more = False
|
||||||
|
def step():
|
||||||
|
# Move the carts
|
||||||
|
order = sorted(range(carts), key=lambda cart: cart_pos[cart], reverse=True)
|
||||||
|
while order:
|
||||||
|
cart = order.pop()
|
||||||
|
if cart_dirs[cart] == NORTH: move_cart(cart, 0, -1)
|
||||||
|
elif cart_dirs[cart] == EAST: move_cart(cart, 1, 0)
|
||||||
|
elif cart_dirs[cart] == SOUTH: move_cart(cart, 0, 1)
|
||||||
|
elif cart_dirs[cart] == WEST: move_cart(cart, -1, 0)
|
||||||
|
|
||||||
|
value = field[cart_pos[cart][::-1]]
|
||||||
|
if value == b"+":
|
||||||
|
cart_dirs[cart] += cart_turns[cart] - 1
|
||||||
|
cart_dirs[cart] %= 4
|
||||||
|
cart_turns[cart] = (cart_turns[cart] + 1) % 3
|
||||||
|
elif value == b"/":
|
||||||
|
if cart_dirs[cart] in (NORTH, SOUTH):
|
||||||
|
cart_dirs[cart] = (cart_dirs[cart] + 1) % 4
|
||||||
|
else:
|
||||||
|
cart_dirs[cart] = (cart_dirs[cart] - 1) % 4
|
||||||
|
elif value == b"\\":
|
||||||
|
if cart_dirs[cart] in (EAST, WEST):
|
||||||
|
cart_dirs[cart] = (cart_dirs[cart] + 1) % 4
|
||||||
|
else:
|
||||||
|
cart_dirs[cart] = (cart_dirs[cart] - 1) % 4
|
||||||
|
elif value not in (b"-", b"|"):
|
||||||
|
raise ValueError(value)
|
||||||
|
|
||||||
|
u, c = numpy.unique(cart_pos, axis=0, return_counts=True)
|
||||||
|
if len(u[c > 1]):
|
||||||
|
for pos in u[c > 1]:
|
||||||
|
print("crash at", pos)
|
||||||
|
print(order)
|
||||||
|
|
||||||
|
cart = get_cart(*pos)
|
||||||
|
order = [x if x < cart else x - 1 for x in order if x != cart]
|
||||||
|
remove_cart(cart)
|
||||||
|
|
||||||
|
cart = get_cart(*pos)
|
||||||
|
order = [x if x < cart else x - 1 for x in order if x != cart]
|
||||||
|
remove_cart(cart)
|
||||||
|
print(order)
|
||||||
|
|
||||||
|
if carts == 1:
|
||||||
|
print(cart_pos[0])
|
||||||
|
return False
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
print_field(field)
|
||||||
|
|
||||||
|
while step():
|
||||||
|
pass
|
||||||
|
|
44
Day14/Day14A.py
Normal file
44
Day14/Day14A.py
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
from sys import argv, exit
|
||||||
|
|
||||||
|
try:
|
||||||
|
input_ = int(argv[1])
|
||||||
|
except IndexError:
|
||||||
|
print(f"Usage: {argv[0]} [input]")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
recipes = [3, 7]
|
||||||
|
a, b = 0, 1
|
||||||
|
|
||||||
|
def print_recipes():
|
||||||
|
for i, recipe in enumerate(recipes):
|
||||||
|
if i == a:
|
||||||
|
print(f"({recipe:>2d})", end=" ")
|
||||||
|
elif i == b:
|
||||||
|
print(f"[{recipe:>2d}]", end=" ")
|
||||||
|
else:
|
||||||
|
print(f" {recipe:>2d} ", end=" ")
|
||||||
|
print()
|
||||||
|
|
||||||
|
target = None
|
||||||
|
i = 0
|
||||||
|
while len(recipes) < input_ + 10:
|
||||||
|
# print_recipes()
|
||||||
|
next_ = recipes[a] + recipes[b]
|
||||||
|
|
||||||
|
digits = []
|
||||||
|
if next_ == 0:
|
||||||
|
digits.append(0)
|
||||||
|
else:
|
||||||
|
while next_:
|
||||||
|
digits.append(next_ % 10)
|
||||||
|
next_ //= 10
|
||||||
|
|
||||||
|
recipes.extend(digits[::-1])
|
||||||
|
|
||||||
|
a = (a + recipes[a] + 1) % len(recipes)
|
||||||
|
b = (b + recipes[b] + 1) % len(recipes)
|
||||||
|
|
||||||
|
# print_recipes()
|
||||||
|
output = recipes[input_:input_ + 10]
|
||||||
|
assert len(output) == 10
|
||||||
|
print("".join(str(x) for x in output))
|
45
Day14/Day14B.py
Normal file
45
Day14/Day14B.py
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
from sys import argv, exit
|
||||||
|
from tqdm import tqdm
|
||||||
|
from itertools import count
|
||||||
|
|
||||||
|
try:
|
||||||
|
input_ = bytes([int(x) for x in argv[1]])
|
||||||
|
l = len(input_)
|
||||||
|
except IndexError:
|
||||||
|
print(f"Usage: {argv[0]} [input]")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
recipes = bytearray([3, 7])
|
||||||
|
a, b = 0, 1
|
||||||
|
|
||||||
|
|
||||||
|
def print_recipes():
|
||||||
|
for i, recipe in enumerate(recipes):
|
||||||
|
if i == a:
|
||||||
|
print(f"({recipe:>2d})", end=" ")
|
||||||
|
elif i == b:
|
||||||
|
print(f"[{recipe:>2d}]", end=" ")
|
||||||
|
else:
|
||||||
|
print(f" {recipe:>2d} ", end=" ")
|
||||||
|
print()
|
||||||
|
|
||||||
|
|
||||||
|
for _ in tqdm(count()):
|
||||||
|
next_ = recipes[a] + recipes[b]
|
||||||
|
|
||||||
|
digits = bytearray([])
|
||||||
|
if next_ == 0:
|
||||||
|
digits.append(0)
|
||||||
|
else:
|
||||||
|
while next_:
|
||||||
|
digits.append(next_ % 10)
|
||||||
|
next_ //= 10
|
||||||
|
|
||||||
|
recipes.extend(digits[::-1])
|
||||||
|
|
||||||
|
a = (a + recipes[a] + 1) % len(recipes)
|
||||||
|
b = (b + recipes[b] + 1) % len(recipes)
|
||||||
|
|
||||||
|
if recipes[-l - 2:-2] == input_ or recipes[-l - 1:-1] == input_:
|
||||||
|
print(recipes.find(input_))
|
||||||
|
break
|
Loading…
Reference in a new issue