def main(): # open the file, split into blocks: <fields>, <your ticket>, <other tickets> with open(f"{getcwd()}/2020/day16/input.txt") as file: file = file.read().strip().split("\n\n") allFields = re.findall(r"(.*): (\d+-\d+) or (\d+-\d+)", file[0]) yourTicket = file[1].splitlines()[1] otherTickets = file[2].splitlines()[1:] validTicket = Ticket() # fill the ticket with all the fields and ranges in the input for field in allFields: validTicket.addFieldRange(field[0], [field[1], field[2]]) # list of all valid tickets (just tuples of values that appear on the ticket) validTickets = [ tuple(strToIntSequence(line)) for line in map(str.strip, otherTickets) if isValidTicket(strToIntSequence(line), validTicket) ] # a list of sets of the possible labels for each field fieldList = [ validTicket.getFields().copy() for _ in range(len(validTickets[0])) ] # find the arrangement of labels for the tickets for i, fieldSet in enumerate(fieldList): fieldsToRemove = set() for field in fieldSet: for ticket in validTickets: if not validTicket.isValidForField(field, ticket[i]): fieldsToRemove.add(field) break fieldSet -= fieldsToRemove if len(fieldSet) == 1: removeUnique(i, list(fieldSet)[0], fieldList) fieldList = [list(item)[0] for item in fieldList] # calculate ticket score score = 1 for label, value in zip(fieldList, strToIntSequence(yourTicket)): if label.startswith("departure"): score *= value print(f"Product of departure fields: {score}")