| *.dat | |||||
| __pycache__/ | |||||
| .DS_Store | |||||
| venv/ |
| FILE = $(shell find . -name p??.py -type f | xargs ls -rt | tail -n 1) | |||||
| DATA = $(shell echo $(FILE) | sed -e s/\.py/\.dat/) | |||||
| PYTHONPATH=. | |||||
| main: venv/ | |||||
| @touch $(DATA) | |||||
| @cat $(DATA) | venv/bin/python -u $(FILE) | |||||
| venv/: requirements.txt | |||||
| rm -rf venv/ | |||||
| python3 -m venv venv | |||||
| venv/bin/pip install -r requirements.txt | |||||
| touch requirements.txt venv/ |
| pypng | |||||
| numpy | |||||
| scipy | |||||
| scikit-image |
| import collections | |||||
| import re | |||||
| from pathlib import Path | |||||
| def read_in(): | |||||
| grid = collections.defaultdict(lambda: ' ') | |||||
| for _ in Path('y2018/p17.dat').read_text().splitlines(): | |||||
| _ = _.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}) | |||||
| return grid | |||||
| def write_out(grid, path): | |||||
| text = '\n'.join( | |||||
| ''.join(grid[x, y] for x in range(xmin - 5, xmax + 5)) | |||||
| for y in range(ymin, ymax + 1) | |||||
| ) | |||||
| Path(path).write_text(text) | |||||
| def flow(start): | |||||
| stack = [start] | |||||
| while stack: | |||||
| x, y = stack.pop() | |||||
| grid[x, y] = '~' | |||||
| if y > ymax: | |||||
| break | |||||
| for dx, dy in [(1, 0), (-1, 0), (0, 1)]: | |||||
| new = x + dx, y + dy | |||||
| if dy == 1 and grid[new] == '|': | |||||
| stack.clear() | |||||
| break | |||||
| if grid[new] == ' ': | |||||
| stack.append(new) | |||||
| drain((x, y)) | |||||
| def drain(end): | |||||
| stack = [end] | |||||
| while stack: | |||||
| x, y = stack.pop() | |||||
| grid[x, y] = '|' | |||||
| if grid[x - 1, y] == '|' and grid[x + 1, y] == ' ' and grid[x, y + 1] != '|': | |||||
| flow((x + 1, y)) | |||||
| for dx, dy in [(-1, 0), (1, 0), (0, -1)]: | |||||
| new = x + dx, y + dy | |||||
| if grid[new] == '~': | |||||
| stack.append(new) | |||||
| grid = read_in() | |||||
| xmin, *_, xmax = sorted(x for x, y in grid) | |||||
| ymin, *_, ymax = sorted(y for x, y in grid) | |||||
| flow((500, 0)) | |||||
| counter = collections.Counter(grid.values()) | |||||
| print(counter['~'] + counter['|']) | |||||
| print(counter['~']) | |||||
| write_out(grid, 'y2018/p17out.dat') |
| import re | |||||
| def parse(string): | |||||
| return [int(n) for n in re.findall(r'-?\d+', string)] | |||||
| def get_parameters(ns, pos, modes, N, writes): | |||||
| for c in writes: | |||||
| # paradox: return immediate mode to use positionally outside | |||||
| modes[ord(c) - ord('a')] = '1' | |||||
| for mode, x in zip(modes, ns[pos:][:N]): | |||||
| yield { | |||||
| '0': lambda: ns[x], | |||||
| '1': lambda: x, | |||||
| }[mode]() | |||||
| yield pos + N | |||||
| def compute(ns, inp): | |||||
| if isinstance(ns, str): | |||||
| ns = parse(ns) | |||||
| pos = 0 | |||||
| consume = lambda n, writes='': get_parameters(ns, pos, modes, n, writes) | |||||
| while True: | |||||
| op = ns[pos] % 100 | |||||
| # instructions stupidly say ABC referring to parameters 3, 2, 1 | |||||
| # we do a, b, c | |||||
| modes = list(str(ns[pos] // 100).zfill(3)[::-1]) | |||||
| pos += 1 | |||||
| if op == 1: | |||||
| a, b, c, pos = consume(3, 'c') | |||||
| ns[c] = a + b | |||||
| elif op == 2: | |||||
| a, b, c, pos = consume(3, 'c') | |||||
| ns[c] = a * b | |||||
| elif op == 3: | |||||
| a, pos = consume(1, 'a') | |||||
| ns[a] = inp | |||||
| elif op == 4: | |||||
| a, pos = consume(1) | |||||
| yield a | |||||
| elif op == 5: | |||||
| a, b, pos = consume(2) | |||||
| if a != 0: | |||||
| pos = b | |||||
| elif op == 6: | |||||
| a, b, pos = consume(2) | |||||
| if a == 0: | |||||
| pos = b | |||||
| elif op == 7: | |||||
| a, b, c, pos = consume(3, 'c') | |||||
| ns[c] = int(a < b) | |||||
| elif op == 8: | |||||
| a, b, c, pos = consume(3, 'c') | |||||
| ns[c] = int(a == b) | |||||
| elif op == 99: | |||||
| return | |||||
| else: | |||||
| raise RuntimeError(op) |
| import sys | |||||
| text = sys.stdin.read() | |||||
| ns = [int(s) for s in text.splitlines()] | |||||
| def handle(n): | |||||
| m = n // 3 - 2 | |||||
| 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)) |
| import itertools | |||||
| import re | |||||
| import sys | |||||
| from intcode import compute, parse | |||||
| def check(noun, verb): | |||||
| ns = parse(text) | |||||
| ns[1:3] = [noun, verb] | |||||
| list(compute(ns, 2)) | |||||
| return ns[0] | |||||
| text = sys.stdin.read() | |||||
| print(check(12, 2)) | |||||
| for noun, verb in itertools.product(range(100), repeat=2): | |||||
| if check(noun, verb) == 19690720: | |||||
| print(100 * noun + verb) |
| import sys | |||||
| text = sys.stdin.read() | |||||
| maps = {'R': -1, 'D': -1j, 'L': 1, 'U': 1j} | |||||
| info = [] | |||||
| for path in text.splitlines(): | |||||
| i, p = 0, 0 | |||||
| best = {} | |||||
| for a, *n in path.split(','): | |||||
| d = maps[a] | |||||
| for _ in range(int(''.join(n))): | |||||
| i += 1 | |||||
| p += d | |||||
| if p not in best: | |||||
| best[p] = i | |||||
| info.append(best) | |||||
| isect = set(info[0]) & set(info[1]) | |||||
| print(int(min((abs(p.real) + abs(p.imag), p) for p in isect)[0])) | |||||
| print(min(info[0][p] + info[1][p] for p in isect)) |
| import sys | |||||
| import itertools | |||||
| strings = [str(n) for n in range(347312, 805915 + 1)] | |||||
| print(sum(list(s) == sorted(s) and any(len(list(vs)) >= 2 for k, vs in itertools.groupby(s)) for s in strings)) | |||||
| print(sum(list(s) == sorted(s) and any(len(list(vs)) == 2 for k, vs in itertools.groupby(s)) for s in strings)) |
| import sys | |||||
| from intcode import compute, parse | |||||
| tests = [ | |||||
| ('3,0,4,0,99', [(12421, 12421)]), | |||||
| ('3,9,8,9,10,9,4,9,99,-1,8', [(8, 1), (7, 0)]), | |||||
| ('3,9,7,9,10,9,4,9,99,-1,8', [(7, 1), (8, 0), (9, 0)]), | |||||
| ('3,12,6,12,15,1,13,14,13,4,13,99,-1,0,1,9', [(0, 0), (213, 1)]), | |||||
| ('3,3,1105,-1,9,1101,0,0,12,4,12,99,1', [(0, 0), (213, 1)]), | |||||
| (''' | |||||
| 3,21,1008,21,8,20,1005,20,22,107,8,21,20,1006,20,31, | |||||
| 1106,0,36,98,0,0,1002,21,125,20,4,20,1105,1,46,104, | |||||
| 999,1105,1,46,1101,1000,1,20,4,20,1105,1,46,98,99 | |||||
| ''', [(7, 999), (8, 1000), (9, 1001)]), | |||||
| ] | |||||
| for program, pairs in tests: | |||||
| for inp, expect in pairs: | |||||
| out = list(compute(program, inp))[-1] | |||||
| assert out == expect, (out, expect) | |||||
| text = sys.stdin.read() | |||||
| print(list(compute(text, 1))[-1]) | |||||
| print(list(compute(text, 5))[-1]) |