58 lines
1.5 KiB
Python
58 lines
1.5 KiB
Python
#!/usr/bin/env python3
|
|
import re
|
|
|
|
|
|
def yield_spans(gs: dict):
|
|
for g in gs.values():
|
|
yield g[:2]
|
|
yield g[2:]
|
|
|
|
|
|
def in_spans(x, spans):
|
|
for span in spans:
|
|
if span[0] <= x <= span[1]:
|
|
return True
|
|
return False
|
|
|
|
|
|
lines = (x.strip() for x in open("input.txt"))
|
|
REGEX_RANGES = re.compile(r"^([a-z ]+): (\d+)-(\d+) or (\d+)-(\d+)$")
|
|
groups = {}
|
|
your = ()
|
|
nearby = []
|
|
read_step = 0
|
|
|
|
for line in lines:
|
|
if read_step == 0:
|
|
if line == "":
|
|
read_step = 1
|
|
continue
|
|
match = REGEX_RANGES.match(line)
|
|
groups[match[1]] = list(map(int, match.groups()[1:]))
|
|
elif read_step == 1:
|
|
if line == "":
|
|
read_step = 2
|
|
continue
|
|
if line.startswith("your"):
|
|
continue
|
|
your = list(map(int, line.split(',')))
|
|
elif read_step == 2:
|
|
if line.startswith("nearby"):
|
|
continue
|
|
nearby.append(list(map(int, line.split(','))))
|
|
|
|
valid_spans = []
|
|
for span in yield_spans(groups):
|
|
start_idx = next((i for i, v in enumerate(valid_spans) if span[0] <= v[1]), len(valid_spans))
|
|
end_idx = next((len(valid_spans)-i for i, v in enumerate(valid_spans[::-1]) if span[1] >= v[0]), 0)
|
|
for idx in range(start_idx, end_idx):
|
|
popped = valid_spans.pop(start_idx)
|
|
span = (min(popped[0], span[0]), max(popped[1], span[1]))
|
|
valid_spans.insert(start_idx, tuple(span))
|
|
|
|
print("Valid Spans:", valid_spans)
|
|
|
|
|
|
invalid_sum = sum(x for n in nearby for x in n if not in_spans(x, valid_spans))
|
|
print(invalid_sum)
|