From b7244ad400f2296ae835f592bce32de60f6158e5 Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Tue, 19 Nov 2024 21:57:45 +0100 Subject: [PATCH 1/5] Attempt at a harness --- 2024/README.md | 0 2024/aoc/__init__.py | 0 2024/aoc/__main__.py | 34 +++++++++ 2024/aoc/days/__init__.py | 44 +++++++++++ 2024/aoc/days/day1.py | 13 ++++ 2024/pyproject.toml | 22 ++++++ 2024/uv.lock | 152 ++++++++++++++++++++++++++++++++++++++ 7 files changed, 265 insertions(+) create mode 100644 2024/README.md create mode 100644 2024/aoc/__init__.py create mode 100644 2024/aoc/__main__.py create mode 100644 2024/aoc/days/__init__.py create mode 100644 2024/aoc/days/day1.py create mode 100644 2024/pyproject.toml create mode 100644 2024/uv.lock diff --git a/2024/README.md b/2024/README.md new file mode 100644 index 0000000..e69de29 diff --git a/2024/aoc/__init__.py b/2024/aoc/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/2024/aoc/__main__.py b/2024/aoc/__main__.py new file mode 100644 index 0000000..2fb500d --- /dev/null +++ b/2024/aoc/__main__.py @@ -0,0 +1,34 @@ +import datetime + +import click + +from . import days + + +@click.command() +@click.option( + "-i", + "--input", + "data", + type=click.File(mode="rt", encoding="utf8"), + default="-", + help="Problem input file", +) +@click.option("-t", "--time", is_flag=True, help="Print elapsed time afterwards") +@click.argument("day", required=True) +def main(day: int, time: bool, data: str) -> None: + runner_class = days.get_runner(day) + + start = datetime.datetime.now() + + part1, part2 = runner_class.run_both(data) + + if time: + click.echo(f"Elapsed: {datetime.datetime.now() - start}", err=True) + + click.echo(part1) + click.echo(part2) + + +if __name__ == "__main__": + main() diff --git a/2024/aoc/days/__init__.py b/2024/aoc/days/__init__.py new file mode 100644 index 0000000..cf5cd07 --- /dev/null +++ b/2024/aoc/days/__init__.py @@ -0,0 +1,44 @@ +import importlib +from abc import ABC, abstractmethod +from typing import Any, Tuple, cast + + +class Runner(ABC): + @classmethod + @abstractmethod + def run_both(cls, data: str) -> Tuple[Any, Any]: + pass + + @classmethod + @abstractmethod + def part1(cls, data: str) -> Any: + pass + + @classmethod + @abstractmethod + def part2(cls, data: str) -> Any: + pass + + +class SeparateRunner(Runner): + @classmethod + def run_both(cls, data: str) -> Tuple[Any, Any]: + return (cls.part1(data), cls.part2(data)) + + +class CombinedRunner(Runner): + @classmethod + def part1(cls, data: str) -> Any: + return cls.run_both(data)[0] + + @classmethod + def part2(cls, data: str) -> Any: + return cls.run_both(data)[1] + + +def get_runner(day: int) -> type[Runner]: + runner_module = importlib.import_module(f".day{day}", package=__name__) + + assert issubclass(runner_module.DayRunner, Runner) + + return cast(type[Runner], runner_module.DayRunner) diff --git a/2024/aoc/days/day1.py b/2024/aoc/days/day1.py new file mode 100644 index 0000000..b27f33d --- /dev/null +++ b/2024/aoc/days/day1.py @@ -0,0 +1,13 @@ +from typing import Any + +from . import SeparateRunner + + +class DayRunner(SeparateRunner): + @classmethod + def part1(cls, _data: str) -> Any: + return "Hello" + + @classmethod + def part2(cls, _data: str) -> Any: + return "world!" diff --git a/2024/pyproject.toml b/2024/pyproject.toml new file mode 100644 index 0000000..a0cc789 --- /dev/null +++ b/2024/pyproject.toml @@ -0,0 +1,22 @@ +[project] +name = "aoc-2024" +version = "0.1.0" +description = "Advent of Code 2024 solutions programs" +readme = "README.md" +requires-python = ">=3.12" +dependencies = [ + "click>=8.1.7", + "numpy>=2.1.2", +] + +[dependency-groups] +dev = [ + "mypy>=1.13.0", + "ruff>=0.7.3", +] + +[tool.ruff.lint] +select = ["F", "E", "I"] + +[tool.mypy] +strict = true diff --git a/2024/uv.lock b/2024/uv.lock new file mode 100644 index 0000000..a1999ef --- /dev/null +++ b/2024/uv.lock @@ -0,0 +1,152 @@ +version = 1 +requires-python = ">=3.12" + +[[package]] +name = "aoc-2024" +version = "0.1.0" +source = { virtual = "." } +dependencies = [ + { name = "click" }, + { name = "numpy" }, +] + +[package.dev-dependencies] +dev = [ + { name = "mypy" }, + { name = "ruff" }, +] + +[package.metadata] +requires-dist = [ + { name = "click", specifier = ">=8.1.7" }, + { name = "numpy", specifier = ">=2.1.2" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "mypy", specifier = ">=1.13.0" }, + { name = "ruff", specifier = ">=0.7.3" }, +] + +[[package]] +name = "click" +version = "8.1.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "platform_system == 'Windows'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/96/d3/f04c7bfcf5c1862a2a5b845c6b2b360488cf47af55dfa79c98f6a6bf98b5/click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de", size = 336121 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28", size = 97941 }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "mypy" +version = "1.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e8/21/7e9e523537991d145ab8a0a2fd98548d67646dc2aaaf6091c31ad883e7c1/mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e", size = 3152532 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/31/c526a7bd2e5c710ae47717c7a5f53f616db6d9097caf48ad650581e81748/mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5", size = 11077900 }, + { url = "https://files.pythonhosted.org/packages/83/67/b7419c6b503679d10bd26fc67529bc6a1f7a5f220bbb9f292dc10d33352f/mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e", size = 10074818 }, + { url = "https://files.pythonhosted.org/packages/ba/07/37d67048786ae84e6612575e173d713c9a05d0ae495dde1e68d972207d98/mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2", size = 12589275 }, + { url = "https://files.pythonhosted.org/packages/1f/17/b1018c6bb3e9f1ce3956722b3bf91bff86c1cefccca71cec05eae49d6d41/mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0", size = 13037783 }, + { url = "https://files.pythonhosted.org/packages/cb/32/cd540755579e54a88099aee0287086d996f5a24281a673f78a0e14dba150/mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2", size = 9726197 }, + { url = "https://files.pythonhosted.org/packages/11/bb/ab4cfdc562cad80418f077d8be9b4491ee4fb257440da951b85cbb0a639e/mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7", size = 11069721 }, + { url = "https://files.pythonhosted.org/packages/59/3b/a393b1607cb749ea2c621def5ba8c58308ff05e30d9dbdc7c15028bca111/mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62", size = 10063996 }, + { url = "https://files.pythonhosted.org/packages/d1/1f/6b76be289a5a521bb1caedc1f08e76ff17ab59061007f201a8a18cc514d1/mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8", size = 12584043 }, + { url = "https://files.pythonhosted.org/packages/a6/83/5a85c9a5976c6f96e3a5a7591aa28b4a6ca3a07e9e5ba0cec090c8b596d6/mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7", size = 13036996 }, + { url = "https://files.pythonhosted.org/packages/b4/59/c39a6f752f1f893fccbcf1bdd2aca67c79c842402b5283563d006a67cf76/mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc", size = 9737709 }, + { url = "https://files.pythonhosted.org/packages/3b/86/72ce7f57431d87a7ff17d442f521146a6585019eb8f4f31b7c02801f78ad/mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a", size = 2647043 }, +] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, +] + +[[package]] +name = "numpy" +version = "2.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4b/d1/8a730ea07f4a37d94f9172f4ce1d81064b7a64766b460378be278952de75/numpy-2.1.2.tar.gz", hash = "sha256:13532a088217fa624c99b843eeb54640de23b3414b14aa66d023805eb731066c", size = 18878063 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/7d/554a6838f37f3ada5a55f25173c619d556ae98092a6e01afb6e710501d70/numpy-2.1.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d7bf0a4f9f15b32b5ba53147369e94296f5fffb783db5aacc1be15b4bf72f43b", size = 20848077 }, + { url = "https://files.pythonhosted.org/packages/b0/29/cb48a402ea879e645b16218718f3f7d9588a77d674a9dcf22e4c43487636/numpy-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:b1d0fcae4f0949f215d4632be684a539859b295e2d0cb14f78ec231915d644db", size = 13493242 }, + { url = "https://files.pythonhosted.org/packages/56/44/f899b0581766c230da42f751b7b8896d096640b19b312164c267e48d36cb/numpy-2.1.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:f751ed0a2f250541e19dfca9f1eafa31a392c71c832b6bb9e113b10d050cb0f1", size = 5089219 }, + { url = "https://files.pythonhosted.org/packages/79/8f/b987070d45161a7a4504afc67ed38544ed2c0ed5576263599a0402204a9c/numpy-2.1.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:bd33f82e95ba7ad632bc57837ee99dba3d7e006536200c4e9124089e1bf42426", size = 6620167 }, + { url = "https://files.pythonhosted.org/packages/c4/a7/af3329fda3c3ec31d9b650e42bbcd3422fc62a765cbb1405fde4177a0996/numpy-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1b8cde4f11f0a975d1fd59373b32e2f5a562ade7cde4f85b7137f3de8fbb29a0", size = 13604905 }, + { url = "https://files.pythonhosted.org/packages/9b/b4/e3c7e6fab0f77fff6194afa173d1f2342073d91b1d3b4b30b17c3fb4407a/numpy-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d95f286b8244b3649b477ac066c6906fbb2905f8ac19b170e2175d3d799f4df", size = 16041825 }, + { url = "https://files.pythonhosted.org/packages/e9/50/6828e66a78aa03147c111f84d55f33ce2dde547cb578d6744a3b06a0124b/numpy-2.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ab4754d432e3ac42d33a269c8567413bdb541689b02d93788af4131018cbf366", size = 16409541 }, + { url = "https://files.pythonhosted.org/packages/bf/72/66af7916d9c3c6dbfbc8acdd4930c65461e1953374a2bc43d00f948f004a/numpy-2.1.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e585c8ae871fd38ac50598f4763d73ec5497b0de9a0ab4ef5b69f01c6a046142", size = 14081134 }, + { url = "https://files.pythonhosted.org/packages/dc/5a/59a67d84f33fe00ae74f0b5b69dd4f93a586a4aba7f7e19b54b2133db038/numpy-2.1.2-cp312-cp312-win32.whl", hash = "sha256:9c6c754df29ce6a89ed23afb25550d1c2d5fdb9901d9c67a16e0b16eaf7e2550", size = 6237784 }, + { url = "https://files.pythonhosted.org/packages/4c/79/73735a6a5dad6059c085f240a4e74c9270feccd2bc66e4d31b5ca01d329c/numpy-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:456e3b11cb79ac9946c822a56346ec80275eaf2950314b249b512896c0d2505e", size = 12568254 }, + { url = "https://files.pythonhosted.org/packages/16/72/716fa1dbe92395a9a623d5049203ff8ddb0cfce65b9df9117c3696ccc011/numpy-2.1.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a84498e0d0a1174f2b3ed769b67b656aa5460c92c9554039e11f20a05650f00d", size = 20834690 }, + { url = "https://files.pythonhosted.org/packages/1e/fb/3e85a39511586053b5c6a59a643879e376fae22230ebfef9cfabb0e032e2/numpy-2.1.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4d6ec0d4222e8ffdab1744da2560f07856421b367928026fb540e1945f2eeeaf", size = 13507474 }, + { url = "https://files.pythonhosted.org/packages/35/eb/5677556d9ba13436dab51e129f98d4829d95cd1b6bd0e199c14485a4bdb9/numpy-2.1.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:259ec80d54999cc34cd1eb8ded513cb053c3bf4829152a2e00de2371bd406f5e", size = 5074742 }, + { url = "https://files.pythonhosted.org/packages/3e/c5/6c5ef5ba41b65a7e51bed50dbf3e1483eb578055633dd013e811a28e96a1/numpy-2.1.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:675c741d4739af2dc20cd6c6a5c4b7355c728167845e3c6b0e824e4e5d36a6c3", size = 6606787 }, + { url = "https://files.pythonhosted.org/packages/08/ac/f2f29dd4fd325b379c7dc932a0ebab22f0e031dbe80b2f6019b291a3a544/numpy-2.1.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05b2d4e667895cc55e3ff2b56077e4c8a5604361fc21a042845ea3ad67465aa8", size = 13601333 }, + { url = "https://files.pythonhosted.org/packages/44/26/63f5f4e5089654dfb858f4892215ed968cd1a68e6f4a83f9961f84f855cb/numpy-2.1.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:43cca367bf94a14aca50b89e9bc2061683116cfe864e56740e083392f533ce7a", size = 16038090 }, + { url = "https://files.pythonhosted.org/packages/1d/21/015e0594de9c3a8d5edd24943d2bd23f102ec71aec026083f822f86497e2/numpy-2.1.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:76322dcdb16fccf2ac56f99048af32259dcc488d9b7e25b51e5eca5147a3fb98", size = 16410865 }, + { url = "https://files.pythonhosted.org/packages/df/01/c1bcf9e6025d79077fbf3f3ee503b50aa7bfabfcd8f4b54f5829f4c00f3f/numpy-2.1.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:32e16a03138cabe0cb28e1007ee82264296ac0983714094380b408097a418cfe", size = 14078077 }, + { url = "https://files.pythonhosted.org/packages/ba/06/db9d127d63bd11591770ba9f3d960f8041e0f895184b9351d4b1b5b56983/numpy-2.1.2-cp313-cp313-win32.whl", hash = "sha256:242b39d00e4944431a3cd2db2f5377e15b5785920421993770cddb89992c3f3a", size = 6234904 }, + { url = "https://files.pythonhosted.org/packages/a9/96/9f61f8f95b6e0ea0aa08633b704c75d1882bdcb331bdf8bfd63263b25b00/numpy-2.1.2-cp313-cp313-win_amd64.whl", hash = "sha256:f2ded8d9b6f68cc26f8425eda5d3877b47343e68ca23d0d0846f4d312ecaa445", size = 12561910 }, + { url = "https://files.pythonhosted.org/packages/36/b8/033f627821784a48e8f75c218033471eebbaacdd933f8979c79637a1b44b/numpy-2.1.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ffef621c14ebb0188a8633348504a35c13680d6da93ab5cb86f4e54b7e922b5", size = 20857719 }, + { url = "https://files.pythonhosted.org/packages/96/46/af5726fde5b74ed83f2f17a73386d399319b7ed4d51279fb23b721d0816d/numpy-2.1.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:ad369ed238b1959dfbade9018a740fb9392c5ac4f9b5173f420bd4f37ba1f7a0", size = 13518826 }, + { url = "https://files.pythonhosted.org/packages/db/6e/8ce677edf36da1c4dae80afe5529f47690697eb55b4864673af260ccea7b/numpy-2.1.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d82075752f40c0ddf57e6e02673a17f6cb0f8eb3f587f63ca1eaab5594da5b17", size = 5115036 }, + { url = "https://files.pythonhosted.org/packages/6a/ba/3cce44fb1b8438042c11847048812a776f75ee0e7070179c22e4cfbf420c/numpy-2.1.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:1600068c262af1ca9580a527d43dc9d959b0b1d8e56f8a05d830eea39b7c8af6", size = 6628641 }, + { url = "https://files.pythonhosted.org/packages/59/c8/e722998720ccbd35ffbcf1d1b8ed0aa2304af88d3f1c38e06ebf983599b3/numpy-2.1.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a26ae94658d3ba3781d5e103ac07a876b3e9b29db53f68ed7df432fd033358a8", size = 13574803 }, + { url = "https://files.pythonhosted.org/packages/7c/8e/fc1fdd83a55476765329ac2913321c4aed5b082a7915095628c4ca30ea72/numpy-2.1.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13311c2db4c5f7609b462bc0f43d3c465424d25c626d95040f073e30f7570e35", size = 16021174 }, + { url = "https://files.pythonhosted.org/packages/2a/b6/a790742aa88067adb4bd6c89a946778c1417d4deaeafce3ca928f26d4c52/numpy-2.1.2-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:2abbf905a0b568706391ec6fa15161fad0fb5d8b68d73c461b3c1bab6064dd62", size = 16400117 }, + { url = "https://files.pythonhosted.org/packages/48/6f/129e3c17e3befe7fefdeaa6890f4c4df3f3cf0831aa053802c3862da67aa/numpy-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a", size = 14066202 }, +] + +[[package]] +name = "ruff" +version = "0.7.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4b/06/09d1276df977eece383d0ed66052fc24ec4550a61f8fbc0a11200e690496/ruff-0.7.3.tar.gz", hash = "sha256:e1d1ba2e40b6e71a61b063354d04be669ab0d39c352461f3d789cac68b54a313", size = 3243664 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/56/933d433c2489e4642487b835f53dd9ff015fb3d8fa459b09bb2ce42d7c4b/ruff-0.7.3-py3-none-linux_armv6l.whl", hash = "sha256:34f2339dc22687ec7e7002792d1f50712bf84a13d5152e75712ac08be565d344", size = 10372090 }, + { url = "https://files.pythonhosted.org/packages/20/ea/1f0a22a6bcdd3fc26c73f63a025d05bd565901b729d56bcb093c722a6c4c/ruff-0.7.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:fb397332a1879b9764a3455a0bb1087bda876c2db8aca3a3cbb67b3dbce8cda0", size = 10190037 }, + { url = "https://files.pythonhosted.org/packages/16/74/aca75666e0d481fe394e76a8647c44ea919087748024924baa1a17371e3e/ruff-0.7.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:37d0b619546103274e7f62643d14e1adcbccb242efda4e4bdb9544d7764782e9", size = 9811998 }, + { url = "https://files.pythonhosted.org/packages/20/a1/cf446a0d7f78ea1f0bd2b9171c11dfe746585c0c4a734b25966121eb4f5d/ruff-0.7.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d59f0c3ee4d1a6787614e7135b72e21024875266101142a09a61439cb6e38a5", size = 10620626 }, + { url = "https://files.pythonhosted.org/packages/cd/c1/82b27d09286ae855f5d03b1ad37cf243f21eb0081732d4d7b0d658d439cb/ruff-0.7.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:44eb93c2499a169d49fafd07bc62ac89b1bc800b197e50ff4633aed212569299", size = 10177598 }, + { url = "https://files.pythonhosted.org/packages/b9/42/c0acac22753bf74013d035a5ef6c5c4c40ad4d6686bfb3fda7c6f37d9b37/ruff-0.7.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6d0242ce53f3a576c35ee32d907475a8d569944c0407f91d207c8af5be5dae4e", size = 11171963 }, + { url = "https://files.pythonhosted.org/packages/43/18/bb0befb7fb9121dd9009e6a72eb98e24f1bacb07c6f3ecb55f032ba98aed/ruff-0.7.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6b6224af8b5e09772c2ecb8dc9f3f344c1aa48201c7f07e7315367f6dd90ac29", size = 11856157 }, + { url = "https://files.pythonhosted.org/packages/5e/91/04e98d7d6e32eca9d1372be595f9abc7b7f048795e32eb2edbd8794d50bd/ruff-0.7.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c50f95a82b94421c964fae4c27c0242890a20fe67d203d127e84fbb8013855f5", size = 11440331 }, + { url = "https://files.pythonhosted.org/packages/f5/dc/3fe99f2ce10b76d389041a1b9f99e7066332e479435d4bebcceea16caff5/ruff-0.7.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7f3eff9961b5d2644bcf1616c606e93baa2d6b349e8aa8b035f654df252c8c67", size = 12725354 }, + { url = "https://files.pythonhosted.org/packages/43/7b/1daa712de1c5bc6cbbf9fa60e9c41cc48cda962dc6d2c4f2a224d2c3007e/ruff-0.7.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8963cab06d130c4df2fd52c84e9f10d297826d2e8169ae0c798b6221be1d1d2", size = 11010091 }, + { url = "https://files.pythonhosted.org/packages/b6/db/1227a903587432eb569e57a95b15a4f191a71fe315cde4c0312df7bc85da/ruff-0.7.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:61b46049d6edc0e4317fb14b33bd693245281a3007288b68a3f5b74a22a0746d", size = 10610687 }, + { url = "https://files.pythonhosted.org/packages/db/e2/dc41ee90c3085aadad4da614d310d834f641aaafddf3dfbba08210c616ce/ruff-0.7.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:10ebce7696afe4644e8c1a23b3cf8c0f2193a310c18387c06e583ae9ef284de2", size = 10254843 }, + { url = "https://files.pythonhosted.org/packages/6f/09/5f6cac1c91542bc5bd33d40b4c13b637bf64d7bb29e091dadb01b62527fe/ruff-0.7.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:3f36d56326b3aef8eeee150b700e519880d1aab92f471eefdef656fd57492aa2", size = 10730962 }, + { url = "https://files.pythonhosted.org/packages/d3/42/89a4b9a24ef7d00269e24086c417a006f9a3ffeac2c80f2629eb5ce140ee/ruff-0.7.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:5d024301109a0007b78d57ab0ba190087b43dce852e552734ebf0b0b85e4fb16", size = 11101907 }, + { url = "https://files.pythonhosted.org/packages/b0/5c/efdb4777686683a8edce94ffd812783bddcd3d2454d38c5ac193fef7c500/ruff-0.7.3-py3-none-win32.whl", hash = "sha256:4ba81a5f0c5478aa61674c5a2194de8b02652f17addf8dfc40c8937e6e7d79fc", size = 8611095 }, + { url = "https://files.pythonhosted.org/packages/bb/b8/28fbc6a4efa50178f973972d1c84b2d0a33cdc731588522ab751ac3da2f5/ruff-0.7.3-py3-none-win_amd64.whl", hash = "sha256:588a9ff2fecf01025ed065fe28809cd5a53b43505f48b69a1ac7707b1b7e4088", size = 9418283 }, + { url = "https://files.pythonhosted.org/packages/3f/77/b587cba6febd5e2003374f37eb89633f79f161e71084f94057c8653b7fb3/ruff-0.7.3-py3-none-win_arm64.whl", hash = "sha256:1713e2c5545863cdbfe2cbce21f69ffaf37b813bfd1fb3b90dc9a6f1963f5a8c", size = 8725228 }, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, +] From fd6b58022ddd8c54575b129ac14d74ff405bc9c1 Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Thu, 21 Nov 2024 17:34:32 +0100 Subject: [PATCH 2/5] Review comments --- 2024/aoc/__main__.py | 13 ++++++++----- 2024/aoc/days/__init__.py | 6 +++--- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/2024/aoc/__main__.py b/2024/aoc/__main__.py index 2fb500d..c968a50 100644 --- a/2024/aoc/__main__.py +++ b/2024/aoc/__main__.py @@ -1,4 +1,5 @@ import datetime +import time import click @@ -14,17 +15,19 @@ default="-", help="Problem input file", ) -@click.option("-t", "--time", is_flag=True, help="Print elapsed time afterwards") +@click.option("-t", "--time", "timing", is_flag=True, help="Print elapsed time afterwards") @click.argument("day", required=True) -def main(day: int, time: bool, data: str) -> None: +def main(day: int, timing: bool, data: str) -> None: runner_class = days.get_runner(day) - start = datetime.datetime.now() + start = time.perf_counter_ns() part1, part2 = runner_class.run_both(data) - if time: - click.echo(f"Elapsed: {datetime.datetime.now() - start}", err=True) + if timing: + elapsed = time.perf_counter_ns() - start + delta = datetime.timedelta(microseconds=elapsed / 1000) + click.echo(f"Elapsed: {delta}", err=True) click.echo(part1) click.echo(part2) diff --git a/2024/aoc/days/__init__.py b/2024/aoc/days/__init__.py index cf5cd07..416ed5c 100644 --- a/2024/aoc/days/__init__.py +++ b/2024/aoc/days/__init__.py @@ -1,12 +1,12 @@ import importlib from abc import ABC, abstractmethod -from typing import Any, Tuple, cast +from typing import Any, cast class Runner(ABC): @classmethod @abstractmethod - def run_both(cls, data: str) -> Tuple[Any, Any]: + def run_both(cls, data: str) -> tuple[Any, Any]: pass @classmethod @@ -22,7 +22,7 @@ def part2(cls, data: str) -> Any: class SeparateRunner(Runner): @classmethod - def run_both(cls, data: str) -> Tuple[Any, Any]: + def run_both(cls, data: str) -> tuple[Any, Any]: return (cls.part1(data), cls.part2(data)) From ee5eb931a926dfb75dfce455b3bea73b196d77a6 Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Fri, 22 Nov 2024 10:28:10 +0100 Subject: [PATCH 3/5] Better project setup, now with a structure UV likes --- 2024/pyproject.toml | 4 +++ 2024/{ => src}/aoc/__init__.py | 0 2024/{ => src}/aoc/__main__.py | 2 +- 2024/{ => src}/aoc/days/__init__.py | 0 2024/{ => src}/aoc/days/day1.py | 0 2024/tests/test_harness.py | 6 ++++ 2024/uv.lock | 46 ++++++++++++++++++++++++++++- 7 files changed, 56 insertions(+), 2 deletions(-) rename 2024/{ => src}/aoc/__init__.py (100%) rename 2024/{ => src}/aoc/__main__.py (97%) rename 2024/{ => src}/aoc/days/__init__.py (100%) rename 2024/{ => src}/aoc/days/day1.py (100%) create mode 100644 2024/tests/test_harness.py diff --git a/2024/pyproject.toml b/2024/pyproject.toml index a0cc789..f3333f8 100644 --- a/2024/pyproject.toml +++ b/2024/pyproject.toml @@ -12,9 +12,13 @@ dependencies = [ [dependency-groups] dev = [ "mypy>=1.13.0", + "pytest>=8.3.3", "ruff>=0.7.3", ] +[tool.uv] +package = true + [tool.ruff.lint] select = ["F", "E", "I"] diff --git a/2024/aoc/__init__.py b/2024/src/aoc/__init__.py similarity index 100% rename from 2024/aoc/__init__.py rename to 2024/src/aoc/__init__.py diff --git a/2024/aoc/__main__.py b/2024/src/aoc/__main__.py similarity index 97% rename from 2024/aoc/__main__.py rename to 2024/src/aoc/__main__.py index c968a50..c5a72d3 100644 --- a/2024/aoc/__main__.py +++ b/2024/src/aoc/__main__.py @@ -3,7 +3,7 @@ import click -from . import days +from aoc import days @click.command() diff --git a/2024/aoc/days/__init__.py b/2024/src/aoc/days/__init__.py similarity index 100% rename from 2024/aoc/days/__init__.py rename to 2024/src/aoc/days/__init__.py diff --git a/2024/aoc/days/day1.py b/2024/src/aoc/days/day1.py similarity index 100% rename from 2024/aoc/days/day1.py rename to 2024/src/aoc/days/day1.py diff --git a/2024/tests/test_harness.py b/2024/tests/test_harness.py new file mode 100644 index 0000000..36fafb7 --- /dev/null +++ b/2024/tests/test_harness.py @@ -0,0 +1,6 @@ +from aoc import days + + +def test_harness_works() -> None: + runner = days.get_runner(1) + assert runner is not None diff --git a/2024/uv.lock b/2024/uv.lock index a1999ef..3c62d22 100644 --- a/2024/uv.lock +++ b/2024/uv.lock @@ -4,7 +4,7 @@ requires-python = ">=3.12" [[package]] name = "aoc-2024" version = "0.1.0" -source = { virtual = "." } +source = { editable = "." } dependencies = [ { name = "click" }, { name = "numpy" }, @@ -13,6 +13,7 @@ dependencies = [ [package.dev-dependencies] dev = [ { name = "mypy" }, + { name = "pytest" }, { name = "ruff" }, ] @@ -25,6 +26,7 @@ requires-dist = [ [package.metadata.requires-dev] dev = [ { name = "mypy", specifier = ">=1.13.0" }, + { name = "pytest", specifier = ">=8.3.3" }, { name = "ruff", specifier = ">=0.7.3" }, ] @@ -49,6 +51,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, ] +[[package]] +name = "iniconfig" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, +] + [[package]] name = "mypy" version = "1.13.0" @@ -117,6 +128,39 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/48/6f/129e3c17e3befe7fefdeaa6890f4c4df3f3cf0831aa053802c3862da67aa/numpy-2.1.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ef444c57d664d35cac4e18c298c47d7b504c66b17c2ea91312e979fcfbdfb08a", size = 14066202 }, ] +[[package]] +name = "packaging" +version = "24.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, +] + +[[package]] +name = "pytest" +version = "8.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8b/6c/62bbd536103af674e227c41a8f3dcd022d591f6eed5facb5a0f31ee33bbc/pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181", size = 1442487 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6b/77/7440a06a8ead44c7757a64362dd22df5760f9b12dc5f11b6188cd2fc27a0/pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2", size = 342341 }, +] + [[package]] name = "ruff" version = "0.7.3" From 3d24e50cb329ec83003e1d743d8a3308292db70d Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Fri, 22 Nov 2024 10:42:19 +0100 Subject: [PATCH 4/5] Ci thing --- .github/workflows/2023.yml | 52 -------------------------------------- .github/workflows/2024.yml | 43 +++++++++++++++++++++++++++++++ 2024/src/aoc/__main__.py | 4 ++- 3 files changed, 46 insertions(+), 53 deletions(-) delete mode 100644 .github/workflows/2023.yml create mode 100644 .github/workflows/2024.yml diff --git a/.github/workflows/2023.yml b/.github/workflows/2023.yml deleted file mode 100644 index 1ad8e76..0000000 --- a/.github/workflows/2023.yml +++ /dev/null @@ -1,52 +0,0 @@ -on: - - push - -name: Advent of Code 2023 - -jobs: - ci: - strategy: - matrix: - toolchain: - - stable - - beta - experimental: [false] - include: - - toolchain: nightly - experimental: true - - name: Continuous Integration - runs-on: ubuntu-latest - continue-on-error: ${{ matrix.experimental }} - - steps: - - uses: actions/checkout@v4 - - - name: Install toolchain - uses: dtolnay/rust-toolchain@v1 - with: - profile: minimal - toolchain: ${{ matrix.toolchain }} - override: true - components: rustfmt - - - name: Set up caching - uses: Swatinem/rust-cache@v2 - with: - workspaces: > - 2023 -> target - - - name: Build binaries - working-directory: 2023 - run: > - cargo build --all-targets - - - name: Run tests - working-directory: 2023 - run: > - cargo test - - - name: Check formatting - working-directory: 2023 - run: > - cargo fmt --check diff --git a/.github/workflows/2024.yml b/.github/workflows/2024.yml new file mode 100644 index 0000000..a145ec8 --- /dev/null +++ b/.github/workflows/2024.yml @@ -0,0 +1,43 @@ +on: + - push + +name: Advent of Code 2024 + +jobs: + ci: + strategy: + matrix: + python-version: + - "3.12" + - "3.13" + + name: Continuous Integration + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: ${{ matrix.python-version }} + + - name: Install uv + uses: astral-sh/setup-uv@v3 + with: + enable-cache: true + cache-dependency-glob: "2024/uv.lock" + + - name: Check formatting + working-directory: "2024" + run: > + uv run ruff format --check + + - name: Run lints + working-directory: "2024" + run: > + uv run ruff check + + - name: Run tests + working-directory: "2024" + run: > + uv run pytest tests diff --git a/2024/src/aoc/__main__.py b/2024/src/aoc/__main__.py index c5a72d3..88467ba 100644 --- a/2024/src/aoc/__main__.py +++ b/2024/src/aoc/__main__.py @@ -15,7 +15,9 @@ default="-", help="Problem input file", ) -@click.option("-t", "--time", "timing", is_flag=True, help="Print elapsed time afterwards") +@click.option( + "-t", "--time", "timing", is_flag=True, help="Print elapsed time afterwards" +) @click.argument("day", required=True) def main(day: int, timing: bool, data: str) -> None: runner_class = days.get_runner(day) From eef637f0066357f5ad1fb806dc427b69200d23b2 Mon Sep 17 00:00:00 2001 From: Bert Peters Date: Fri, 22 Nov 2024 10:45:53 +0100 Subject: [PATCH 5/5] Remove old unused CI I'm never going to finish that rework anyway --- .github/workflows/2019.yml | 18 ------------------ 1 file changed, 18 deletions(-) delete mode 100644 .github/workflows/2019.yml diff --git a/.github/workflows/2019.yml b/.github/workflows/2019.yml deleted file mode 100644 index bcdb82b..0000000 --- a/.github/workflows/2019.yml +++ /dev/null @@ -1,18 +0,0 @@ -name: AOC 2019 test suite -on: - push: - -jobs: - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - with: - python-version: 3.9 - - name: Install dependencies - run: | - python -m pip install --upgrade pip - pip install -r 2019/requirements.txt - - name: Run Pytest - run: pytest 2019