Skip to content

Commit

Permalink
feat: add 2023 day 06 part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
marcelblijleven committed Dec 7, 2023
1 parent 8f4ab9a commit 0d7fbaf
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 0 deletions.
73 changes: 73 additions & 0 deletions src/adventofcode/year_2023/day_06_2023.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import re
from itertools import starmap

from math import prod

from adventofcode.util.exceptions import SolutionNotFoundError
from adventofcode.registry.decorators import register_solution
from adventofcode.util.input_helpers import get_input_for_day


def parse_input(data: list[str]) -> list[tuple[int, int]]:
"""
Zip the time and distance values into a list of tuples of int
"""
pattern = re.compile("\\d+")
times = map(int, pattern.findall(data[0]))
distances = map(int, pattern.findall(data[1]))
return list(zip(times, distances))


def calculate_distance(hold: int, max_time: int) -> int:
"""
Calculate the distance you can travel within the max limit
for the given hold duration
"""
if hold == 0 or hold == max_time:
return 0

return (max_time - hold) * hold


def calculate_ways_to_win(duration: int, farthest_distance: int) -> int:
"""
Calculate ways to beat the current farthest distance
"""
possibilities = zip(range(duration + 1), [duration] * duration)
distances = starmap(calculate_distance, possibilities)
winning_distances = filter(lambda x: x > farthest_distance, distances)
return len(list(winning_distances))


def calculate_margin_of_error(data: list[str]) -> int:
"""
Calculate the margin of error
"""
parsed_input = parse_input(data)
return prod(starmap(calculate_ways_to_win, parsed_input))


@register_solution(2023, 6, 1)
def part_one(input_data: list[str]):
answer = calculate_margin_of_error(input_data)

if not answer:
raise SolutionNotFoundError(2023, 6, 1)

return answer


@register_solution(2023, 6, 2)
def part_two(input_data: list[str]):
answer = ...

if not answer:
raise SolutionNotFoundError(2023, 6, 2)

return answer


if __name__ == '__main__':
data = get_input_for_day(2023, 6)
part_one(data)
part_two(data)
44 changes: 44 additions & 0 deletions tests/adventofcode/year_2023/test_day_06_2023.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import pytest

from adventofcode.year_2023.day_06_2023 import (part_two, part_one, calculate_distance, parse_input,
calculate_ways_to_win)

test_input = [
"Time: 7 15 30",
"Distance: 9 40 200",
]


def test_parse_input():
assert parse_input(test_input) == [(7, 9), (15, 40), (30, 200)]


@pytest.mark.parametrize(["hold", "max_time", "expected"], [
(0, 7, 0),
(1, 7, 6),
(2, 7, 10),
(3, 7, 12),
(4, 7, 12),
(5, 7, 10),
(6, 7, 6),
(7, 7, 0),
])
def test_calculate_distance(hold, max_time, expected):
assert calculate_distance(hold, max_time) == expected


@pytest.mark.parametrize(["duration", "farthest_distance", "expected"], [
(7, 9, 4),
(15, 40, 8),
(30, 200, 9),
])
def test_calculate_ways_to_win(duration, farthest_distance, expected):
assert calculate_ways_to_win(duration, farthest_distance) == expected


def test_part_one():
assert part_one(test_input) == 288


def test_part_two():
assert part_two(test_input) == 'x'

0 comments on commit 0d7fbaf

Please sign in to comment.