| @@ -105,7 +105,7 @@ def loop_consume(lines, handler): | |||
| if __name__ == '__main__': | |||
| data_file = Path(sys.argv[1]).with_suffix('.dat') | |||
| ensure_data(data_file) | |||
| builtins.data_file = data_file | |||
| builtins.df = data_file | |||
| builtins.string = string | |||
| builtins.re = re | |||
| rel = re.sub(r'.+(y\d+)/(p\d+).+', r'\1.\2', os.environ['FILE']) | |||
| @@ -0,0 +1,6 @@ | |||
| import json | |||
| lines = df.read_text().splitlines() | |||
| ans1 = sum(len(ln) - len(eval(ln)) for ln in lines) | |||
| ans2 = sum(len(json.dumps(ln)) - len(ln) for ln in lines) | |||
| @@ -0,0 +1,15 @@ | |||
| from itertools import permutations | |||
| places = set() | |||
| mapping = {} | |||
| for line in df.read_text().splitlines(): | |||
| A, _, B, _, val = line.split() | |||
| places.update({A, B}) | |||
| mapping[A, B] = mapping[B, A] = int(val) | |||
| length = lambda combo: sum(mapping[pair] for pair in zip(combo, combo[1:])) | |||
| lengths = [length(combo) for combo in permutations(places)] | |||
| ans1 = min(lengths) | |||
| ans2 = max(lengths) | |||
| @@ -0,0 +1,12 @@ | |||
| from itertools import groupby | |||
| def mod(string): | |||
| return ''.join(f'{len(list(vs))}{k}' for k, vs in groupby(string)) | |||
| inp = df.read_text().splitlines() | |||
| for _ in range(50): | |||
| inp.append(mod(inp[-1])) | |||
| ans1 = len(inp[40]) | |||
| ans2 = len(inp[50]) | |||
| @@ -0,0 +1,26 @@ | |||
| import itertools | |||
| az = string.ascii_lowercase | |||
| trip = re.compile('|'.join(''.join(abc) for abc in zip(az, az[1:], az[2:]))) | |||
| iol = re.compile(r'i|o|l') | |||
| dup = re.compile(r'(.)\1.*(.)\2') | |||
| def is_valid(code): | |||
| return trip.search(code) and not iol.search(code) and dup.search(code) | |||
| def as_int(S): | |||
| return sum((ord(c) - 97) % 26 * 26 ** i for i, c in enumerate(S[::-1])) | |||
| def as_str(N): | |||
| return ''.join(chr(N // 26 ** i % 26 + 97) for i in range(8))[::-1] | |||
| code, = df.read_text().splitlines() | |||
| n = as_int(code) | |||
| generator = filter(is_valid, (as_str(n + i) for i in itertools.count())) | |||
| ans1 = next(generator) | |||
| ans2 = next(generator) | |||
| @@ -0,0 +1,60 @@ | |||
| import collections | |||
| def program(qsnd, qrcv, known=tuple()): | |||
| i, j = 0, 0 | |||
| regs = collections.defaultdict(int) | |||
| regs.update(known) | |||
| read = lambda value: regs[value] if value.isalpha() else int(value) | |||
| while True: | |||
| line = lines[i] | |||
| op, *args = line.split() | |||
| if op == 'set': | |||
| x, y = args | |||
| regs[x] = read(y) | |||
| elif op == 'mul': | |||
| x, y = args | |||
| regs[x] *= read(y) | |||
| elif op == 'jgz': | |||
| x, y = args | |||
| if read(x) > 0: | |||
| i += read(y) | |||
| continue | |||
| elif op == 'add': | |||
| x, y = args | |||
| regs[x] += read(y) | |||
| elif op == 'snd': | |||
| x, = args | |||
| qsnd.append(read(x)) | |||
| elif op == 'rcv': | |||
| x, = args | |||
| if not known: | |||
| if read(x) != 0: | |||
| yield False | |||
| continue | |||
| else: | |||
| if j < len(qrcv): | |||
| regs[x] = qrcv[j] | |||
| j += 1 | |||
| else: | |||
| yield False | |||
| continue | |||
| elif op == 'mod': | |||
| x, y = args | |||
| regs[x] %= read(y) | |||
| i += 1 | |||
| yield True | |||
| lines = df.read_text().splitlines() | |||
| q = [] | |||
| p = program(q, None) | |||
| while next(p): pass | |||
| ans1 = q[-1] | |||
| qA, qB = [], [] | |||
| p0 = program(qA, qB, {'p': 0}) | |||
| p1 = program(qB, qA, {'p': 1}) | |||
| while next(p0) + next(p1): pass | |||
| ans2 = len(qB) | |||