@@ -0,0 +1,4 @@ | |||
*.dat | |||
__pycache__/ | |||
.DS_Store | |||
venv/ |
@@ -0,0 +1,13 @@ | |||
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/ |
@@ -0,0 +1,4 @@ | |||
pypng | |||
numpy | |||
scipy | |||
scikit-image |
@@ -0,0 +1,68 @@ | |||
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') |
@@ -0,0 +1,74 @@ | |||
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) |
@@ -0,0 +1,15 @@ | |||
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)) |
@@ -0,0 +1,18 @@ | |||
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) |
@@ -0,0 +1,24 @@ | |||
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)) |
@@ -0,0 +1,6 @@ | |||
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)) |
@@ -0,0 +1,27 @@ | |||
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]) |