day04 finished
This commit is contained in:
parent
dc319ea862
commit
371bde9b7d
5 changed files with 1085 additions and 0 deletions
0
advent/days/day04/__init__.py
Normal file
0
advent/days/day04/__init__.py
Normal file
1000
advent/days/day04/data/input.txt
Normal file
1000
advent/days/day04/data/input.txt
Normal file
File diff suppressed because it is too large
Load diff
6
advent/days/day04/data/test01.txt
Normal file
6
advent/days/day04/data/test01.txt
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
2-4,6-8
|
||||||
|
2-3,4-5
|
||||||
|
5-7,7-9
|
||||||
|
2-8,3-7
|
||||||
|
6-6,4-6
|
||||||
|
2-6,4-8
|
||||||
55
advent/days/day04/solution.py
Normal file
55
advent/days/day04/solution.py
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
from typing import Iterator
|
||||||
|
|
||||||
|
day_num = 4
|
||||||
|
|
||||||
|
|
||||||
|
def part1(lines: Iterator[str]) -> int:
|
||||||
|
return sum(1 for line in lines if Pair.parse(line).includes())
|
||||||
|
|
||||||
|
|
||||||
|
def part2(lines: Iterator[str]) -> int:
|
||||||
|
return sum(1 for line in lines if Pair.parse(line).overlap())
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(slots=True, frozen=True)
|
||||||
|
class Range:
|
||||||
|
start: int
|
||||||
|
end: int
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def parse(line: str) -> Range:
|
||||||
|
match line.split('-'):
|
||||||
|
case [s, e]: return Range(int(s), int(e))
|
||||||
|
case _: raise Exception(f"Not a valid range: {line}")
|
||||||
|
|
||||||
|
def includes(self, other: Range) -> bool:
|
||||||
|
""" Check if this range includes the other """
|
||||||
|
return self.start <= other.start and self.end >= other.end
|
||||||
|
|
||||||
|
def overlap(self, other: Range) -> bool:
|
||||||
|
""" Check if this range obverlaps with the other """
|
||||||
|
return (self.start >= other.start and self.start <= other.end) or (
|
||||||
|
other.start >= self.start and other.start <= self.end)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass(slots=True, frozen=True)
|
||||||
|
class Pair:
|
||||||
|
first: Range
|
||||||
|
second: Range
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def parse(line: str) -> Pair:
|
||||||
|
match line.split(','):
|
||||||
|
case [f, s]: return Pair(Range.parse(f), Range.parse(s))
|
||||||
|
case _: raise Exception(f"Not a valid Pair: {line}")
|
||||||
|
|
||||||
|
def includes(self) -> bool:
|
||||||
|
""" Check if one range includes the other """
|
||||||
|
return self.first.includes(self.second) or self.second.includes(self.first)
|
||||||
|
|
||||||
|
def overlap(self) -> bool:
|
||||||
|
""" Check if the two ranges obverlap """
|
||||||
|
return self.first.overlap(self.second)
|
||||||
24
advent/days/day04/test_solution.py
Normal file
24
advent/days/day04/test_solution.py
Normal file
|
|
@ -0,0 +1,24 @@
|
||||||
|
from advent.common import utils
|
||||||
|
|
||||||
|
from .solution import Pair, Range, day_num, part1, part2
|
||||||
|
|
||||||
|
|
||||||
|
def test_part1():
|
||||||
|
data = utils.read_data(day_num, 'test01.txt')
|
||||||
|
expected = 2
|
||||||
|
result = part1(data)
|
||||||
|
assert result == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_part2():
|
||||||
|
data = utils.read_data(day_num, 'test01.txt')
|
||||||
|
expected = 4
|
||||||
|
result = part2(data)
|
||||||
|
assert result == expected
|
||||||
|
|
||||||
|
|
||||||
|
def test_parse():
|
||||||
|
input = "2-4,6-8"
|
||||||
|
expected = Pair(Range(2, 4), Range(6, 8))
|
||||||
|
result = Pair.parse(input)
|
||||||
|
assert result == expected
|
||||||
Loading…
Add table
Add a link
Reference in a new issue