@@ -1,6 +1,7 @@ | |||
FILE = $(shell find . -name p??.py -type f | xargs ls -rt | tail -n 1) | |||
FILE = $(shell find . -path "./y????/p??.py" -type f | xargs ls -rt | tail -n 1) | |||
DATA = $(shell echo $(FILE) | sed -e s/\.py/\.dat/) | |||
PYTHONPATH=. | |||
PYTHONPATH = . | |||
export | |||
main: venv/ | |||
@touch $(DATA) |
@@ -0,0 +1,12 @@ | |||
def render(grid, brush): | |||
if isinstance(brush, str): | |||
brush = {i: c for i, c in enumerate(brush)} | |||
xmin, *_, xmax = sorted(int(p.real) for p in grid) | |||
ymin, *_, ymax = sorted(int(p.imag) for p in grid) | |||
brush[None] = ' ' | |||
rendered = '' | |||
for y in range(ymin, ymax + 1): | |||
for x in range(xmin, xmax + 1): | |||
rendered += brush[grid.get(complex(x, y))] | |||
rendered += '\n' | |||
return rendered |
@@ -9,22 +9,12 @@ def read_in(): | |||
_ = _.replace(',', ';') | |||
_ = re.sub(r'(\d+)\.\.(\d+)', r'range(\1, \2 + 1)', _) | |||
_ = re.sub(r'=(\d+)', r'=[\1]', _) | |||
exec(_, globals()) | |||
grid.update({(X, Y): '#' for X in x for Y in y}) # noqa | |||
temp = {} | |||
exec(_, temp) | |||
grid.update({(X, Y): '#' for X in temp['x'] for Y in temp['y']}) | |||
return grid | |||
def write_out(grid, path): | |||
xmin, *_, xmax = sorted(x for x, y in grid) | |||
ymin, *_, ymax = sorted(y for x, y in grid) | |||
text = '\n'.join( | |||
''.join(grid[x, y] for x in range(xmin - 5, xmax + 5)) | |||
for y in range(ymin, ymax + 1) | |||
) | |||
with open('p17out.dat', 'w') as fp: | |||
fp.write(text) | |||
def flow(grid, start, ymax): | |||
stack = [start] | |||
while stack: | |||
@@ -68,4 +58,3 @@ flow(grid, (500, ymin), ymax) | |||
counter = collections.Counter(grid.values()) | |||
print(counter['~'] + counter['|']) | |||
print(counter['~']) | |||
write_out(grid, 'y2018/p17out.dat') |
@@ -10,6 +10,5 @@ def handle(n): | |||
return [m] + handle(m) if m > 0 else [] | |||
if __name__ == '__main__': | |||
print(sum(handle(n)[0] for n in ns)) | |||
print(sum(sum(handle(n)) for n in ns)) | |||
print(sum(handle(n)[0] for n in ns)) | |||
print(sum(sum(handle(n)) for n in ns)) |
@@ -1,5 +1,7 @@ | |||
import sys | |||
from toolkit import render | |||
w, h = 25, 6 | |||
text = sys.stdin.read() | |||
@@ -10,5 +12,6 @@ layers = list(zip(*[(int(n) for n in text.strip())] * w * h)) | |||
min_layer = min(layers, key=count(0)) | |||
print(count(1)(min_layer) * count(2)(min_layer)) | |||
px = (' #'[next(n for n in stack if n != 2)] for stack in zip(*layers)) | |||
print('\n'.join(''.join(next(px) for _ in range(w)) for _ in range(h))) | |||
px = (next(n for n in stack if n != 2) for stack in zip(*layers)) | |||
grid = {complex(x, y): next(px) for y in range(h) for x in range(w)} | |||
print(render(grid, ' #')) |
@@ -3,6 +3,8 @@ import sys | |||
from intcode import compute | |||
from toolkit import render | |||
def get_panels(ns, start): | |||
feedback = [start] | |||
@@ -19,15 +21,6 @@ def get_panels(ns, start): | |||
return panels | |||
def visualize(panels, brush): | |||
xmin, *_, xmax = sorted(int(p.real) for p in panels) | |||
ymin, *_, ymax = sorted(int(p.imag) for p in panels) | |||
for y in range(ymin, ymax + 1): | |||
for x in range(xmin, xmax + 1): | |||
print(brush[panels[complex(x, y)]], end='') | |||
print() | |||
text = sys.stdin.read() | |||
print(len(get_panels(text, 0))) | |||
visualize(get_panels(text, 1), brush=' #') | |||
print(render(get_panels(text, 1), brush=' #')) |
@@ -1,7 +1,7 @@ | |||
import collections | |||
import sys | |||
from intcode import compute | |||
from intcode import compute, parse | |||
def arkanoid(text): | |||
@@ -31,5 +31,7 @@ text = sys.stdin.read() | |||
grid, _ = arkanoid(text) | |||
print(collections.Counter(grid.values())[2]) | |||
_, score = arkanoid('2' + text[1:]) | |||
ns = parse(text) | |||
ns[0] = 2 | |||
_, score = arkanoid(ns) | |||
print(score) |
@@ -5,29 +5,29 @@ import sys | |||
text = sys.stdin.read() | |||
to_get = {} | |||
cookbook = {} | |||
for line in text.strip().splitlines(): | |||
for i, (qty, name) in enumerate(re.findall(r'(\d+) ([A-Z]+)', line)[::-1]): | |||
if i == 0: | |||
output = name | |||
to_get[output] = {output: -int(qty)} | |||
cookbook[output] = {output: -int(qty)} | |||
else: | |||
to_get[output][name] = int(qty) | |||
cookbook[output][name] = int(qty) | |||
def fuel_to_ore(wanted): | |||
required = collections.Counter({'FUEL': wanted}) | |||
pending = required.copy() | |||
def fuel_to_ore(state): | |||
state = collections.Counter(state) | |||
pending = state.copy() | |||
while pending: | |||
pending = {k: v for k, v in required.items() if k != 'ORE' and v > 0} | |||
pending = {k: v for k, v in state.items() if k in cookbook and v > 0} | |||
for out, out_qty in pending.items(): | |||
min_qty = -to_get[out][out] | |||
min_qty = -cookbook[out][out] | |||
n_times = math.ceil(out_qty / min_qty) | |||
required.update({k: v * n_times for k, v in to_get[out].items()}) | |||
return required['ORE'] | |||
state.update({k: v * n_times for k, v in cookbook[out].items()}) | |||
return state | |||
print(fuel_to_ore(1)) | |||
print(fuel_to_ore({'FUEL': 1})['ORE']) | |||
def bsearch(fn, goal, lo, hi): | |||
@@ -46,4 +46,4 @@ def bsearch(fn, goal, lo, hi): | |||
return lo | |||
print(bsearch(fuel_to_ore, 1E12, 1, 10_000_000)) | |||
print(bsearch(lambda n: fuel_to_ore({'FUEL': n})['ORE'], 1E12, 1, 10_000_000)) |