import re def decode_lines(l): rules = re.compile(r"(?P\w+ ?\w+): (?P\d+)-(?P\d+) or (?P\d+)-(?P\d+)").findall(l) my_ticket = re.compile(r"your ticket:\n(?P\d+[,\d+]+)").search(l) nearby_tickets = re.compile(r"\n(?P\d+[,\d+]+)").findall(l) return rules, my_ticket.group('ticket'), nearby_tickets[1:] def is_valid(ticket): count = 0 for value in ticket: valid = False for rule in rules: if int(rule[1]) <= int(value) <= int(rule[2]) or int(rule[3]) <= int(value) <= int(rule[4]): valid = True if not valid: count += int(value) return count def find_rule(rule): for i in range(0, len(nt[0])): valid = True for ticket in nt: value = ticket[i] if not (int(rule[1]) <= int(value) <= int(rule[2]) or int(rule[3]) <= int(value) <= int(rule[4])): valid = False if valid: yield i with open(r"C:\Users\Maya\Desktop\Uni\WS_2021\AoC\input16") as f: lines = f.readlines() lines = "".join(lines) rules, mine, nearby = decode_lines(lines) nt = [tick.split(',') for tick in nearby] mine = mine.split(',') print(mine) scanning_error = 0 for ticket in nt: scanning_error += is_valid(ticket) print(scanning_error) for ticket in nt: if is_valid(ticket) > 0: nt.remove(ticket) for ticket in nt: if is_valid(ticket) > 0: nt.remove(ticket) mem = {} for rule in rules: mem[rule[0]] = [False] * 20 for r in find_rule(rule): mem[rule[0]][r] = True rulebook = {} while True: if len(rulebook) == 15: break for i in range(0, 20): count = 0 for rule, value in mem.items(): if value[i]: count += 1 if count == 1: for rule, value in mem.items(): if value[i]: rulebook[i] = rule mem.pop(rule) print(rule) break print(rulebook) print(int(mine[19])*int(mine[17])*int(mine[11])*int(mine[8])*int(mine[10])*int(mine[0]))