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