from aoc.input import get_input import copy import itertools import time import collections import re from aoc.partselector import part_one, part_two import functools def pw(line): return line.strip() def p1(): inp = get_input(pw) rules_tmp = [x.split(': ') for x in inp[0:20]] my = inp[22].split(',') nearby = [list(map(int, x.split(','))) for x in inp[25:]] rules = {} for r in rules_tmp: rules[r[0]] = list(map(lambda x: list(map(int, x.split('-'))), r[1].split(' or '))) print(rules) count = 0 for n in nearby: valid = True for field in n: fvalid = [] for r in rules.values(): tvalid = [] for rr in r: tvalid.append(field > rr[0] and field < rr[1]) fvalid.append(any(tvalid)) if not any(fvalid): count += field pass print(count) return inp def p2(): inp = get_input(pw) rules_tmp = [x.split(': ') for x in inp[0:20]] my = list(map(int, inp[22].split(','))) nearby = [list(map(int, x.split(','))) for x in inp[25:]] rules = {} for r in rules_tmp: rules[r[0]] = list(map(lambda x: list(map(int, x.split('-'))), r[1].split(' or '))) print(rules) count = 0 vtickets = [] print(len(nearby)) for n in nearby: valid = [] for field in n: fvalid = [] for r in rules.values(): tvalid = [] for rr in r: tvalid.append(field >= rr[0] and field <= rr[1]) fvalid.append(any(tvalid)) valid.append(any(fvalid)) if all(valid): vtickets.append(n) print(len(vtickets)) print(my) vtickets.append(my) fields = collections.defaultdict(list) for name, r in rules.items(): for i in range(len(my)): rvalid = [] for n in vtickets: field = n[i] tvalid = [] for rr in r: tvalid.append(field >= rr[0] and field <= rr[1]) rvalid.append(any(tvalid)) if all(rvalid): fields[i].append(name) print(i, name) newfields = copy.copy(fields) print('------') realfields = {} for i in range(len(fields)): i, f = sorted(newfields.items(), key=lambda x: len(x[1]), reverse=False)[0] v = f[0] del newfields[i] realfields[i] = v for i2, f2 in fields.items(): if v in f2: f2.remove(v) fields[i2] = f2 value = 1 for i, v in realfields.items(): if v.startswith('departure'): value *= my[i] print(value) return 0 if part_one(): start = time.time() result1 = p1() print(round(1000*(time.time() - start), 2), 'ms') if part_two(): start = time.time() p2() print(round(1000*(time.time() - start), 2), 'ms')