-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathcommon.py
More file actions
65 lines (45 loc) · 1.77 KB
/
common.py
File metadata and controls
65 lines (45 loc) · 1.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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