diff --git a/aoc.py b/aoc/aoc.py similarity index 93% rename from aoc.py rename to aoc/aoc.py index ec12ae2..0da2258 100644 --- a/aoc.py +++ b/aoc/aoc.py @@ -179,10 +179,21 @@ class AocParseLinesSameParser(Generic[T1], AocParseLines[T1, T1]): ... +def run_latest() -> None: + days = [ + import_module(f".{file.stem}", package="aoc") + for file in Path("aoc").iterdir() + if file.name.endswith(".py") and file.name.startswith("day") + ] + day = days[-1] + print(f"Running {day.__name__}") + day.main() + + def main() -> None: days = [ - import_module(file.stem) - for file in Path(".").iterdir() + import_module(f".{file.stem}", package="aoc") + for file in Path("aoc").iterdir() if file.name.endswith(".py") and file.name.startswith("day") ] for day in days: diff --git a/day01.py b/aoc/day01.py similarity index 86% rename from day01.py rename to aoc/day01.py index 0d1b632..a0d66d3 100644 --- a/day01.py +++ b/aoc/day01.py @@ -1,7 +1,11 @@ -from aoc import Aoc2, AocSameImplementation, AocParseLines +from .aoc import Aoc2, AocSameImplementation, AocParseLines -class Day01(AocParseLines[str, str], AocSameImplementation[list[str]], Aoc2[list[str], list[str]]): +class Day01( + AocParseLines[str, str], + AocSameImplementation[list[str]], + Aoc2[list[str], list[str]], +): def __init__(self) -> None: Aoc2.__init__(self, 2023, 1) diff --git a/day02.py b/aoc/day02.py similarity index 97% rename from day02.py rename to aoc/day02.py index 3be804a..10efe41 100644 --- a/day02.py +++ b/aoc/day02.py @@ -1,7 +1,7 @@ from __future__ import annotations from dataclasses import dataclass -from aoc import Aoc2, AocParseLinesSameParser +from .aoc import Aoc2, AocParseLinesSameParser @dataclass(frozen=True) diff --git a/day03.py b/aoc/day03.py similarity index 98% rename from day03.py rename to aoc/day03.py index c72b117..3e55327 100644 --- a/day03.py +++ b/aoc/day03.py @@ -2,7 +2,7 @@ from collections import defaultdict from dataclasses import dataclass from functools import reduce from typing import Any, Optional -from aoc import Aoc2, AocSameParser +from .aoc import Aoc2, AocSameParser @dataclass diff --git a/day04.py b/aoc/day04.py similarity index 88% rename from day04.py rename to aoc/day04.py index e19b139..02a4657 100644 --- a/day04.py +++ b/aoc/day04.py @@ -2,7 +2,7 @@ from __future__ import annotations from dataclasses import dataclass import regex -from aoc import Aoc2, AocParseLinesSameParser +from .aoc import Aoc2, AocParseLinesSameParser @dataclass @@ -41,9 +41,7 @@ class Day04(AocParseLinesSameParser[Card], Aoc2[list[Card], list[Card]]): def part2(self, cards: list[Card]) -> int: d = [0] * len(cards) for card in reversed(cards): - d[card.card_id - 1] = 1 + sum( - d[card.card_id + i] for i in range(card.wins) - ) + d[card.card_id - 1] = 1 + sum(d[card.card_id + i] for i in range(card.wins)) return sum(d) diff --git a/day05.py b/aoc/day05.py similarity index 99% rename from day05.py rename to aoc/day05.py index 12f51cf..d105c87 100644 --- a/day05.py +++ b/aoc/day05.py @@ -6,7 +6,7 @@ from typing import Optional import regex as re -from aoc import Aoc2, AocSameParser +from .aoc import Aoc2, AocSameParser class Map: diff --git a/aoc/day06.py b/aoc/day06.py new file mode 100644 index 0000000..091844f --- /dev/null +++ b/aoc/day06.py @@ -0,0 +1,56 @@ +from dataclasses import dataclass +from functools import reduce + +import re + +from .aoc import Aoc2, AocSameImplementation + + +@dataclass +class Race: + time: int + distance: int + + +class Day06(AocSameImplementation[list[Race]], Aoc2[list[Race], list[Race]]): + def simulate(self, timeaccel: int, timeoverall: int) -> int: + racetime = timeoverall - timeaccel + return racetime * timeaccel + + def parseinput2(self, inpt: str) -> list[Race]: + lines = inpt.splitlines() + times = int("".join(re.findall(r"\d+", lines[0]))) + distances = int("".join(re.findall(r"\d+", lines[1]))) + + return [Race(times, distances)] + + def parseinput1(self, inpt: str) -> list[Race]: + lines = inpt.splitlines() + times = (int(d) for d in re.findall(r"\d+", lines[0])) + distances = (int(d) for d in re.findall(r"\d+", lines[1])) + + return [Race(*t) for t in zip(times, distances)] + + def part(self, inpt: list[Race]) -> int: + return reduce( + lambda x, y: x * y, + [ + len( + [ + poss + for poss in range(race.time) + if self.simulate(poss, race.time) > race.distance + ] + ) + for race in inpt + ], + ) + + +def main() -> None: + day06 = Day06(2023, 6) + day06.run() + + +if __name__ == "__main__": + main() diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..b3a16aa --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,22 @@ +[tool.poetry] +name = "aoc2023" +version = "0.1.0" +description = "Advent of Code 2023" +authors = ["Christoph Stahl "] +readme = "README.md" +packages = [{include = "aoc"}] + +[tool.poetry.dependencies] +python = "^3.10" +regex = "^2023.10.3" +types-regex = "^2023.10.3.0" +mypy = "^1.7.1" + + +[build-system] +requires = ["poetry-core"] +build-backend = "poetry.core.masonry.api" + +[tool.poetry.scripts] +aoc = "aoc.aoc:main" +latest = "aoc.aoc:run_latest"