diff --git a/16/part2 b/16/part2 new file mode 100755 index 0000000..4a705d0 --- /dev/null +++ b/16/part2 @@ -0,0 +1,92 @@ +#!/usr/bin/python3 + +import re +from pprint import pprint + +with open("input") as fh: + state = "rules" + rules = {} + nearby = [] + for ln in fh: + ln = ln.strip() + if state == "rules": + if m := re.match(r"([a-z ]+): ([0-9]+)-([0-9]+) or ([0-9]+)-([0-9]+)", ln): + rules[m.group(1)] = ((int(m.group(2)), int(m.group(3))), + (int(m.group(4)), int(m.group(5)))) + elif ln == "your ticket:": + state = "your" + elif ln == "": + pass + else: + raise RuntimeError(ln) + elif state == "your": + if re.match(r"[0-9,]+", ln): + my_ticket = [int(x) for x in ln.split(",")] + elif ln == "nearby tickets:": + state = "nearby" + elif ln == "": + pass + else: + raise RuntimeError(ln) + elif state == "nearby": + if re.match(r"[0-9,]+", ln): + ticket = [int(x) for x in ln.split(",")] + nearby.append(ticket) + elif ln == "": + pass + else: + raise RuntimeError(ln) + +print(len(nearby), "tickets") +valid_tickets = [] +for ticket in nearby: + ticket_ok = True + for num in ticket: + ok = False + for rule in rules.values(): + if rule[0][0] <= num <= rule[0][1] or rule[1][0] <= num <= rule[1][1]: + ok = True + break + if not ok: + ticket_ok = False + break + if ticket_ok: + valid_tickets.append(ticket) + +print(len(valid_tickets), "tickets valid") + +candidates = {x: set(range(len(valid_tickets[0]))) for x in rules.keys()} +pprint(candidates) + +for name, rule in rules.items(): + for ticket in valid_tickets: + for i in list(candidates[name]): + num = ticket[i] + if rule[0][0] <= num <= rule[0][1] or rule[1][0] <= num <= rule[1][1]: + pass + else: + print(num, "doesn't match", rule, "eliminating", i, "from", name) + candidates[name] -= {i} + +pprint(candidates) + +column = {} +while candidates: + for name, columns in candidates.items(): + if len(columns) == 1: + column[name] = c = columns.pop() + for columns in candidates.values(): + columns -= {c} + break + elif len(columns) == 0: + # eliminated earlier + del candidates[name] + break +pprint(column) + +res = 1 +for name, c in column.items(): + if name.startswith("departure"): + res *= my_ticket[c] + +print(res)