diff --git a/data/example/2019/04.txt b/data/example/2019/04.txt new file mode 100644 index 000000000..c6e7396 --- /dev/null +++ b/data/example/2019/04.txt @@ -0,0 +1 @@ +229228-249228 diff --git a/src/solution/year_2019/day_04.py b/src/solution/year_2019/day_04.py new file mode 100644 index 000000000..aa2e6f3 --- /dev/null +++ b/src/solution/year_2019/day_04.py @@ -0,0 +1,66 @@ +from typing import Any + + +def _test_len(s: str, n: int): + return len(s) == n + + +def _test_increasing(s: str): + return all(s[i - 1] <= s[i] for i in range(1, len(s))) + + +def _test_adjacent(s: str): + return any(s[i - 1] == s[i] for i in range(1, len(s))) + + +def _get_index(s: str, i: int) -> str | None: + if not (0 <= i < len(s)): + return None + + return s[i] + + +def _test_adjacent_2(s: str) -> bool: + for i in range(1, len(s)): + s1 = s[i] + s2 = s[i - 1] + + s0 = _get_index(s, i - 2) + s3 = _get_index(s, i + 1) + + if s1 == s2 and s1 != s0 and s2 != s3: + return True + + return False + + +def _is_valid_password(n: int) -> bool: + s = str(n) + return all([_test_len(s, 6), _test_adjacent(s), _test_increasing(s)]) + + +def _is_valid_password_2(n: int) -> bool: + s = str(n) + return all([_test_len(s, 6), _test_adjacent_2(s), _test_increasing(s)]) + + +def part_1(input_data: str) -> Any: + a, b = input_data.split("-") + a, b = int(a), int(b) + + return len([x for x in range(a, b + 1) if _is_valid_password(x)]) + + +def part_2(input_data: str) -> Any: + a, b = input_data.split("-") + a, b = int(a), int(b) + + return len([x for x in range(a, b + 1) if _is_valid_password_2(x)]) + + +def test_part_1(example_data): + assert part_1(example_data) == 316 + + +def test_part_2(example_data): + assert part_2(example_data) == 218