コード例 #1
0
ファイル: part2.py プロジェクト: kilbouri/Advent-of-Code
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}")