Files
advent-of-code-2022/04/py/solution.py
2022-12-16 12:44:56 +01:00

68 lines
1.6 KiB
Python

import operator
from collections.abc import Callable
from dataclasses import dataclass
from pathlib import Path
@dataclass(frozen=True, slots=True)
class Range:
lower: int
upper: int
@classmethod
def from_pair(cls, s: str) -> "Range":
left, right = [int(num) for num in s.split("-")]
return cls(left, right)
@staticmethod
def _compare(a: "Range", b: "Range", _op: Callable[[bool, bool], bool]):
if _op(
b.lower <= a.lower <= b.upper,
b.lower <= a.upper <= b.upper,
):
return True
if _op(
a.lower <= b.lower <= a.upper,
a.lower <= b.upper <= a.upper,
):
return True
return False
def fully_contains(self, other: "Range") -> bool:
return Range._compare(self, other, operator.and_)
def overlaps(self, other: "Range") -> bool:
return Range._compare(self, other, operator.or_)
def part1(data: str) -> int:
count = 0
for line in data.splitlines():
left, right = [Range.from_pair(s) for s in line.split(",")]
if left.fully_contains(right):
count += 1
return count
def part2(data: str) -> int:
count = 0
for line in data.splitlines():
left, right = [Range.from_pair(s) for s in line.split(",")]
if left.overlaps(right):
count += 1
return count
# Setup
data = (Path(__file__).parents[1] / "input").read_text()
# Problem solving - part 1
result = part1(data)
print(f"Part 1 solution: {result}")
# Problem solving - part 2
result = part2(data)
print(f"Part 2 solution: {result}")