Initial commit with days 1 to 4.
This commit is contained in:
69
day2/solver.py
Normal file
69
day2/solver.py
Normal file
@@ -0,0 +1,69 @@
|
||||
from typing import Callable, Iterator
|
||||
import sys
|
||||
|
||||
|
||||
def check_report_basic(levels: tuple[int, ...]) -> bool:
|
||||
safe = True
|
||||
differences = [next_level - level for level, next_level in zip(levels, levels[1:])]
|
||||
safe = safe and (
|
||||
all(-3 <= diff <= -1 for diff in differences)
|
||||
or all(1 <= diff <= 3 for diff in differences)
|
||||
)
|
||||
return safe
|
||||
|
||||
def check_report_damp(levels: tuple[int, ...]) -> bool:
|
||||
# Obvious solution is using check_report_basic iteratively..
|
||||
# Is there a better solution?
|
||||
safe = check_report_basic(levels)
|
||||
safe = safe or any(check_report_basic(levels[:i] + levels[i+1:]) for i in range(len(levels)))
|
||||
return safe
|
||||
|
||||
def tester(data: dict[tuple[int, ...], bool], checker: Callable[[tuple[int, ...]], bool]):
|
||||
for report, expected in data.items():
|
||||
assert (checker(report) is expected), f"Check failed: {report=} should be {expected=}"
|
||||
|
||||
def tests():
|
||||
print("Testing basic check")
|
||||
data = {
|
||||
(7, 6, 4, 2, 1): True,
|
||||
(1, 2, 7, 8, 9): False,
|
||||
(9, 7, 6, 2, 1): False,
|
||||
(1, 3, 2, 4, 5): False,
|
||||
(8, 6, 4, 4, 1): False,
|
||||
(1, 3, 6, 7, 9): True,
|
||||
}
|
||||
tester(data, check_report_basic)
|
||||
print("Basic check passed.")
|
||||
|
||||
print("Testing dampened check.")
|
||||
data = {
|
||||
(7, 6, 4, 2, 1): True,
|
||||
(1, 2, 7, 8, 9): False,
|
||||
(9, 7, 6, 2, 1): False,
|
||||
(1, 3, 2, 4, 5): True,
|
||||
(8, 6, 4, 4, 1): True,
|
||||
(1, 3, 6, 7, 9): True,
|
||||
}
|
||||
tester(data, check_report_damp)
|
||||
print("Damp check passed.")
|
||||
|
||||
def main():
|
||||
tests()
|
||||
filename = sys.argv[1]
|
||||
reports = load_data(filename)
|
||||
total = sum(map(check_report_basic, reports))
|
||||
print(f"Total safe reports without damping: {total}")
|
||||
|
||||
reports = load_data(filename)
|
||||
total = sum(map(check_report_damp, reports))
|
||||
print(f"Total safe reports with damping: {total}")
|
||||
|
||||
|
||||
def load_data(filename) -> Iterator[tuple[int, ...]]:
|
||||
with open(filename) as f:
|
||||
for line in f:
|
||||
if line.strip():
|
||||
yield tuple(map(int, line.split()))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user