| @@ -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)) | |||