adventOfCode/16-ticketTranslation/python/common.py
2020-12-16 16:58:17 +00:00

51 lines
No EOL
1.7 KiB
Python

from typing import List, Tuple
class Rule:
name: str
ranges: Tuple[int, ...]
def __init__(self, instr:str) -> None:
# arrival location: 26-482 or 504-959
field, conditions = instr.strip().split(": ")
self.name = field
ranges = conditions.split("or")
self.ranges = tuple([int(x) for x in ranges[0].strip().split("-")] + [int(x) for x in ranges[1].strip().split("-")])
class Ticket:
fields: Tuple[int]
def __init__(self, instr:str) -> None:
self.fields = tuple([int(x) for x in instr.strip().split(",")])
def parse(instr: str) -> Tuple[List[Rule], Ticket, List[Ticket]]:
raw_rules, raw_my_ticket, raw_other_tickets = instr.strip().split("\n\n")
rules = [Rule(x) for x in raw_rules.split("\n")]
my_ticket = Ticket(raw_my_ticket.split("\n")[-1])
other_tickets = [Ticket(x) for x in raw_other_tickets.strip("nearby tickets:\n").split("\n")]
return rules, my_ticket, other_tickets
def test_value(value:int, condition:Tuple[int, ...]) -> bool:
return condition[0] <= value <= condition[1] or condition[2] <= value <= condition[3]
def find_invalid(rules:List[Rule], tickets:List[Ticket]) -> Tuple[List[int], List[int]]:
# returns invalid values and indexes of invalid tickets
invalid_values = []
invalid_indexes = []
for i, ticket in enumerate(tickets):
for field in ticket.fields:
field_is_valid = False
for rule in rules:
if test_value(field, rule.ranges):
field_is_valid = True
if not field_is_valid:
invalid_values.append(field)
invalid_indexes.append(i)
return invalid_values, invalid_indexes