Add days 10, 12, 13 and 14

This commit is contained in:
Sijmen 2018-12-15 13:25:13 +01:00
parent d85b305f87
commit 2fc461d579
5 changed files with 346 additions and 0 deletions

77
Day10/Day10A.py Normal file
View 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
View 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
View 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
View 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
View 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