From e2964c6c362f3b91024dd1772eda6ccca85ccf61 Mon Sep 17 00:00:00 2001 From: Thibaud Date: Mon, 4 Aug 2025 16:23:06 +0200 Subject: [PATCH] chore: create new project structure and aoc.py runner script --- 2024/stats.txt | 17 -- Makefile | 26 +++ README.md | 14 +- {2015 => adventofcode/2015}/day1/day1.py | 0 {2018 => adventofcode/2018}/day1/day1.py | 0 {2018 => adventofcode/2018}/day2/day2.py | 0 {2018 => adventofcode/2018}/day3/day3.py | 0 {2018 => adventofcode/2018}/day4/day4.py | 0 {2018 => adventofcode/2018}/day5/day5.py | 0 {2018 => adventofcode/2018}/day6/day6.py | 0 {2018 => adventofcode/2018}/day7/day7.py | 0 adventofcode/2019/__init__.py | 0 {2019 => adventofcode/2019}/day1/day1.py | 0 {2019 => adventofcode/2019}/day11/day11.py | 0 adventofcode/2019/day13/__init__.py | 0 {2019 => adventofcode/2019}/day13/day13.py | 0 {2019 => adventofcode/2019}/day2/day2.py | 0 {2019 => adventofcode/2019}/day3/day3.py | 158 +++++++++--------- {2019 => adventofcode/2019}/day4/day4.py | 0 {2019 => adventofcode/2019}/day5/day5.py | 0 {2019 => adventofcode/2019}/day5/day52.py | 0 {2019 => adventofcode/2019}/day6/day6.py | 0 {2019 => adventofcode/2019}/day7/day7.py | 3 - {2019 => adventofcode/2019}/day8/day8.py | 0 {2019 => adventofcode/2019}/day9/day9.py | 0 .../2019}/intcode/benchmark.py | 0 .../2019}/intcode/intcode.py | 0 {2019 => adventofcode/2019}/intcode/tests.py | 0 {2020 => adventofcode/2020}/day1/day1.py | 0 {2020 => adventofcode/2020}/day10/day10.py | 0 {2020 => adventofcode/2020}/day11/day11.py | 0 {2020 => adventofcode/2020}/day11/grid.py | 0 {2020 => adventofcode/2020}/day11/rules.py | 0 {2020 => adventofcode/2020}/day14/day14.py | 0 {2020 => adventofcode/2020}/day15/day15.py | 0 {2020 => adventofcode/2020}/day16/day16.py | 0 {2020 => adventofcode/2020}/day2/day2.py | 0 {2020 => adventofcode/2020}/day2/part1.py | 0 {2020 => adventofcode/2020}/day2/part2.py | 0 {2020 => adventofcode/2020}/day3/day3.py | 0 {2020 => adventofcode/2020}/day4/day4.py | 0 {2020 => adventofcode/2020}/day5/day5.py | 0 {2020 => adventofcode/2020}/day5/tests.py | 0 {2020 => adventofcode/2020}/day6/day6.py | 0 {2020 => adventofcode/2020}/day7/day7.py | 0 {2020 => adventofcode/2020}/day8/day8.py | 0 {2020 => adventofcode/2020}/day9/day9.py | 0 {2021 => adventofcode/2021}/day1/day1.py | 0 {2021 => adventofcode/2021}/day2/day2.py | 0 {2021 => adventofcode/2021}/day3/day3.py | 0 {2021 => adventofcode/2021}/day4/day4.py | 0 {2021 => adventofcode/2021}/day5/day5.py | 0 {2021 => adventofcode/2021}/day6/day6.py | 0 {2021 => adventofcode/2021}/day6/day6_2.py | 0 {2021 => adventofcode/2021}/day7/day7.py | 0 {2021 => adventofcode/2021}/day8/day8.py | 0 {2022 => adventofcode/2022}/day1/day1.py | 0 {2022 => adventofcode/2022}/day2/day2.py | 0 {2022 => adventofcode/2022}/day3/day3.py | 0 {2022 => adventofcode/2022}/day4/day4.py | 0 {2023 => adventofcode/2023}/day1/day1.py | 0 {2023 => adventofcode/2023}/day10/day10.py | 0 {2023 => adventofcode/2023}/day2/day2.py | 0 {2023 => adventofcode/2023}/day3/day3.py | 0 {2023 => adventofcode/2023}/day4/day4.py | 0 {2023 => adventofcode/2023}/day5/day5.py | 0 {2023 => adventofcode/2023}/day6/day6.py | 0 {2023 => adventofcode/2023}/day7/day7.py | 0 {2023 => adventofcode/2023}/day8/day8.py | 0 {2023 => adventofcode/2023}/day9/day9.py | 0 {2024 => adventofcode/2024}/day1/day1.py | 0 {2024 => adventofcode/2024}/day10/day10.py | 0 {2024 => adventofcode/2024}/day11/: | 0 {2024 => adventofcode/2024}/day11/day11.py | 0 {2024 => adventofcode/2024}/day12/day12.py | 0 {2024 => adventofcode/2024}/day13/day13.py | 0 {2024 => adventofcode/2024}/day14/day14.py | 0 {2024 => adventofcode/2024}/day15/day15.py | 0 {2024 => adventofcode/2024}/day16/day16.py | 0 {2024 => adventofcode/2024}/day18/day18.py | 0 {2024 => adventofcode/2024}/day2/day2.py | 0 {2024 => adventofcode/2024}/day3/day3.py | 0 {2024 => adventofcode/2024}/day4/day4.py | 0 {2024 => adventofcode/2024}/day5/day5.py | 0 {2024 => adventofcode/2024}/day6/day6.py | 0 {2024 => adventofcode/2024}/day7/day7.py | 0 {2024 => adventofcode/2024}/day8/day8.py | 0 {2024 => adventofcode/2024}/day9/day9.py | 0 adventofcode/aoc.py | 41 +++++ run.py => adventofcode/helper.py | 17 +- pyproject.toml | 14 ++ 91 files changed, 177 insertions(+), 113 deletions(-) delete mode 100644 2024/stats.txt create mode 100644 Makefile rename {2015 => adventofcode/2015}/day1/day1.py (100%) rename {2018 => adventofcode/2018}/day1/day1.py (100%) rename {2018 => adventofcode/2018}/day2/day2.py (100%) rename {2018 => adventofcode/2018}/day3/day3.py (100%) rename {2018 => adventofcode/2018}/day4/day4.py (100%) rename {2018 => adventofcode/2018}/day5/day5.py (100%) rename {2018 => adventofcode/2018}/day6/day6.py (100%) rename {2018 => adventofcode/2018}/day7/day7.py (100%) create mode 100644 adventofcode/2019/__init__.py rename {2019 => adventofcode/2019}/day1/day1.py (100%) rename {2019 => adventofcode/2019}/day11/day11.py (100%) create mode 100644 adventofcode/2019/day13/__init__.py rename {2019 => adventofcode/2019}/day13/day13.py (100%) rename {2019 => adventofcode/2019}/day2/day2.py (100%) rename {2019 => adventofcode/2019}/day3/day3.py (96%) rename {2019 => adventofcode/2019}/day4/day4.py (100%) rename {2019 => adventofcode/2019}/day5/day5.py (100%) rename {2019 => adventofcode/2019}/day5/day52.py (100%) rename {2019 => adventofcode/2019}/day6/day6.py (100%) rename {2019 => adventofcode/2019}/day7/day7.py (95%) rename {2019 => adventofcode/2019}/day8/day8.py (100%) rename {2019 => adventofcode/2019}/day9/day9.py (100%) rename {2019 => adventofcode/2019}/intcode/benchmark.py (100%) rename {2019 => adventofcode/2019}/intcode/intcode.py (100%) rename {2019 => adventofcode/2019}/intcode/tests.py (100%) rename {2020 => adventofcode/2020}/day1/day1.py (100%) rename {2020 => adventofcode/2020}/day10/day10.py (100%) rename {2020 => adventofcode/2020}/day11/day11.py (100%) rename {2020 => adventofcode/2020}/day11/grid.py (100%) rename {2020 => adventofcode/2020}/day11/rules.py (100%) rename {2020 => adventofcode/2020}/day14/day14.py (100%) rename {2020 => adventofcode/2020}/day15/day15.py (100%) rename {2020 => adventofcode/2020}/day16/day16.py (100%) rename {2020 => adventofcode/2020}/day2/day2.py (100%) rename {2020 => adventofcode/2020}/day2/part1.py (100%) rename {2020 => adventofcode/2020}/day2/part2.py (100%) rename {2020 => adventofcode/2020}/day3/day3.py (100%) rename {2020 => adventofcode/2020}/day4/day4.py (100%) rename {2020 => adventofcode/2020}/day5/day5.py (100%) rename {2020 => adventofcode/2020}/day5/tests.py (100%) rename {2020 => adventofcode/2020}/day6/day6.py (100%) rename {2020 => adventofcode/2020}/day7/day7.py (100%) rename {2020 => adventofcode/2020}/day8/day8.py (100%) rename {2020 => adventofcode/2020}/day9/day9.py (100%) rename {2021 => adventofcode/2021}/day1/day1.py (100%) rename {2021 => adventofcode/2021}/day2/day2.py (100%) rename {2021 => adventofcode/2021}/day3/day3.py (100%) rename {2021 => adventofcode/2021}/day4/day4.py (100%) rename {2021 => adventofcode/2021}/day5/day5.py (100%) rename {2021 => adventofcode/2021}/day6/day6.py (100%) rename {2021 => adventofcode/2021}/day6/day6_2.py (100%) rename {2021 => adventofcode/2021}/day7/day7.py (100%) rename {2021 => adventofcode/2021}/day8/day8.py (100%) rename {2022 => adventofcode/2022}/day1/day1.py (100%) rename {2022 => adventofcode/2022}/day2/day2.py (100%) rename {2022 => adventofcode/2022}/day3/day3.py (100%) rename {2022 => adventofcode/2022}/day4/day4.py (100%) rename {2023 => adventofcode/2023}/day1/day1.py (100%) rename {2023 => adventofcode/2023}/day10/day10.py (100%) rename {2023 => adventofcode/2023}/day2/day2.py (100%) rename {2023 => adventofcode/2023}/day3/day3.py (100%) rename {2023 => adventofcode/2023}/day4/day4.py (100%) rename {2023 => adventofcode/2023}/day5/day5.py (100%) rename {2023 => adventofcode/2023}/day6/day6.py (100%) rename {2023 => adventofcode/2023}/day7/day7.py (100%) rename {2023 => adventofcode/2023}/day8/day8.py (100%) rename {2023 => adventofcode/2023}/day9/day9.py (100%) rename {2024 => adventofcode/2024}/day1/day1.py (100%) rename {2024 => adventofcode/2024}/day10/day10.py (100%) rename {2024 => adventofcode/2024}/day11/: (100%) rename {2024 => adventofcode/2024}/day11/day11.py (100%) rename {2024 => adventofcode/2024}/day12/day12.py (100%) rename {2024 => adventofcode/2024}/day13/day13.py (100%) rename {2024 => adventofcode/2024}/day14/day14.py (100%) rename {2024 => adventofcode/2024}/day15/day15.py (100%) rename {2024 => adventofcode/2024}/day16/day16.py (100%) rename {2024 => adventofcode/2024}/day18/day18.py (100%) rename {2024 => adventofcode/2024}/day2/day2.py (100%) rename {2024 => adventofcode/2024}/day3/day3.py (100%) rename {2024 => adventofcode/2024}/day4/day4.py (100%) rename {2024 => adventofcode/2024}/day5/day5.py (100%) rename {2024 => adventofcode/2024}/day6/day6.py (100%) rename {2024 => adventofcode/2024}/day7/day7.py (100%) rename {2024 => adventofcode/2024}/day8/day8.py (100%) rename {2024 => adventofcode/2024}/day9/day9.py (100%) create mode 100644 adventofcode/aoc.py rename run.py => adventofcode/helper.py (86%) create mode 100644 pyproject.toml diff --git a/2024/stats.txt b/2024/stats.txt deleted file mode 100644 index c12b692..0000000 --- a/2024/stats.txt +++ /dev/null @@ -1,17 +0,0 @@ -ran day1/day1.py in 0.016s -ran day2/day2.py in 0.021s -ran day3/day3.py in 0.017s -ran day4/day4.py in 0.039s -ran day5/day5.py in 0.191s -ran day6/day6.py in 9.655s -ran day7/day7.py in 2.227s -ran day8/day8.py in 0.017s -ran day9/day9.py in 11.159s -ran day10/day10.py in 0.052s -ran day11/day11.py in 0.116s -ran day12/day12.py in 0.170s -ran day13/day13.py in 0.014s -ran day14/day14.py in 3.729s -ran day16/day16.py in 10.082s -ran day18/day18.py in 0.872s - diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..f5eeb62 --- /dev/null +++ b/Makefile @@ -0,0 +1,26 @@ +.PHONY: all venv install clean + +# Define the virtual environment directory +VENV_DIR = ./venv + +# Define the Python interpreter to use +PYTHON = $(VENV_DIR)/bin/python + +# Default target +all: venv install + +# Create virtual environment if it doesn't exist +venv: + @echo "Creating virtual environment..." + @if [ ! -d $(VENV_DIR) ]; then \ + python3 -m venv $(VENV_DIR); \ + fi + +install: venv + @$(PYTHON) -m pip install --upgrade pip + @$(PYTHON) -m pip install -e . + +clean: + @echo "Removing virtual environment..." + @rm -rf $(VENV_DIR) + diff --git a/README.md b/README.md index d558f3b..8da1264 100644 --- a/README.md +++ b/README.md @@ -4,15 +4,25 @@ My solutions to the [advent of code](https://adventofcode.com/) challenges, writ ## How to run +### Install project + +Run `make install` or + +Run from root directory (inside a virtualenv): + +```shell +$ pip install -e . +``` + ### Run a single day ```shell -$ python3 run.py +$ aoc ``` ### Run a whole year ```shell -$ python3 run.py +$ aoc ``` diff --git a/2015/day1/day1.py b/adventofcode/2015/day1/day1.py similarity index 100% rename from 2015/day1/day1.py rename to adventofcode/2015/day1/day1.py diff --git a/2018/day1/day1.py b/adventofcode/2018/day1/day1.py similarity index 100% rename from 2018/day1/day1.py rename to adventofcode/2018/day1/day1.py diff --git a/2018/day2/day2.py b/adventofcode/2018/day2/day2.py similarity index 100% rename from 2018/day2/day2.py rename to adventofcode/2018/day2/day2.py diff --git a/2018/day3/day3.py b/adventofcode/2018/day3/day3.py similarity index 100% rename from 2018/day3/day3.py rename to adventofcode/2018/day3/day3.py diff --git a/2018/day4/day4.py b/adventofcode/2018/day4/day4.py similarity index 100% rename from 2018/day4/day4.py rename to adventofcode/2018/day4/day4.py diff --git a/2018/day5/day5.py b/adventofcode/2018/day5/day5.py similarity index 100% rename from 2018/day5/day5.py rename to adventofcode/2018/day5/day5.py diff --git a/2018/day6/day6.py b/adventofcode/2018/day6/day6.py similarity index 100% rename from 2018/day6/day6.py rename to adventofcode/2018/day6/day6.py diff --git a/2018/day7/day7.py b/adventofcode/2018/day7/day7.py similarity index 100% rename from 2018/day7/day7.py rename to adventofcode/2018/day7/day7.py diff --git a/adventofcode/2019/__init__.py b/adventofcode/2019/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/2019/day1/day1.py b/adventofcode/2019/day1/day1.py similarity index 100% rename from 2019/day1/day1.py rename to adventofcode/2019/day1/day1.py diff --git a/2019/day11/day11.py b/adventofcode/2019/day11/day11.py similarity index 100% rename from 2019/day11/day11.py rename to adventofcode/2019/day11/day11.py diff --git a/adventofcode/2019/day13/__init__.py b/adventofcode/2019/day13/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/2019/day13/day13.py b/adventofcode/2019/day13/day13.py similarity index 100% rename from 2019/day13/day13.py rename to adventofcode/2019/day13/day13.py diff --git a/2019/day2/day2.py b/adventofcode/2019/day2/day2.py similarity index 100% rename from 2019/day2/day2.py rename to adventofcode/2019/day2/day2.py diff --git a/2019/day3/day3.py b/adventofcode/2019/day3/day3.py similarity index 96% rename from 2019/day3/day3.py rename to adventofcode/2019/day3/day3.py index 7729105..220e2be 100644 --- a/2019/day3/day3.py +++ b/adventofcode/2019/day3/day3.py @@ -1,79 +1,79 @@ -#!/usr/bin/env python3 - - -def manhattan_distance(p): - return abs(p[0]) + abs(p[1]) - - -def points_for_wire(wire): - x, y, count = 0, 0, 0 - points = {} - # (x, y) - directions = {"R": (1, 0), "L": (-1, 0), "U": (0, 1), "D": (0, -1)} - for p in wire: - # D42 -> for _ in range(42) - for _ in range(int(p[1:])): - offset = directions[p[0]] - x += offset[0] - y += offset[1] - count += 1 - points[(x ,y)] = count - - return points - - -def find_min_distance(wire1, wire2): - points1 = points_for_wire(wire1) - points2 = points_for_wire(wire2) - - intersections = points1.keys() & points2.keys() - closest = min((intersection for intersection in intersections), key=manhattan_distance) - - return manhattan_distance(closest) - - -def find_least_steps(wire1, wire2): - points1 = points_for_wire(wire1) - points2 = points_for_wire(wire2) - - intersections = points1.keys() & points2.keys() - # Intersection with the least steps - least_steps = min(intersections, key=lambda x: points1[x] + points2[x]) - - return points1[least_steps] + points2[least_steps] - - -def tests(): - inputs = ( - (("R8", "U5", "L5", "D3"), ("U7", "R6", "D4", "L4")), - (("R75","D30","R83", "U83", "L12", "D49", "R71", "U7", "L72"), ("U62", "R66", "U55", "R34", "D71", "R55", "D58", "R83")), - (("R98", "U47", "R26", "D63", "R33", "U87", "L62", "D20", "R33", "U53", "R51"), ("U98", "R91", "D20", "R16", "D67", "R40", "U7", "R15", "U6", "R7")) - ) - - # Part 1 - expected = (6, 159, 135) - for i, inp in enumerate(inputs): - result = find_min_distance(inp[0], inp[1]) - assert result == expected[i], "Result for {} should be {}, was {}".format( - inp, expected[i], result - ) - - # Part 2 - # expected number of steps - expected_part2 = (30, 610, 410) - print("All tests passed.") - for i, inp in enumerate(inputs): - result = find_least_steps(inp[0], inp[1]) - assert result == expected_part2[i], "Result for {} should be {}, was {}".format( - inp, expected_part2[i], result - ) - -if __name__ == "__main__": - tests() - import sys - infile = sys.argv[1] if len(sys.argv) > 1 else "example.txt" - with open(infile) as raw_input: - lines = raw_input.readlines() - wire1, wire2 = [line.strip("\n").split(",") for line in lines] - print("Part 1 -- distance = ", find_min_distance(wire1, wire2)) - print("Part 2 -- steps = ", find_least_steps(wire1, wire2)) +#!/usr/bin/env python3 + + +def manhattan_distance(p): + return abs(p[0]) + abs(p[1]) + + +def points_for_wire(wire): + x, y, count = 0, 0, 0 + points = {} + # (x, y) + directions = {"R": (1, 0), "L": (-1, 0), "U": (0, 1), "D": (0, -1)} + for p in wire: + # D42 -> for _ in range(42) + for _ in range(int(p[1:])): + offset = directions[p[0]] + x += offset[0] + y += offset[1] + count += 1 + points[(x ,y)] = count + + return points + + +def find_min_distance(wire1, wire2): + points1 = points_for_wire(wire1) + points2 = points_for_wire(wire2) + + intersections = points1.keys() & points2.keys() + closest = min((intersection for intersection in intersections), key=manhattan_distance) + + return manhattan_distance(closest) + + +def find_least_steps(wire1, wire2): + points1 = points_for_wire(wire1) + points2 = points_for_wire(wire2) + + intersections = points1.keys() & points2.keys() + # Intersection with the least steps + least_steps = min(intersections, key=lambda x: points1[x] + points2[x]) + + return points1[least_steps] + points2[least_steps] + + +def tests(): + inputs = ( + (("R8", "U5", "L5", "D3"), ("U7", "R6", "D4", "L4")), + (("R75","D30","R83", "U83", "L12", "D49", "R71", "U7", "L72"), ("U62", "R66", "U55", "R34", "D71", "R55", "D58", "R83")), + (("R98", "U47", "R26", "D63", "R33", "U87", "L62", "D20", "R33", "U53", "R51"), ("U98", "R91", "D20", "R16", "D67", "R40", "U7", "R15", "U6", "R7")) + ) + + # Part 1 + expected = (6, 159, 135) + for i, inp in enumerate(inputs): + result = find_min_distance(inp[0], inp[1]) + assert result == expected[i], "Result for {} should be {}, was {}".format( + inp, expected[i], result + ) + + # Part 2 + # expected number of steps + expected_part2 = (30, 610, 410) + print("All tests passed.") + for i, inp in enumerate(inputs): + result = find_least_steps(inp[0], inp[1]) + assert result == expected_part2[i], "Result for {} should be {}, was {}".format( + inp, expected_part2[i], result + ) + +if __name__ == "__main__": + tests() + import sys + infile = sys.argv[1] if len(sys.argv) > 1 else "example.txt" + with open(infile) as raw_input: + lines = raw_input.readlines() + wire1, wire2 = [line.strip("\n").split(",") for line in lines] + print("Part 1 -- distance = ", find_min_distance(wire1, wire2)) + print("Part 2 -- steps = ", find_least_steps(wire1, wire2)) diff --git a/2019/day4/day4.py b/adventofcode/2019/day4/day4.py similarity index 100% rename from 2019/day4/day4.py rename to adventofcode/2019/day4/day4.py diff --git a/2019/day5/day5.py b/adventofcode/2019/day5/day5.py similarity index 100% rename from 2019/day5/day5.py rename to adventofcode/2019/day5/day5.py diff --git a/2019/day5/day52.py b/adventofcode/2019/day5/day52.py similarity index 100% rename from 2019/day5/day52.py rename to adventofcode/2019/day5/day52.py diff --git a/2019/day6/day6.py b/adventofcode/2019/day6/day6.py similarity index 100% rename from 2019/day6/day6.py rename to adventofcode/2019/day6/day6.py diff --git a/2019/day7/day7.py b/adventofcode/2019/day7/day7.py similarity index 95% rename from 2019/day7/day7.py rename to adventofcode/2019/day7/day7.py index 040d103..583d59d 100644 --- a/2019/day7/day7.py +++ b/adventofcode/2019/day7/day7.py @@ -1,14 +1,11 @@ import sys from pathlib import Path -# TODO replace PYTHONPATH hack with a proper solution, like making intcode an -# installed module https://stackoverflow.com/a/50194143 sys.path.append(str(Path(__file__).absolute().parent.parent / "intcode")) from itertools import cycle, permutations from intcode import interpret_intcode, Interpreter - def main(inp): mem = list(map(int, inp.readline().rstrip().split(","))) max_ret = 0 diff --git a/2019/day8/day8.py b/adventofcode/2019/day8/day8.py similarity index 100% rename from 2019/day8/day8.py rename to adventofcode/2019/day8/day8.py diff --git a/2019/day9/day9.py b/adventofcode/2019/day9/day9.py similarity index 100% rename from 2019/day9/day9.py rename to adventofcode/2019/day9/day9.py diff --git a/2019/intcode/benchmark.py b/adventofcode/2019/intcode/benchmark.py similarity index 100% rename from 2019/intcode/benchmark.py rename to adventofcode/2019/intcode/benchmark.py diff --git a/2019/intcode/intcode.py b/adventofcode/2019/intcode/intcode.py similarity index 100% rename from 2019/intcode/intcode.py rename to adventofcode/2019/intcode/intcode.py diff --git a/2019/intcode/tests.py b/adventofcode/2019/intcode/tests.py similarity index 100% rename from 2019/intcode/tests.py rename to adventofcode/2019/intcode/tests.py diff --git a/2020/day1/day1.py b/adventofcode/2020/day1/day1.py similarity index 100% rename from 2020/day1/day1.py rename to adventofcode/2020/day1/day1.py diff --git a/2020/day10/day10.py b/adventofcode/2020/day10/day10.py similarity index 100% rename from 2020/day10/day10.py rename to adventofcode/2020/day10/day10.py diff --git a/2020/day11/day11.py b/adventofcode/2020/day11/day11.py similarity index 100% rename from 2020/day11/day11.py rename to adventofcode/2020/day11/day11.py diff --git a/2020/day11/grid.py b/adventofcode/2020/day11/grid.py similarity index 100% rename from 2020/day11/grid.py rename to adventofcode/2020/day11/grid.py diff --git a/2020/day11/rules.py b/adventofcode/2020/day11/rules.py similarity index 100% rename from 2020/day11/rules.py rename to adventofcode/2020/day11/rules.py diff --git a/2020/day14/day14.py b/adventofcode/2020/day14/day14.py similarity index 100% rename from 2020/day14/day14.py rename to adventofcode/2020/day14/day14.py diff --git a/2020/day15/day15.py b/adventofcode/2020/day15/day15.py similarity index 100% rename from 2020/day15/day15.py rename to adventofcode/2020/day15/day15.py diff --git a/2020/day16/day16.py b/adventofcode/2020/day16/day16.py similarity index 100% rename from 2020/day16/day16.py rename to adventofcode/2020/day16/day16.py diff --git a/2020/day2/day2.py b/adventofcode/2020/day2/day2.py similarity index 100% rename from 2020/day2/day2.py rename to adventofcode/2020/day2/day2.py diff --git a/2020/day2/part1.py b/adventofcode/2020/day2/part1.py similarity index 100% rename from 2020/day2/part1.py rename to adventofcode/2020/day2/part1.py diff --git a/2020/day2/part2.py b/adventofcode/2020/day2/part2.py similarity index 100% rename from 2020/day2/part2.py rename to adventofcode/2020/day2/part2.py diff --git a/2020/day3/day3.py b/adventofcode/2020/day3/day3.py similarity index 100% rename from 2020/day3/day3.py rename to adventofcode/2020/day3/day3.py diff --git a/2020/day4/day4.py b/adventofcode/2020/day4/day4.py similarity index 100% rename from 2020/day4/day4.py rename to adventofcode/2020/day4/day4.py diff --git a/2020/day5/day5.py b/adventofcode/2020/day5/day5.py similarity index 100% rename from 2020/day5/day5.py rename to adventofcode/2020/day5/day5.py diff --git a/2020/day5/tests.py b/adventofcode/2020/day5/tests.py similarity index 100% rename from 2020/day5/tests.py rename to adventofcode/2020/day5/tests.py diff --git a/2020/day6/day6.py b/adventofcode/2020/day6/day6.py similarity index 100% rename from 2020/day6/day6.py rename to adventofcode/2020/day6/day6.py diff --git a/2020/day7/day7.py b/adventofcode/2020/day7/day7.py similarity index 100% rename from 2020/day7/day7.py rename to adventofcode/2020/day7/day7.py diff --git a/2020/day8/day8.py b/adventofcode/2020/day8/day8.py similarity index 100% rename from 2020/day8/day8.py rename to adventofcode/2020/day8/day8.py diff --git a/2020/day9/day9.py b/adventofcode/2020/day9/day9.py similarity index 100% rename from 2020/day9/day9.py rename to adventofcode/2020/day9/day9.py diff --git a/2021/day1/day1.py b/adventofcode/2021/day1/day1.py similarity index 100% rename from 2021/day1/day1.py rename to adventofcode/2021/day1/day1.py diff --git a/2021/day2/day2.py b/adventofcode/2021/day2/day2.py similarity index 100% rename from 2021/day2/day2.py rename to adventofcode/2021/day2/day2.py diff --git a/2021/day3/day3.py b/adventofcode/2021/day3/day3.py similarity index 100% rename from 2021/day3/day3.py rename to adventofcode/2021/day3/day3.py diff --git a/2021/day4/day4.py b/adventofcode/2021/day4/day4.py similarity index 100% rename from 2021/day4/day4.py rename to adventofcode/2021/day4/day4.py diff --git a/2021/day5/day5.py b/adventofcode/2021/day5/day5.py similarity index 100% rename from 2021/day5/day5.py rename to adventofcode/2021/day5/day5.py diff --git a/2021/day6/day6.py b/adventofcode/2021/day6/day6.py similarity index 100% rename from 2021/day6/day6.py rename to adventofcode/2021/day6/day6.py diff --git a/2021/day6/day6_2.py b/adventofcode/2021/day6/day6_2.py similarity index 100% rename from 2021/day6/day6_2.py rename to adventofcode/2021/day6/day6_2.py diff --git a/2021/day7/day7.py b/adventofcode/2021/day7/day7.py similarity index 100% rename from 2021/day7/day7.py rename to adventofcode/2021/day7/day7.py diff --git a/2021/day8/day8.py b/adventofcode/2021/day8/day8.py similarity index 100% rename from 2021/day8/day8.py rename to adventofcode/2021/day8/day8.py diff --git a/2022/day1/day1.py b/adventofcode/2022/day1/day1.py similarity index 100% rename from 2022/day1/day1.py rename to adventofcode/2022/day1/day1.py diff --git a/2022/day2/day2.py b/adventofcode/2022/day2/day2.py similarity index 100% rename from 2022/day2/day2.py rename to adventofcode/2022/day2/day2.py diff --git a/2022/day3/day3.py b/adventofcode/2022/day3/day3.py similarity index 100% rename from 2022/day3/day3.py rename to adventofcode/2022/day3/day3.py diff --git a/2022/day4/day4.py b/adventofcode/2022/day4/day4.py similarity index 100% rename from 2022/day4/day4.py rename to adventofcode/2022/day4/day4.py diff --git a/2023/day1/day1.py b/adventofcode/2023/day1/day1.py similarity index 100% rename from 2023/day1/day1.py rename to adventofcode/2023/day1/day1.py diff --git a/2023/day10/day10.py b/adventofcode/2023/day10/day10.py similarity index 100% rename from 2023/day10/day10.py rename to adventofcode/2023/day10/day10.py diff --git a/2023/day2/day2.py b/adventofcode/2023/day2/day2.py similarity index 100% rename from 2023/day2/day2.py rename to adventofcode/2023/day2/day2.py diff --git a/2023/day3/day3.py b/adventofcode/2023/day3/day3.py similarity index 100% rename from 2023/day3/day3.py rename to adventofcode/2023/day3/day3.py diff --git a/2023/day4/day4.py b/adventofcode/2023/day4/day4.py similarity index 100% rename from 2023/day4/day4.py rename to adventofcode/2023/day4/day4.py diff --git a/2023/day5/day5.py b/adventofcode/2023/day5/day5.py similarity index 100% rename from 2023/day5/day5.py rename to adventofcode/2023/day5/day5.py diff --git a/2023/day6/day6.py b/adventofcode/2023/day6/day6.py similarity index 100% rename from 2023/day6/day6.py rename to adventofcode/2023/day6/day6.py diff --git a/2023/day7/day7.py b/adventofcode/2023/day7/day7.py similarity index 100% rename from 2023/day7/day7.py rename to adventofcode/2023/day7/day7.py diff --git a/2023/day8/day8.py b/adventofcode/2023/day8/day8.py similarity index 100% rename from 2023/day8/day8.py rename to adventofcode/2023/day8/day8.py diff --git a/2023/day9/day9.py b/adventofcode/2023/day9/day9.py similarity index 100% rename from 2023/day9/day9.py rename to adventofcode/2023/day9/day9.py diff --git a/2024/day1/day1.py b/adventofcode/2024/day1/day1.py similarity index 100% rename from 2024/day1/day1.py rename to adventofcode/2024/day1/day1.py diff --git a/2024/day10/day10.py b/adventofcode/2024/day10/day10.py similarity index 100% rename from 2024/day10/day10.py rename to adventofcode/2024/day10/day10.py diff --git a/2024/day11/: b/adventofcode/2024/day11/: similarity index 100% rename from 2024/day11/: rename to adventofcode/2024/day11/: diff --git a/2024/day11/day11.py b/adventofcode/2024/day11/day11.py similarity index 100% rename from 2024/day11/day11.py rename to adventofcode/2024/day11/day11.py diff --git a/2024/day12/day12.py b/adventofcode/2024/day12/day12.py similarity index 100% rename from 2024/day12/day12.py rename to adventofcode/2024/day12/day12.py diff --git a/2024/day13/day13.py b/adventofcode/2024/day13/day13.py similarity index 100% rename from 2024/day13/day13.py rename to adventofcode/2024/day13/day13.py diff --git a/2024/day14/day14.py b/adventofcode/2024/day14/day14.py similarity index 100% rename from 2024/day14/day14.py rename to adventofcode/2024/day14/day14.py diff --git a/2024/day15/day15.py b/adventofcode/2024/day15/day15.py similarity index 100% rename from 2024/day15/day15.py rename to adventofcode/2024/day15/day15.py diff --git a/2024/day16/day16.py b/adventofcode/2024/day16/day16.py similarity index 100% rename from 2024/day16/day16.py rename to adventofcode/2024/day16/day16.py diff --git a/2024/day18/day18.py b/adventofcode/2024/day18/day18.py similarity index 100% rename from 2024/day18/day18.py rename to adventofcode/2024/day18/day18.py diff --git a/2024/day2/day2.py b/adventofcode/2024/day2/day2.py similarity index 100% rename from 2024/day2/day2.py rename to adventofcode/2024/day2/day2.py diff --git a/2024/day3/day3.py b/adventofcode/2024/day3/day3.py similarity index 100% rename from 2024/day3/day3.py rename to adventofcode/2024/day3/day3.py diff --git a/2024/day4/day4.py b/adventofcode/2024/day4/day4.py similarity index 100% rename from 2024/day4/day4.py rename to adventofcode/2024/day4/day4.py diff --git a/2024/day5/day5.py b/adventofcode/2024/day5/day5.py similarity index 100% rename from 2024/day5/day5.py rename to adventofcode/2024/day5/day5.py diff --git a/2024/day6/day6.py b/adventofcode/2024/day6/day6.py similarity index 100% rename from 2024/day6/day6.py rename to adventofcode/2024/day6/day6.py diff --git a/2024/day7/day7.py b/adventofcode/2024/day7/day7.py similarity index 100% rename from 2024/day7/day7.py rename to adventofcode/2024/day7/day7.py diff --git a/2024/day8/day8.py b/adventofcode/2024/day8/day8.py similarity index 100% rename from 2024/day8/day8.py rename to adventofcode/2024/day8/day8.py diff --git a/2024/day9/day9.py b/adventofcode/2024/day9/day9.py similarity index 100% rename from 2024/day9/day9.py rename to adventofcode/2024/day9/day9.py diff --git a/adventofcode/aoc.py b/adventofcode/aoc.py new file mode 100644 index 0000000..3fc9343 --- /dev/null +++ b/adventofcode/aoc.py @@ -0,0 +1,41 @@ +import argparse +from adventofcode.helper import run, get_input_file + + +def main(): + parser = argparse.ArgumentParser(description="Advent of Code CLI") + subparsers = parser.add_subparsers(dest='command') + + # Sous-commande init + init_parser = subparsers.add_parser('init', help='Init an aoc day') + init_parser.add_argument('year', type=int) + init_parser.add_argument('day', type=int) + + # Sous-commande run + run_parser = subparsers.add_parser('run', help='Run an aoc day') + run_parser.add_argument('year', type=int) + run_parser.add_argument('day', type=int) + + args = parser.parse_args() + + if args.command == 'init': + handle_init(args.year, args.day) + elif args.command == 'run': + handle_run(args.year, args.day) + else: + parser.print_help() + + +def handle_init(year, day): + # TODO initialize directory if needed, download input file and create + # dayX.py from a template + raise NotImplementedError("init") + + +def handle_run(year, day): + run(year, day) + + +if __name__ == "__main__": + main() + diff --git a/run.py b/adventofcode/helper.py similarity index 86% rename from run.py rename to adventofcode/helper.py index 78d7f97..c4cf508 100644 --- a/run.py +++ b/adventofcode/helper.py @@ -1,3 +1,4 @@ +#!/usr/bin/env python3 import urllib.request import getpass import sys @@ -6,6 +7,7 @@ import subprocess import os from pathlib import Path +ROOTPATH = Path(os.path.dirname(os.path.realpath(__file__))) _auth = None @@ -27,9 +29,9 @@ def get_input_file(year, day): return res -def main(year, day): +def run(year, day): if day is not None: - path = Path(f"{year}/day{day}") + path = ROOTPATH / Path(f"{year}/day{day}") script_path = path / Path(f"day{day}.py") input_path = path / Path("input.txt") if not script_path.exists(): @@ -45,7 +47,7 @@ def main(year, day): run_day(script_path, input_path) else: for day in range(1, 26): - path = Path(f"{year}/day{day}") + path = ROOTPATH / Path(f"{year}/day{day}") script_path = path / Path(f"day{day}.py") input_path = path / Path("input.txt") if script_path.exists(): @@ -69,12 +71,3 @@ def run_day(script_path, input_path): except subprocess.TimeoutExpired: print(f"> timeout {script_path} after 30s", file=sys.stderr) - -if __name__ == "__main__": - if len(sys.argv) <= 1: - print(f"Usage: {__file__} []", file=sys.stderr) - exit(1) - year = sys.argv[1] - day = sys.argv[2] if len(sys.argv) > 2 else None - main(year, day) - diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..1572d73 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,14 @@ +[build-system] +requires = ["setuptools"] +build-backend = "setuptools.build_meta" + +[project] +name = "adventofcode" +version = "1.0.0" + +[project.scripts] +aoc = "adventofcode.aoc:main" + +[tool.setuptools.packages.find] +where = ["."] +