Fix linting.

This commit is contained in:
Mikael CAPELLE 2024-12-03 14:11:29 +01:00
parent cb0145baa2
commit acb767184e
49 changed files with 1160 additions and 353 deletions

4
.gitignore vendored
View File

@ -1,2 +1,6 @@
# python / VS Code
venv
__pycache__
.ruff_cache
.vscode
build

329
poetry.lock generated
View File

@ -26,52 +26,6 @@ files = [
astroid = ["astroid (>=2,<4)"]
test = ["astroid (>=2,<4)", "pytest", "pytest-cov", "pytest-xdist"]
[[package]]
name = "black"
version = "24.10.0"
description = "The uncompromising code formatter."
optional = false
python-versions = ">=3.9"
files = [
{file = "black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812"},
{file = "black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea"},
{file = "black-24.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:649fff99a20bd06c6f727d2a27f401331dc0cc861fb69cde910fe95b01b5928f"},
{file = "black-24.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:fe4d6476887de70546212c99ac9bd803d90b42fc4767f058a0baa895013fbb3e"},
{file = "black-24.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5a2221696a8224e335c28816a9d331a6c2ae15a2ee34ec857dcf3e45dbfa99ad"},
{file = "black-24.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9da3333530dbcecc1be13e69c250ed8dfa67f43c4005fb537bb426e19200d50"},
{file = "black-24.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4007b1393d902b48b36958a216c20c4482f601569d19ed1df294a496eb366392"},
{file = "black-24.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:394d4ddc64782e51153eadcaaca95144ac4c35e27ef9b0a42e121ae7e57a9175"},
{file = "black-24.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e39e0fae001df40f95bd8cc36b9165c5e2ea88900167bddf258bacef9bbdc3"},
{file = "black-24.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d37d422772111794b26757c5b55a3eade028aa3fde43121ab7b673d050949d65"},
{file = "black-24.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14b3502784f09ce2443830e3133dacf2c0110d45191ed470ecb04d0f5f6fcb0f"},
{file = "black-24.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:30d2c30dc5139211dda799758559d1b049f7f14c580c409d6ad925b74a4208a8"},
{file = "black-24.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cbacacb19e922a1d75ef2b6ccaefcd6e93a2c05ede32f06a21386a04cedb981"},
{file = "black-24.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f93102e0c5bb3907451063e08b9876dbeac810e7da5a8bfb7aeb5a9ef89066b"},
{file = "black-24.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ddacb691cdcdf77b96f549cf9591701d8db36b2f19519373d60d31746068dbf2"},
{file = "black-24.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:680359d932801c76d2e9c9068d05c6b107f2584b2a5b88831c83962eb9984c1b"},
{file = "black-24.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:17374989640fbca88b6a448129cd1745c5eb8d9547b464f281b251dd00155ccd"},
{file = "black-24.10.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:63f626344343083322233f175aaf372d326de8436f5928c042639a4afbbf1d3f"},
{file = "black-24.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfa1d0cb6200857f1923b602f978386a3a2758a65b52e0950299ea014be6800"},
{file = "black-24.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:2cd9c95431d94adc56600710f8813ee27eea544dd118d45896bb734e9d7a0dc7"},
{file = "black-24.10.0-py3-none-any.whl", hash = "sha256:3bb2b7a1f7b685f85b11fed1ef10f8a9148bceb49853e47a294a3dd963c1dd7d"},
{file = "black-24.10.0.tar.gz", hash = "sha256:846ea64c97afe3bc677b761787993be4991810ecc7a4a937816dd6bddedc4875"},
]
[package.dependencies]
click = ">=8.0.0"
mypy-extensions = ">=0.4.3"
packaging = ">=22.0"
pathspec = ">=0.9.0"
platformdirs = ">=2"
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""}
[package.extras]
colorama = ["colorama (>=0.4.3)"]
d = ["aiohttp (>=3.10)"]
jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"]
uvloop = ["uvloop (>=0.15.2)"]
[[package]]
name = "cffi"
version = "1.17.1"
@ -151,20 +105,6 @@ files = [
[package.dependencies]
pycparser = "*"
[[package]]
name = "click"
version = "8.1.7"
description = "Composable command line interface toolkit"
optional = false
python-versions = ">=3.7"
files = [
{file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
{file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
]
[package.dependencies]
colorama = {version = "*", markers = "platform_system == \"Windows\""}
[[package]]
name = "colorama"
version = "0.4.6"
@ -267,41 +207,6 @@ files = [
[package.extras]
tests = ["asttokens (>=2.1.0)", "coverage", "coverage-enable-subprocess", "ipython", "littleutils", "pytest", "rich"]
[[package]]
name = "flake8"
version = "7.1.1"
description = "the modular source code checker: pep8 pyflakes and co"
optional = false
python-versions = ">=3.8.1"
files = [
{file = "flake8-7.1.1-py2.py3-none-any.whl", hash = "sha256:597477df7860daa5aa0fdd84bf5208a043ab96b8e96ab708770ae0364dd03213"},
{file = "flake8-7.1.1.tar.gz", hash = "sha256:049d058491e228e03e67b390f311bbf88fce2dbaa8fa673e7aea87b7198b8d38"},
]
[package.dependencies]
mccabe = ">=0.7.0,<0.8.0"
pycodestyle = ">=2.12.0,<2.13.0"
pyflakes = ">=3.2.0,<3.3.0"
[[package]]
name = "flake8-black"
version = "0.3.6"
description = "flake8 plugin to call black as a code style validator"
optional = false
python-versions = ">=3.7"
files = [
{file = "flake8-black-0.3.6.tar.gz", hash = "sha256:0dfbca3274777792a5bcb2af887a4cad72c72d0e86c94e08e3a3de151bb41c34"},
{file = "flake8_black-0.3.6-py3-none-any.whl", hash = "sha256:fe8ea2eca98d8a504f22040d9117347f6b367458366952862ac3586e7d4eeaca"},
]
[package.dependencies]
black = ">=22.1.0"
flake8 = ">=3"
tomli = {version = "*", markers = "python_version < \"3.11\""}
[package.extras]
develop = ["build", "twine"]
[[package]]
name = "ipykernel"
version = "6.29.5"
@ -373,20 +278,6 @@ qtconsole = ["qtconsole"]
test = ["packaging", "pickleshare", "pytest", "pytest-asyncio (<0.22)", "testpath"]
test-extra = ["curio", "ipython[test]", "matplotlib (!=3.2.0)", "nbformat", "numpy (>=1.23)", "pandas", "trio"]
[[package]]
name = "isort"
version = "5.13.2"
description = "A Python utility / library to sort Python imports."
optional = false
python-versions = ">=3.8.0"
files = [
{file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"},
{file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"},
]
[package.extras]
colors = ["colorama (>=0.4.6)"]
[[package]]
name = "jedi"
version = "0.19.2"
@ -462,17 +353,6 @@ files = [
[package.dependencies]
traitlets = "*"
[[package]]
name = "mccabe"
version = "0.7.0"
description = "McCabe checker, plugin for flake8"
optional = false
python-versions = ">=3.6"
files = [
{file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
{file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
]
[[package]]
name = "mpmath"
version = "1.3.0"
@ -490,70 +370,6 @@ docs = ["sphinx"]
gmpy = ["gmpy2 (>=2.1.0a4)"]
tests = ["pytest (>=4.6)"]
[[package]]
name = "mypy"
version = "1.13.0"
description = "Optional static typing for Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "mypy-1.13.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6607e0f1dd1fb7f0aca14d936d13fd19eba5e17e1cd2a14f808fa5f8f6d8f60a"},
{file = "mypy-1.13.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8a21be69bd26fa81b1f80a61ee7ab05b076c674d9b18fb56239d72e21d9f4c80"},
{file = "mypy-1.13.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7b2353a44d2179846a096e25691d54d59904559f4232519d420d64da6828a3a7"},
{file = "mypy-1.13.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:0730d1c6a2739d4511dc4253f8274cdd140c55c32dfb0a4cf8b7a43f40abfa6f"},
{file = "mypy-1.13.0-cp310-cp310-win_amd64.whl", hash = "sha256:c5fc54dbb712ff5e5a0fca797e6e0aa25726c7e72c6a5850cfd2adbc1eb0a372"},
{file = "mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d"},
{file = "mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d"},
{file = "mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b"},
{file = "mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73"},
{file = "mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca"},
{file = "mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5"},
{file = "mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e"},
{file = "mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2"},
{file = "mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0"},
{file = "mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2"},
{file = "mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7"},
{file = "mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62"},
{file = "mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8"},
{file = "mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7"},
{file = "mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc"},
{file = "mypy-1.13.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:100fac22ce82925f676a734af0db922ecfea991e1d7ec0ceb1e115ebe501301a"},
{file = "mypy-1.13.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:7bcb0bb7f42a978bb323a7c88f1081d1b5dee77ca86f4100735a6f541299d8fb"},
{file = "mypy-1.13.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bde31fc887c213e223bbfc34328070996061b0833b0a4cfec53745ed61f3519b"},
{file = "mypy-1.13.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:07de989f89786f62b937851295ed62e51774722e5444a27cecca993fc3f9cd74"},
{file = "mypy-1.13.0-cp38-cp38-win_amd64.whl", hash = "sha256:4bde84334fbe19bad704b3f5b78c4abd35ff1026f8ba72b29de70dda0916beb6"},
{file = "mypy-1.13.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0246bcb1b5de7f08f2826451abd947bf656945209b140d16ed317f65a17dc7dc"},
{file = "mypy-1.13.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7f5b7deae912cf8b77e990b9280f170381fdfbddf61b4ef80927edd813163732"},
{file = "mypy-1.13.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7029881ec6ffb8bc233a4fa364736789582c738217b133f1b55967115288a2bc"},
{file = "mypy-1.13.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:3e38b980e5681f28f033f3be86b099a247b13c491f14bb8b1e1e134d23bb599d"},
{file = "mypy-1.13.0-cp39-cp39-win_amd64.whl", hash = "sha256:a6789be98a2017c912ae6ccb77ea553bbaf13d27605d2ca20a76dfbced631b24"},
{file = "mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a"},
{file = "mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e"},
]
[package.dependencies]
mypy-extensions = ">=1.0.0"
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
typing-extensions = ">=4.6.0"
[package.extras]
dmypy = ["psutil (>=4.0)"]
faster-cache = ["orjson"]
install-types = ["pip"]
mypyc = ["setuptools (>=50)"]
reports = ["lxml"]
[[package]]
name = "mypy-extensions"
version = "1.0.0"
description = "Type system extensions for programs checked with the mypy type checker."
optional = false
python-versions = ">=3.5"
files = [
{file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
{file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
]
[[package]]
name = "nest-asyncio"
version = "1.6.0"
@ -810,17 +626,6 @@ files = [
{file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"},
]
[[package]]
name = "pathspec"
version = "0.12.1"
description = "Utility library for gitignore style pattern matching of file paths."
optional = false
python-versions = ">=3.8"
files = [
{file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"},
{file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"},
]
[[package]]
name = "pexpect"
version = "4.9.0"
@ -853,18 +658,19 @@ type = ["mypy (>=1.11.2)"]
[[package]]
name = "poethepoet"
version = "0.24.4"
version = "0.31.1"
description = "A task runner that works well with poetry."
optional = false
python-versions = ">=3.8"
python-versions = ">=3.9"
files = [
{file = "poethepoet-0.24.4-py3-none-any.whl", hash = "sha256:fb4ea35d7f40fe2081ea917d2e4102e2310fda2cde78974050ca83896e229075"},
{file = "poethepoet-0.24.4.tar.gz", hash = "sha256:ff4220843a87c888cbcb5312c8905214701d0af60ac7271795baa8369b428fef"},
{file = "poethepoet-0.31.1-py3-none-any.whl", hash = "sha256:7fdfa0ac6074be9936723e7231b5bfaad2923e96c674a9857e81d326cf8ccdc2"},
{file = "poethepoet-0.31.1.tar.gz", hash = "sha256:d6b66074edf85daf115bb916eae0afd6387d19e1562e1c9ef7d61d5c585696aa"},
]
[package.dependencies]
pastel = ">=0.2.1,<0.3.0"
tomli = ">=1.2.2"
pyyaml = ">=6.0.2,<7.0.0"
tomli = {version = ">=1.2.2", markers = "python_version < \"3.11\""}
[package.extras]
poetry-plugin = ["poetry (>=1.0,<2.0)"]
@ -938,17 +744,6 @@ files = [
[package.extras]
tests = ["pytest"]
[[package]]
name = "pycodestyle"
version = "2.12.1"
description = "Python style guide checker"
optional = false
python-versions = ">=3.8"
files = [
{file = "pycodestyle-2.12.1-py2.py3-none-any.whl", hash = "sha256:46f0fb92069a7c28ab7bb558f05bfc0110dac69a0cd23c61ea0040283a9d78b3"},
{file = "pycodestyle-2.12.1.tar.gz", hash = "sha256:6838eae08bbce4f6accd5d5572075c63626a15ee3e6f842df996bf62f6d73521"},
]
[[package]]
name = "pycparser"
version = "2.22"
@ -960,17 +755,6 @@ files = [
{file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"},
]
[[package]]
name = "pyflakes"
version = "3.2.0"
description = "passive checker of Python programs"
optional = false
python-versions = ">=3.8"
files = [
{file = "pyflakes-3.2.0-py2.py3-none-any.whl", hash = "sha256:84b5be138a2dfbb40689ca07e2152deb896a65c3a3e24c251c5c62489568074a"},
{file = "pyflakes-3.2.0.tar.gz", hash = "sha256:1c61603ff154621fb2a9172037d84dca3500def8c8b630657d1701f026f8af3f"},
]
[[package]]
name = "pygments"
version = "2.18.0"
@ -1057,6 +841,68 @@ files = [
{file = "pywin32-308-cp39-cp39-win_amd64.whl", hash = "sha256:71b3322d949b4cc20776436a9c9ba0eeedcbc9c650daa536df63f0ff111bb920"},
]
[[package]]
name = "pyyaml"
version = "6.0.2"
description = "YAML parser and emitter for Python"
optional = false
python-versions = ">=3.8"
files = [
{file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"},
{file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"},
{file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"},
{file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"},
{file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"},
{file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"},
{file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"},
{file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"},
{file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"},
{file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"},
{file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"},
{file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"},
{file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"},
{file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"},
{file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"},
{file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"},
{file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"},
{file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"},
{file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"},
{file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"},
{file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"},
{file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"},
{file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"},
{file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"},
{file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"},
{file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"},
{file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"},
{file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"},
{file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"},
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"},
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"},
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"},
{file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"},
{file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"},
{file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"},
{file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"},
{file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"},
{file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"},
{file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"},
{file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"},
{file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"},
{file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"},
{file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"},
{file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"},
{file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"},
{file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"},
{file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"},
{file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"},
{file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"},
{file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"},
{file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"},
{file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"},
{file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"},
]
[[package]]
name = "pyzmq"
version = "26.2.0"
@ -1180,28 +1026,29 @@ cffi = {version = "*", markers = "implementation_name == \"pypy\""}
[[package]]
name = "ruff"
version = "0.1.15"
version = "0.8.1"
description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
files = [
{file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5fe8d54df166ecc24106db7dd6a68d44852d14eb0729ea4672bb4d96c320b7df"},
{file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6f0bfbb53c4b4de117ac4d6ddfd33aa5fc31beeaa21d23c45c6dd249faf9126f"},
{file = "ruff-0.1.15-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0d432aec35bfc0d800d4f70eba26e23a352386be3a6cf157083d18f6f5881c8"},
{file = "ruff-0.1.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9405fa9ac0e97f35aaddf185a1be194a589424b8713e3b97b762336ec79ff807"},
{file = "ruff-0.1.15-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c66ec24fe36841636e814b8f90f572a8c0cb0e54d8b5c2d0e300d28a0d7bffec"},
{file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6f8ad828f01e8dd32cc58bc28375150171d198491fc901f6f98d2a39ba8e3ff5"},
{file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86811954eec63e9ea162af0ffa9f8d09088bab51b7438e8b6488b9401863c25e"},
{file = "ruff-0.1.15-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd4025ac5e87d9b80e1f300207eb2fd099ff8200fa2320d7dc066a3f4622dc6b"},
{file = "ruff-0.1.15-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b17b93c02cdb6aeb696effecea1095ac93f3884a49a554a9afa76bb125c114c1"},
{file = "ruff-0.1.15-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ddb87643be40f034e97e97f5bc2ef7ce39de20e34608f3f829db727a93fb82c5"},
{file = "ruff-0.1.15-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:abf4822129ed3a5ce54383d5f0e964e7fef74a41e48eb1dfad404151efc130a2"},
{file = "ruff-0.1.15-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6c629cf64bacfd136c07c78ac10a54578ec9d1bd2a9d395efbee0935868bf852"},
{file = "ruff-0.1.15-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1bab866aafb53da39c2cadfb8e1c4550ac5340bb40300083eb8967ba25481447"},
{file = "ruff-0.1.15-py3-none-win32.whl", hash = "sha256:2417e1cb6e2068389b07e6fa74c306b2810fe3ee3476d5b8a96616633f40d14f"},
{file = "ruff-0.1.15-py3-none-win_amd64.whl", hash = "sha256:3837ac73d869efc4182d9036b1405ef4c73d9b1f88da2413875e34e0d6919587"},
{file = "ruff-0.1.15-py3-none-win_arm64.whl", hash = "sha256:9a933dfb1c14ec7a33cceb1e49ec4a16b51ce3c20fd42663198746efc0427360"},
{file = "ruff-0.1.15.tar.gz", hash = "sha256:f6dfa8c1b21c913c326919056c390966648b680966febcb796cc9d1aaab8564e"},
{file = "ruff-0.8.1-py3-none-linux_armv6l.whl", hash = "sha256:fae0805bd514066f20309f6742f6ee7904a773eb9e6c17c45d6b1600ca65c9b5"},
{file = "ruff-0.8.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8a4f7385c2285c30f34b200ca5511fcc865f17578383db154e098150ce0a087"},
{file = "ruff-0.8.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cd054486da0c53e41e0086e1730eb77d1f698154f910e0cd9e0d64274979a209"},
{file = "ruff-0.8.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2029b8c22da147c50ae577e621a5bfbc5d1fed75d86af53643d7a7aee1d23871"},
{file = "ruff-0.8.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2666520828dee7dfc7e47ee4ea0d928f40de72056d929a7c5292d95071d881d1"},
{file = "ruff-0.8.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:333c57013ef8c97a53892aa56042831c372e0bb1785ab7026187b7abd0135ad5"},
{file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:288326162804f34088ac007139488dcb43de590a5ccfec3166396530b58fb89d"},
{file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b12c39b9448632284561cbf4191aa1b005882acbc81900ffa9f9f471c8ff7e26"},
{file = "ruff-0.8.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:364e6674450cbac8e998f7b30639040c99d81dfb5bbc6dfad69bc7a8f916b3d1"},
{file = "ruff-0.8.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b22346f845fec132aa39cd29acb94451d030c10874408dbf776af3aaeb53284c"},
{file = "ruff-0.8.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b2f2f7a7e7648a2bfe6ead4e0a16745db956da0e3a231ad443d2a66a105c04fa"},
{file = "ruff-0.8.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:adf314fc458374c25c5c4a4a9270c3e8a6a807b1bec018cfa2813d6546215540"},
{file = "ruff-0.8.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a885d68342a231b5ba4d30b8c6e1b1ee3a65cf37e3d29b3c74069cdf1ee1e3c9"},
{file = "ruff-0.8.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d2c16e3508c8cc73e96aa5127d0df8913d2290098f776416a4b157657bee44c5"},
{file = "ruff-0.8.1-py3-none-win32.whl", hash = "sha256:93335cd7c0eaedb44882d75a7acb7df4b77cd7cd0d2255c93b28791716e81790"},
{file = "ruff-0.8.1-py3-none-win_amd64.whl", hash = "sha256:2954cdbe8dfd8ab359d4a30cd971b589d335a44d444b6ca2cb3d1da21b75e4b6"},
{file = "ruff-0.8.1-py3-none-win_arm64.whl", hash = "sha256:55873cc1a473e5ac129d15eccb3c008c096b94809d693fc7053f588b67822737"},
{file = "ruff-0.8.1.tar.gz", hash = "sha256:3583db9a6450364ed5ca3f3b4225958b24f78178908d5c4bc0f46251ccca898f"},
]
[[package]]
@ -1434,4 +1281,4 @@ files = [
[metadata]
lock-version = "2.0"
python-versions = "^3.10"
content-hash = "f30e6716b379f51af355d186d036726fb112457b561862a73c58c2ea47cb2a2a"
content-hash = "b643261f91a781d77735e05f6d2ac1002867600c2df6393a9d1a15f5e1189109"

View File

@ -17,35 +17,25 @@ sympy = "^1.13.3"
networkx = "^3.4.2"
pandas = "^2.2.3"
[tool.poetry.group.dev.dependencies]
pyright = "^1.1.389"
ruff = "^0.8.1"
poethepoet = "^0.31.1"
ipykernel = "^6.29.5"
networkx-stubs = "^0.0.1"
[tool.poetry.scripts]
holt59-aoc = "holt59.aoc.__main__:main"
[tool.poe.tasks]
lint-black = "black --check --diff src tests typings"
lint-isort = "isort -c src tests typings"
lint-ruff = "ruff src tests typings"
lint-flake8 = "flake8 src tests typings"
lint-pyright = "pyright src tests"
lint-all.sequence = [
"lint-black",
"lint-isort",
"lint-flake8",
"lint-ruff",
"lint-pyright",
]
lint-all.ignore_fail = "return_non_zero"
[tool.poetry.group.dev.dependencies]
flake8 = "^7.1.1"
flake8-black = "^0.3.6"
black = "^24.10.0"
pyright = "^1.1.389"
mypy = "^1.13.0"
isort = "^5.13.2"
ruff = "^0.1.8"
poethepoet = "^0.24.4"
ipykernel = "^6.29.5"
networkx-stubs = "^0.0.1"
format-imports = "ruff check --select I src --fix"
format-ruff = "ruff format src"
format.sequence = ["format-imports", "format-ruff"]
lint-ruff = "ruff check src"
lint-ruff-format = "ruff format --check src"
lint-pyright = "pyright src"
lint.sequence = ["lint-ruff", "lint-ruff-format", "lint-pyright"]
lint.ignore_fail = "return_non_zero"
[build-system]
requires = ["poetry-core"]

View File

@ -2,7 +2,7 @@ from __future__ import annotations
import heapq
import sys
from typing import Literal, TypeAlias
from typing import Literal, TypeAlias, cast
PlayerType: TypeAlias = Literal["player", "boss"]
SpellType: TypeAlias = Literal["magic missile", "drain", "shield", "poison", "recharge"]
@ -18,6 +18,16 @@ Node: TypeAlias = tuple[
tuple[tuple[SpellType, int], ...],
]
ATTACK_SPELLS: list[tuple[SpellType, int, int, int]] = [
("magic missile", 53, 4, 0),
("drain", 73, 2, 2),
]
BUFF_SPELLS: list[tuple[BuffType, int, int]] = [
("shield", 113, 6),
("poison", 173, 6),
("recharge", 229, 5),
]
def play(
player_hp: int,
@ -97,10 +107,7 @@ def play(
else:
buff_types = {b for b, _ in buffs}
for spell, cost, damage, regeneration in (
("magic missile", 53, 4, 0),
("drain", 73, 2, 2),
):
for spell, cost, damage, regeneration in ATTACK_SPELLS:
if player_mana < cost:
continue
@ -114,15 +121,11 @@ def play(
player_armor,
max(0, boss_hp - damage),
buffs,
spells + ((spell, cost),),
spells + cast("tuple[tuple[SpellType, int]]", ((spell, cost),)),
),
)
for buff_type, buff_cost, buff_length in (
("shield", 113, 6),
("poison", 173, 6),
("recharge", 229, 5),
):
for buff_type, buff_cost, buff_length in BUFF_SPELLS:
if buff_type in buff_types:
continue
@ -138,8 +141,14 @@ def play(
player_mana - buff_cost,
player_armor + 7 * (buff_type == "shield"),
boss_hp,
buffs + ((buff_type, buff_length),),
spells + ((buff_type, buff_cost),),
buffs
+ cast(
"tuple[tuple[BuffType, int]]", ((buff_type, buff_length),)
),
spells
+ cast(
"tuple[tuple[SpellType, int]]", ((buff_type, buff_cost),)
),
),
)

View File

@ -10,7 +10,8 @@ lines = sys.stdin.read().splitlines()
distances: dict[str, dict[str, int]] = defaultdict(dict)
for line in lines:
origin, destination, length = cast(
tuple[str, str, int], parse.parse("{} to {} = {:d}", line) # type: ignore
tuple[str, str, int],
parse.parse("{} to {} = {:d}", line), # type: ignore
)
distances[origin][destination] = distances[destination][origin] = length

View File

@ -1,6 +1,4 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()

View File

@ -1,6 +1,4 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()

View File

@ -1,6 +1,4 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()

View File

@ -1,6 +1,4 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()

View File

@ -1,6 +1,4 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()

View File

@ -1,6 +1,4 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()

View File

@ -1,6 +1,4 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()

View File

@ -1,6 +1,4 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()

View File

@ -1,6 +1,4 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()

View File

@ -1,6 +1,4 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()

View File

@ -1,12 +1,13 @@
import sys
from math import prod
from typing import Literal, cast
from typing import Literal, TypeAlias, cast
lines = sys.stdin.read().splitlines()
commands = [
(cast(Literal["forward", "up", "down"], (p := line.split())[0]), int(p[1]))
for line in lines
Command: TypeAlias = Literal["forward", "up", "down"]
commands: list[tuple[Command, int]] = [
(cast(Command, (p := line.split())[0]), int(p[1])) for line in lines
]

View File

@ -1,6 +1,4 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()

View File

@ -1,6 +1,4 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()

View File

@ -1,6 +1,4 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()

View File

@ -1,6 +1,4 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()

View File

@ -1,6 +1,4 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()

View File

@ -1,6 +1,4 @@
import sys
from collections import defaultdict
from dataclasses import dataclass
lines = sys.stdin.read().splitlines()

View File

@ -1,21 +1,19 @@
import sys
import numpy as np
positions = [int(c) for c in sys.stdin.read().strip().split(",")]
positions = np.asarray([int(c) for c in sys.stdin.read().strip().split(",")])
min_position, max_position = positions.min(), positions.max()
min_position, max_position = min(positions), max(positions)
# part 1
answer_1 = min(
np.sum(np.abs(positions - position))
sum(abs(p - position) for p in positions)
for position in range(min_position, max_position + 1)
)
print(f"answer 1 is {answer_1}")
# part 2
answer_2 = min(
np.sum(abs(positions - position) * (abs(positions - position) + 1) // 2)
sum(abs(p - position) * (abs(p - position) + 1) // 2 for p in positions)
for position in range(min_position, max_position + 1)
)
print(f"answer 2 is {answer_2}")

View File

@ -122,8 +122,8 @@ lines = sys.stdin.read().splitlines()
grid = [[ord(cell) - ord("a") for cell in line] for line in lines]
start: tuple[int, int]
end: tuple[int, int]
start: tuple[int, int] | None = None
end: tuple[int, int] | None = None
# for part 2
start_s: list[tuple[int, int]] = []
@ -138,6 +138,9 @@ for i_row, row in enumerate(grid):
elif col == 0:
start_s.append((i_row, i_col))
assert start is not None
assert end is not None
# fix values
grid[start[0]][start[1]] = 0
grid[end[0]][end[1]] = ord("z") - ord("a")

View File

@ -1,20 +1,22 @@
import sys
from typing import Any
import numpy as np
import parse
import parse # type: ignore
from numpy.typing import NDArray
def part1(sensor_to_beacon: dict[tuple[int, int], tuple[int, int]], row: int) -> int:
no_beacons_row_l: list[np.ndarray] = []
no_beacons_row_l: list[NDArray[np.floating[Any]]] = []
for (sx, sy), (bx, by) in sensor_to_beacon.items():
d = abs(sx - bx) + abs(sy - by) # closest
no_beacons_row_l.append(sx - np.arange(0, d - abs(sy - row) + 1))
no_beacons_row_l.append(sx + np.arange(0, d - abs(sy - row) + 1))
no_beacons_row_l.append(sx - np.arange(0, d - abs(sy - row) + 1)) # type: ignore
no_beacons_row_l.append(sx + np.arange(0, d - abs(sy - row) + 1)) # type: ignore
beacons_at_row = set(bx for (bx, by) in sensor_to_beacon.values() if by == row)
no_beacons_row = set(np.concatenate(no_beacons_row_l)).difference(beacons_at_row)
no_beacons_row = set(np.concatenate(no_beacons_row_l)).difference(beacons_at_row) # type: ignore
return len(no_beacons_row)
@ -56,11 +58,12 @@ def part2_cplex(
for (sx, sy), (bx, by) in sensor_to_beacon.items():
d = abs(sx - bx) + abs(sy - by)
m.add_constraint(m.abs(x - sx) + m.abs(y - sy) >= d + 1, ctname=f"ct_{sx}_{sy}")
m.add_constraint(m.abs(x - sx) + m.abs(y - sy) >= d + 1, ctname=f"ct_{sx}_{sy}") # type: ignore
m.set_objective("min", x + y)
s = m.solve()
assert s is not None
vx = int(s.get_value(x))
vy = int(s.get_value(y))
@ -72,7 +75,7 @@ lines = sys.stdin.read().splitlines()
sensor_to_beacon: dict[tuple[int, int], tuple[int, int]] = {}
for line in lines:
r = parse.parse(
r: dict[str, str] = parse.parse( # type: ignore
"Sensor at x={sx}, y={sy}: closest beacon is at x={bx}, y={by}", line
)
sensor_to_beacon[int(r["sx"]), int(r["sy"])] = (int(r["bx"]), int(r["by"]))

View File

@ -1,5 +1,4 @@
import sys
from typing import FrozenSet
import numpy as np

View File

@ -1,9 +1,9 @@
import sys
from typing import Literal
from typing import Any, Literal
import numpy as np
import parse
from tqdm import tqdm
import parse # pyright: ignore[reportMissingTypeStubs]
from numpy.typing import NDArray
Reagent = Literal["ore", "clay", "obsidian", "geode"]
REAGENTS: tuple[Reagent, ...] = (
@ -35,7 +35,7 @@ class State:
self.robots = robots
self.reagents = reagents
def __eq__(self, other) -> bool:
def __eq__(self, other: object) -> bool:
return (
isinstance(other, State)
and self.robots == other.robots
@ -66,7 +66,7 @@ lines = sys.stdin.read().splitlines()
blueprints: list[dict[Reagent, IntOfReagent]] = []
for line in lines:
r = parse.parse(
r: list[int] = parse.parse( # type: ignore
"Blueprint {}: "
"Each ore robot costs {:d} ore. "
"Each clay robot costs {:d} ore. "
@ -94,11 +94,12 @@ def run(blueprint: dict[Reagent, dict[Reagent, int]], max_time: int) -> int:
name: max(blueprint[r].get(name, 0) for r in REAGENTS) for name in REAGENTS
}
state_after_t: dict[int, set[State]] = {0: [State()]}
state_after_t: dict[int, set[State]] = {0: {State()}}
for t in range(1, max_time + 1):
# list of new states at the end of step t that we are going to prune later
states_for_t: set[State] = set()
robots_that_can_be_built: list[Reagent]
for state in state_after_t[t - 1]:
robots_that_can_be_built = [
@ -132,7 +133,7 @@ def run(blueprint: dict[Reagent, dict[Reagent, int]], max_time: int) -> int:
for robot in robots_that_can_be_built:
robots = state.robots.copy()
robots[robot] += 1
reagents = {
reagents: IntOfReagent = {
reagent: state.reagents[reagent]
+ state.robots[reagent]
- blueprint[robot].get(reagent, 0)
@ -151,7 +152,7 @@ def run(blueprint: dict[Reagent, dict[Reagent, int]], max_time: int) -> int:
]
)
to_keep = []
to_keep: list[NDArray[np.integer[Any]]] = []
while len(np_states) > 0:
first_dom = (np_states[1:] >= np_states[0]).all(axis=1).any()

View File

@ -56,7 +56,7 @@ def propagate(
[() for _ in range(len(layout[0]))] for _ in range(len(layout))
]
queue = [(start, direction)]
queue: list[tuple[tuple[int, int], Direction]] = [(start, direction)]
while queue:
(row, col), direction = queue.pop()

View File

@ -114,11 +114,12 @@ for workflow_s in workflows_s.split("\n"):
for block in block_s[:-1].split(","):
check: Check
if (i := block.find(":")) >= 0:
check, target = (
check = (
cast(Category, block[0]),
cast(Literal["<", ">"], block[1]),
int(block[2:i]),
), block[i + 1 :]
)
target = block[i + 1 :]
else:
check, target = None, block
workflows[name].append((check, target))

View File

@ -19,7 +19,7 @@ def _name(i: int) -> str:
def build_supports(
bricks: list[tuple[tuple[int, int, int], tuple[int, int, int]]]
bricks: list[tuple[tuple[int, int, int], tuple[int, int, int]]],
) -> tuple[dict[int, set[int]], dict[int, set[int]]]:
# 1. compute locations where a brick of sand will land after falling by processing
# them in sorted order of bottom z location

View File

@ -2,24 +2,34 @@ import logging
import os
import sys
from collections import defaultdict
from typing import Literal, Sequence, TypeAlias, cast
VERBOSE = os.getenv("AOC_VERBOSE") == "True"
logging.basicConfig(level=logging.INFO if VERBOSE else logging.WARNING)
Direction = {
DirectionType: TypeAlias = Literal[">", "<", "^", "v", ".", "#"]
Direction: dict[DirectionType, tuple[int, int]] = {
">": (0, +1),
"<": (0, -1),
"^": (-1, 0),
"v": (+1, 0),
}
Neighbors = {".": ((+1, 0), (-1, 0), (0, +1), (0, -1)), "#": ()} | {
k: (v,) for k, v in Direction.items()
}
Neighbors = cast(
"dict[DirectionType, tuple[tuple[int, int], ...]]",
{
".": ((+1, 0), (-1, 0), (0, +1), (0, -1)),
"#": (),
}
| {k: (v,) for k, v in Direction.items()},
)
def neighbors(
grid: list[str], node: tuple[int, int], ignore: set[tuple[int, int]] = set()
grid: list[Sequence[DirectionType]],
node: tuple[int, int],
ignore: set[tuple[int, int]] = set(),
):
"""
Compute neighbors of the given node, ignoring the given set of nodes and considering
@ -51,7 +61,7 @@ def neighbors(
def reachable(
grid: list[str], start: tuple[int, int], target: tuple[int, int]
grid: list[Sequence[DirectionType]], start: tuple[int, int], target: tuple[int, int]
) -> tuple[tuple[int, int], int]:
"""
Compute the next 'reachable' node in the grid, starting at the given node.
@ -75,7 +85,7 @@ def reachable(
def compute_direct_links(
grid: list[str], start: tuple[int, int], target: tuple[int, int]
grid: list[Sequence[DirectionType]], start: tuple[int, int], target: tuple[int, int]
) -> dict[tuple[int, int], list[tuple[tuple[int, int], int]]]:
if start == target:
return {}
@ -85,7 +95,7 @@ def compute_direct_links(
i, j = neighbor
di, dj = Direction[grid[i][j]]
reach, distance = reachable(lines, (i + di, j + dj), target)
reach, distance = reachable(grid, (i + di, j + dj), target)
direct[start].append((reach, distance + 2))
direct.update(compute_direct_links(grid, reach, target))
@ -124,7 +134,7 @@ def longest_path_length(
return max_distance
lines = sys.stdin.read().splitlines()
lines = cast(list[Sequence[DirectionType]], sys.stdin.read().splitlines())
n_rows, n_cols = len(lines), len(lines[0])
start = (0, 1)
target = (len(lines) - 1, len(lines[0]) - 2)

View File

View File

View File

@ -0,0 +1,8 @@
from __future__ import annotations
from typing import Literal
from docplex.mp.operand import Operand
class Expr(Operand):
def __pow__(self, power: Literal[0, 1, 2]) -> Expr: ...

View File

@ -0,0 +1,25 @@
from __future__ import annotations
from enum import Enum
class ObjectiveSense(Enum):
Minimize = ...
Maximize = ...
class EffortLevel(Enum):
Auto = ...
CheckFeas = ...
SolveFixed = ...
SolveMIP = ...
Repair = ...
NoCheck = ...
class WriteLevel(Enum):
Auto = ...
AllVars = ...
DiscreteVars = ...
NonZeroVars = ...
NonZeroDiscreteVars = ...
def filter_zeros(self) -> bool: ...
def filter_nondiscrete(self) -> bool: ...

View File

@ -0,0 +1,15 @@
from __future__ import annotations
from docplex.mp.operand import LinearOperand
class AbstractConstraint: ...
class BinaryConstraint(AbstractConstraint): ...
class LinearConstraint(BinaryConstraint, LinearOperand): ...
class RangeConstraint(AbstractConstraint): ...
class NotEqualConstraint(LinearConstraint): ...
class LogicalConstraint(AbstractConstraint): ...
class IndicatorConstraint(LogicalConstraint): ...
class EquivalenceConstraint(LogicalConstraint): ...
class IfThenConstraint(IndicatorConstraint): ...
class QuadraticConstraint(BinaryConstraint): ...
class PwlConstraint(AbstractConstraint): ...

View File

@ -0,0 +1,3 @@
from __future__ import annotations
class Context: ...

View File

@ -0,0 +1,49 @@
from __future__ import annotations
from typing import Final, overload
from docplex.mp.basic import Expr
from docplex.mp.linear import LinearExpr, MonomialExpr
from docplex.mp.model import Model
from docplex.mp.operand import LinearOperand
from docplex.mp.quad import QuadExpr
from docplex.mp.vartype import VarType
class Var(LinearOperand):
lb: float
ub: float
vartype: Final[VarType]
def __init__(
self,
model: Model,
vartype: VarType,
name: str,
lb: float | None = None,
ub: float | None = None,
) -> None: ...
def has_free_lb(self) -> bool: ...
def has_free_ub(self) -> bool: ...
def is_free(self) -> bool: ...
def set_lb(self, ub: float | None) -> None: ...
def set_ub(self, ub: float | None) -> None: ...
def is_binary(self) -> bool: ...
def is_integer(self) -> bool: ...
def is_continuous(self) -> bool: ...
def is_discrete(self) -> bool: ...
def __sub__(self, e: Var | float) -> LinearExpr: ...
def __rsub__(self, e: Var | float) -> LinearExpr: ...
def __neg__(self) -> MonomialExpr: ...
def __add__(self, other: Var | float) -> LinearExpr: ...
def __radd__(self, other: Var | float) -> LinearExpr: ...
@overload
def __mul__(self, other: float) -> MonomialExpr: ...
@overload
def __mul__(self, other: Var) -> QuadExpr: ...
@overload
def __mul__(self, other: Expr) -> Expr: ...
@overload
def __rmul__(self, other: float) -> MonomialExpr: ...
@overload
def __rmul__(self, other: Expr) -> Expr: ...
def __truediv__(self, other: float) -> MonomialExpr: ...

View File

@ -0,0 +1,39 @@
from __future__ import annotations
from typing import overload
from docplex.mp.basic import Expr
from docplex.mp.dvar import Var
from docplex.mp.linear import LinearExpr
from docplex.mp.operand import LinearOperand
from docplex.mp.quad import QuadExpr
class _FunctionalExpr(Expr, LinearOperand):
def __sub__(self, e: Var | float) -> LinearExpr: ...
def __rsub__(self, e: Var | float) -> LinearExpr: ...
def __neg__(self) -> LinearExpr: ...
def __add__(self, other: Var | float) -> LinearExpr: ...
def __radd__(self, other: Var | float) -> LinearExpr: ...
@overload
def __mul__(self, other: float) -> LinearExpr: ...
@overload
def __mul__(self, other: Var) -> QuadExpr: ...
@overload
def __mul__(self, other: Expr) -> LinearExpr: ...
@overload
def __rmul__(self, other: float) -> LinearExpr: ...
@overload
def __rmul__(self, other: Expr) -> LinearExpr: ...
def __div__(self, other: float) -> LinearExpr: ...
def __truediv__(self, other: float) -> LinearExpr: ...
class UnaryFunctionalExpr(_FunctionalExpr): ...
class AbsExpr(UnaryFunctionalExpr): ...
class _SequenceExpr(_FunctionalExpr): ...
class MinimumExpr(_SequenceExpr): ...
class MaximumExpr(_SequenceExpr): ...
class LogicalNotExpr(UnaryFunctionalExpr): ...
class _LogicalSequenceExpr(_SequenceExpr): ...
class LogicalAndExpr(_LogicalSequenceExpr): ...
class LogicalOrExpr(_LogicalSequenceExpr): ...
class PwlExpr(UnaryFunctionalExpr): ...

View File

@ -0,0 +1,86 @@
from __future__ import annotations
from typing import overload
from docplex.mp.basic import Expr
from docplex.mp.operand import LinearOperand
from docplex.mp.quad import QuadExpr
class AbstractLinearExpr(LinearOperand, Expr): ...
class MonomialExpr(AbstractLinearExpr):
def __sub__(self, e: LinearOperand | float) -> LinearExpr: ...
def __rsub__(self, e: LinearOperand | float) -> LinearExpr: ...
def __neg__(self) -> MonomialExpr: ...
def __add__(self, other: LinearOperand | float) -> LinearExpr: ...
def __radd__(self, other: LinearOperand | float) -> LinearExpr: ...
@overload
def __mul__(self, other: float) -> MonomialExpr: ...
@overload
def __mul__(self, other: LinearExpr) -> QuadExpr: ...
def __rmul__(self, other: float) -> MonomialExpr: ...
def __div__(self, other: float) -> MonomialExpr: ...
def __truediv__(self, e: float) -> MonomialExpr: ...
class LinearExpr(AbstractLinearExpr):
def __sub__(self, e: LinearOperand | float) -> LinearExpr: ...
def __rsub__(self, e: LinearOperand | float) -> LinearExpr: ...
def __neg__(self) -> LinearExpr: ...
def __add__(self, e: LinearOperand | float) -> LinearExpr: ...
def __radd__(self, e: LinearOperand | float) -> LinearExpr: ...
@overload
def __mul__(self, e: float) -> LinearExpr: ...
@overload
def __mul__(self, e: LinearOperand) -> QuadExpr: ...
def __rmul__(self, e: float) -> LinearExpr: ...
def __div__(self, e: float) -> LinearExpr: ...
def __truediv__(self, e: float) -> LinearExpr: ...
class ZeroExpr(AbstractLinearExpr):
@overload
def __sub__(self, e: float) -> ConstantExpr: ...
@overload
def __sub__(self, e: LinearOperand) -> LinearExpr: ...
@overload
def __rsub__(self, e: float) -> ConstantExpr: ...
@overload
def __rsub__(self, e: LinearOperand) -> LinearExpr: ...
@overload
def __add__(self, e: float) -> ConstantExpr: ...
@overload
def __add__(self, e: LinearOperand) -> LinearExpr: ...
@overload
def __radd__(self, e: float) -> ConstantExpr: ...
@overload
def __radd__(self, e: LinearOperand) -> LinearExpr: ...
def __neg__(self) -> ZeroExpr: ...
def __mul__(self, e: float | LinearOperand) -> ZeroExpr: ...
def __rmul__(self, e: float | LinearOperand) -> ZeroExpr: ...
def __div__(self, e: float) -> ZeroExpr: ...
def __truediv__(self, e: float) -> ZeroExpr: ...
class ConstantExpr(AbstractLinearExpr):
@overload
def __sub__(self, e: float) -> ConstantExpr: ...
@overload
def __sub__(self, e: LinearOperand) -> LinearExpr: ...
@overload
def __rsub__(self, e: float) -> ConstantExpr: ...
@overload
def __rsub__(self, e: LinearOperand) -> LinearExpr: ...
@overload
def __add__(self, e: float) -> ConstantExpr: ...
@overload
def __add__(self, e: LinearOperand) -> LinearExpr: ...
@overload
def __radd__(self, e: float) -> ConstantExpr: ...
@overload
def __radd__(self, e: LinearOperand) -> LinearExpr: ...
def __neg__(self) -> ConstantExpr: ...
@overload
def __mul__(self, e: float) -> ConstantExpr: ...
@overload
def __mul__(self, e: LinearOperand) -> LinearExpr: ...
def __rmul__(self, e: float | LinearOperand) -> ConstantExpr: ...
def __div__(self, e: float) -> ConstantExpr: ...
def __truediv__(self, e: float) -> ConstantExpr: ...

View File

@ -0,0 +1,177 @@
from __future__ import annotations
from collections.abc import Callable, Iterable
from typing import Any, Iterator, Literal, Sequence, TextIO, TypeVar, overload
from docplex.mp.basic import Expr
from docplex.mp.constants import EffortLevel, ObjectiveSense, WriteLevel
from docplex.mp.constr import AbstractConstraint
from docplex.mp.context import Context
from docplex.mp.dvar import Var
from docplex.mp.functional import (
AbsExpr,
LogicalAndExpr,
LogicalNotExpr,
LogicalOrExpr,
MaximumExpr,
MinimumExpr,
)
from docplex.mp.linear import AbstractLinearExpr, ConstantExpr, LinearExpr, ZeroExpr
from docplex.mp.operand import LinearOperand
from docplex.mp.params.parameters import RootParameterGroup
from docplex.mp.progress import ProgressListener
from docplex.mp.solution import SolveSolution
from typing_extensions import TypeAlias
_Key = TypeVar("_Key")
_Val = TypeVar("_Val")
_MethodDictArg: TypeAlias = (
dict[_Key, _Val] | list[_Val] | Callable[[_Key], _Val] | _Val
)
_ObjectiveSense: TypeAlias = (
ObjectiveSense | Literal["min", "max", "minimize", "maximize", -1, 1]
)
class Model:
def __init__(
self, name: str | None = None, context: Context | None = None, **kwargs: Any
) -> None: ...
def binary_var(self, name: str | None = None) -> Var: ...
def binary_var_list(
self,
keys: int | Sequence[_Key],
name: _MethodDictArg[_Key, str] | None = None,
key_format: str | None = None,
) -> list[Var]: ...
def binary_var_dict(
self,
keys: Iterable[_Key],
name: _MethodDictArg[_Key, str] | None = None,
key_format: str | None = None,
) -> dict[_Key, Var]: ...
def integer_var(
self, lb: int | None = None, ub: int | None = None, name: str | None = None
) -> Var: ...
def integer_var_list(
self,
keys: int | Sequence[_Key],
lb: _MethodDictArg[_Key, int] | None = None,
ub: _MethodDictArg[_Key, int] | None = None,
name: _MethodDictArg[_Key, str] | None = None,
key_format: str | None = None,
) -> list[Var]: ...
def integer_var_dict(
self,
keys: Iterable[_Key],
lb: _MethodDictArg[_Key, int] | None = None,
ub: _MethodDictArg[_Key, int] | None = None,
name: _MethodDictArg[_Key, str] | None = None,
key_format: str | None = None,
) -> dict[_Key, Var]: ...
def continuous_var(
self, lb: float | None = None, ub: float | None = None, name: str | None = None
) -> Var: ...
def continuous_var_list(
self,
keys: int | Sequence[_Key],
lb: _MethodDictArg[_Key, float] | None = None,
ub: _MethodDictArg[_Key, float] | None = None,
name: _MethodDictArg[_Key, str] | None = None,
key_format: str | None = None,
) -> list[Var]: ...
def continuous_var_dict(
self,
keys: Iterable[_Key],
lb: _MethodDictArg[_Key, float] | None = None,
ub: _MethodDictArg[_Key, float] | None = None,
name: _MethodDictArg[_Key, str] | None = None,
key_format: str | None = None,
) -> dict[_Key, Var]: ...
def sum(self, args: Iterable[LinearOperand | float]) -> LinearExpr | ZeroExpr: ...
def sums(self, *args: LinearOperand | float) -> LinearExpr | ZeroExpr: ...
def add_constraint(
self, ct: AbstractConstraint, ctname: str | None = None
) -> AbstractConstraint: ...
def add_constraints(
self, ct: Iterable[AbstractConstraint], names: Iterable[str] | None = None
) -> list[AbstractConstraint]: ...
def remove_constraints(
self,
cts: Iterable[AbstractConstraint],
error: Literal["raise", "warn"] = "warn",
) -> list[AbstractConstraint]: ...
@overload
def add(
self, ct: AbstractConstraint, name: str | None = None
) -> AbstractConstraint: ...
@overload
def add(
self, ct: Iterable[AbstractConstraint], name: Iterable[str] | None = None
) -> list[AbstractConstraint]: ...
def solve(self, **kwargs: Any) -> SolveSolution | None: ...
def set_objective(self, sense: _ObjectiveSense, expr: Expr | Var) -> None: ...
def set_objective_sense(self, sense: _ObjectiveSense) -> None: ...
def set_objective_expr(self, expr: Expr | Var) -> None: ...
def set_lex_multi_objective(
self,
sense: _ObjectiveSense,
exprs: Iterable[Expr | Var],
abstols: float | None = None,
reltols: float | None = None,
names: Iterable[str] | None = None,
) -> None: ...
def get_objective_expr(self) -> Expr: ...
def add_mip_start(
self,
mip_start_sol: SolveSolution,
effort_level: EffortLevel | None = None,
write_level: WriteLevel | None = None,
complete_vars: bool = False,
eps_zero: float = 1e-6,
) -> SolveSolution: ...
@property
def log_output(self) -> TextIO | bool: ...
@log_output.setter
def log_output(self, out: TextIO | bool) -> None: ...
def set_log_output(self, out: TextIO) -> None: ...
@property
def parameters(self) -> RootParameterGroup: ...
def problem_type(self) -> Literal["LP", "MILP", "QP", "MIQP", "QCP", "MIQCP"]: ...
def print_information(self) -> None: ...
def logical_and(
self, *args: Var | Expr | LinearOperand
) -> Var | AbstractLinearExpr | ConstantExpr | LogicalAndExpr: ...
def logical_or(
self, *args: Var | Expr | LinearOperand
) -> Var | AbstractLinearExpr | ConstantExpr | LogicalOrExpr: ...
def logical_not(self, other: Var | Expr) -> LogicalNotExpr: ...
def abs(self, e: Var | Expr | float) -> AbsExpr: ...
def min(self, *args: Var | Expr | Sequence[Var | Expr]) -> MinimumExpr: ...
def max(self, *args: Var | Expr | Sequence[Var | Expr]) -> MaximumExpr: ...
def if_then(
self,
if_ct: AbstractConstraint,
then_ct: AbstractConstraint,
negate: bool = ...,
) -> AbstractConstraint: ...
def indicator_constraint(
self,
binary_var: Var,
linear_ct: AbstractConstraint,
active_value: Literal[0, 1] = ...,
name: str | None = ...,
) -> AbstractConstraint: ...
def add_indicator(
self,
binary_var: Var,
linear_ct: AbstractConstraint,
active_value: Literal[0, 1] = ...,
name: str | None = ...,
) -> AbstractConstraint: ...
def add_progress_listener(self, listener: ProgressListener) -> None: ...
def remove_progress_listener(self, listener: ProgressListener) -> None: ...
@property
def number_of_progress_listeners(self) -> int: ...
def iter_progress_listeners(self) -> Iterator[ProgressListener]: ...
def clear_progress_listeners(self) -> None: ...

View File

@ -0,0 +1,12 @@
from __future__ import annotations
from docplex.mp.constr import BinaryConstraint, NotEqualConstraint
class Operand:
def negate(self) -> Operand: ...
def __le__(self, other: Operand | float) -> BinaryConstraint: ...
def __ge__(self, other: Operand | float) -> BinaryConstraint: ...
def __eq__(self, other: Operand | float) -> BinaryConstraint: ... # type: ignore
class LinearOperand(Operand):
def __ne__(self, other: Operand | float) -> NotEqualConstraint: ... # type: ignore

View File

View File

@ -0,0 +1,272 @@
from __future__ import annotations
class ParameterGroup:
def __init__(
self, name: str, parent_group: ParameterGroup | None = None
) -> None: ...
class _BarrierGroup(ParameterGroup):
class _BarrierLimitsGroup(ParameterGroup):
corrections: int = ...
growth: float = ...
iteration: int = ...
objrange: float = ...
algorithm: int = ...
colnonzeros: int = ...
convergetol: float = ...
crossover: int = ...
display: int = ...
ordering: int = ...
qcpconvergetol: float = ...
startalg: int = ...
limits: _BarrierLimitsGroup = ...
class _BendersGroup(ParameterGroup):
class _BendersTolerancesGroup(ParameterGroup):
feasibilitycut: float = ...
optimalitycut: float = ...
strategy: int = ...
workeralgorithm: int = ...
tolerances: _BendersTolerancesGroup = ...
class _ConflictGroup(ParameterGroup):
algorithm: int = ...
display: int = ...
class _EmphasisGroup(ParameterGroup):
memory: bool = ...
mip: int = ...
numerical: bool = ...
class _FeasoptGroup(ParameterGroup):
mode: int = ...
tolerance: float = ...
class _MipGroup(ParameterGroup):
class _MipCutsGroup(ParameterGroup):
bqp: int = ...
cliques: int = ...
covers: int = ...
disjunctive: int = ...
flowcovers: int = ...
gomory: int = ...
gubcovers: int = ...
implied: int = ...
liftproj: int = ...
localimplied: int = ...
mcfcut: int = ...
mircut: int = ...
nodecuts: int = ...
pathcut: int = ...
rlt: int = ...
zerohalfcut: int = ...
class _MipLimitsGroup(ParameterGroup):
aggforcut: int = ...
auxrootthreads: int = ...
lowerobjstop: float = ...
cutpasses: int = ...
cutsfactor: float = ...
eachcutlimit: int = ...
gomorycand: int = ...
gomorypass: int = ...
nodes: int = ...
populate: int = ...
probedettime: float = ...
probetime: float = ...
repairtries: int = ...
solutions: int = ...
strongcand: int = ...
strongit: int = ...
treememory: float = ...
upperobjstop: float = ...
class _MipPolishafterGroup(ParameterGroup):
absmipgap: float = ...
dettime: float = ...
mipgap: float = ...
nodes: int = ...
solutions: int = ...
time: float = ...
class _MipPoolGroup(ParameterGroup):
absgap: float = ...
capacity: int = ...
intensity: int = ...
relgap: float = ...
replace: int = ...
class _MipstrategyGroup(ParameterGroup):
backtrack: float = ...
bbinterval: int = ...
branch: int = ...
dive: int = ...
file: int = ...
fpheur: int = ...
heuristiceffort: float = ...
heuristicfreq: int = ...
kappastats: int = ...
lbheur: bool = ...
miqcpstrat: int = ...
nodeselect: int = ...
order: bool = ...
presolvenode: int = ...
probe: int = ...
rinsheur: int = ...
search: int = ...
startalgorithm: int = ...
subalgorithm: int = ...
variableselect: int = ...
class _MipSubmipGroup(ParameterGroup):
startalg: int = ...
subalg: int = ...
nodelimit: int = ...
scale: int = ...
class _MipTolerancesGroup(ParameterGroup):
absmipgap: float = ...
linearization: float = ...
integrality: float = ...
lowercutoff: float = ...
mipgap: float = ...
objdifference: float = ...
relobjdifference: float = ...
uppercutoff: float = ...
display: int = ...
interval: int = ...
ordertype: int = ...
cuts: _MipCutsGroup = ...
limits: _MipLimitsGroup = ...
polishafter: _MipPolishafterGroup = ...
pool: _MipPoolGroup = ...
strategy: _MipstrategyGroup = ...
submip: _MipSubmipGroup = ...
tolerances: _MipTolerancesGroup = ...
class _MultiobjectiveGroup(ParameterGroup):
display: int = ...
class _NetworkGroup(ParameterGroup):
class _NetworkTolerancesGroup(ParameterGroup):
feasibility: float = ...
optimality: float = ...
display: int = ...
iterations: int = ...
netfind: int = ...
pricing: int = ...
tolerances: _NetworkTolerancesGroup = ...
class _OutputGroup(ParameterGroup):
intsolfileprefix: str = ...
mpslong: bool = ...
writelevel: int = ...
class _PreprocessingGroup(ParameterGroup):
aggregator: int = ...
boundstrength: int = ...
coeffreduce: int = ...
dependency: int = ...
dual: int = ...
fill: int = ...
folding: int = ...
numpass: int = ...
presolve: bool = ...
qcpduals: int = ...
qpmakepsd: bool = ...
qtolin: int = ...
reduce: int = ...
reformulations: int = ...
relax: int = ...
repeatpresolve: int = ...
sos1reform: int = ...
sos2reform: int = ...
symmetry: int = ...
class _ReadGroup(ParameterGroup):
datacheck: int = ...
fileencoding: str = ...
scale: int = ...
warninglimit: int = ...
class _SiftingGroup(ParameterGroup):
algorithm: int = ...
simplex: bool = ...
display: int = ...
iterations: int = ...
class _SimplexGroup(ParameterGroup):
class _SimplexLimitsGroup(ParameterGroup):
iterations: int = ...
lowerobj: float = ...
perturbation: int = ...
singularity: int = ...
upperobj: float = ...
class _SimplexPerturbationGroup(ParameterGroup):
constant: float = ...
indicator: bool = ...
class _SimplexTolerancesGroup(ParameterGroup):
feasibility: float = ...
markowitz: float = ...
optimality: float = ...
crash: int = ...
dgradient: int = ...
display: int = ...
dynamicrows: int = ...
pgradient: int = ...
pricing: int = ...
refactor: int = ...
limits: _SimplexLimitsGroup = ...
perturbation: _SimplexPerturbationGroup = ...
tolerances: _SimplexTolerancesGroup = ...
class _TuneGroup(ParameterGroup):
dettimelimit: float = ...
display: int = ...
measure: int = ...
repeat: int = ...
timelimit: float = ...
class RootParameterGroup(ParameterGroup):
advance: int = ...
clocktype: int = ...
dettimelimit: float = ...
lpmethod: int = ...
optimalitytarget: int = ...
parallel: int = ...
paramdisplay: bool = ...
qpmethod: int = ...
randomseed: int = ...
record: bool = ...
solutiontype: int = ...
threads: int = ...
timelimit: float = ...
workdir: str = ...
workmem: float = ...
barrier: _BarrierGroup = ...
benders: _BendersGroup = ...
conflict: _ConflictGroup = ...
emphasis: _EmphasisGroup = ...
feasopt: _FeasoptGroup = ...
mip: _MipGroup = ...
multiobjective: _MultiobjectiveGroup = ...
network: _NetworkGroup = ...
output: _OutputGroup = ...
preprocessing: _PreprocessingGroup = ...
read: _ReadGroup = ...
sifting: _SiftingGroup = ...
simplex: _SimplexGroup = ...
tune: _TuneGroup = ...

View File

@ -0,0 +1,192 @@
from collections.abc import Mapping, Sequence
from enum import Enum
from typing import Callable, Iterator, Literal, NamedTuple, Protocol
from docplex.mp.model import Model
from docplex.mp.solution import SolveSolution
class ProgressData(NamedTuple):
has_incumbent: bool
current_objective: float | None
best_bound: float
mip_gap: float | None
current_nb_iterations: int
current_nb_nodes: int
remaining_nb_nodes: int
time: float
det_time: float
class ProgressClock(Enum):
All = ...
Solutions = ...
BestBound = ...
Objective = ...
Gap = ...
@property
def listens_to_solution(self) -> bool: ...
class _Filter(Protocol):
def accept(self, data: ProgressData) -> bool: ...
def reset(self) -> None: ...
class _AbstractProgressListener:
def abort(self) -> None: ...
def notify_start(self) -> None: ...
class ProgressListener(_AbstractProgressListener):
"""The base class for progress listeners."""
def __init__(
self,
clock_ar: ProgressClock = ...,
absdiff: float | None = None,
reldiff: float | None = None,
) -> None: ...
@property
def clock(self) -> ProgressClock: ...
@property
def abs_diff(self) -> float: ...
@property
def relative_diff(self) -> float: ...
@property
def current_progress_data(self) -> ProgressData | None: ...
def accept(self, pdata: ProgressData) -> bool: ...
def requires_solution(self) -> bool: ...
def notify_solution(self, s: SolveSolution) -> None: ...
def notify_jobid(self, jobid: int) -> None: ...
def notify_end(self, status: int, objective: float | None) -> None: ...
def notify_progress(self, progress_data: ProgressData) -> None: ...
class FilterAcceptAll:
def accept(self, pdata: ProgressData) -> bool: ...
def reset(self) -> None: ...
class FilterAcceptAllSolutions(object):
def accept(self, pdata: ProgressData) -> bool: ...
def reset(self) -> None: ...
class Watcher:
def __init__(
self,
name: str,
absdiff: float,
reldiff: float,
update_fn: Callable[[ProgressData], bool],
) -> None: ...
def reset(self) -> None: ...
def accept(self, progress_data: ProgressData) -> bool: ...
def sync(self, pdata: ProgressData) -> None: ...
class ClockFilter:
def __init__(
self,
level: ProgressClock,
obj_absdiff: float,
bbound_absdiff: float,
obj_reldiff: float = ...,
bbound_reldiff: float = ...,
node_delta: int = ...,
) -> None: ...
def accept(self, progress_data: ProgressData) -> bool: ...
def peek(self, progress_data: ProgressData) -> Watcher | None: ...
def reset(self) -> None: ...
class TextProgressListener(ProgressListener):
def __init__(
self,
clock: ProgressClock = ...,
gap_fmt: str | None = ...,
obj_fmt: str | None = ...,
absdiff: float | None = ...,
reldiff: float | None = ...,
) -> None: ...
def notify_start(self) -> None: ...
def notify_progress(self, progress_data: ProgressData) -> None: ...
class ProgressDataRecorder(ProgressListener):
"""A specialized class of ProgressListener, which collects all ProgressData it receives."""
def __init__(
self,
clock: ProgressClock = ...,
absdiff: float | None = ...,
reldiff: float | None = ...,
) -> None: ...
def notify_start(self) -> None: ...
def notify_progress(self, progress_data: ProgressData) -> None: ...
@property
def number_of_records(self) -> int: ...
@property
def iter_recorded(self) -> Iterator[ProgressData]: ...
@property
def recorded(self) -> Sequence[ProgressData]: ...
class SolutionListener(ProgressListener):
def __init__(
self,
clock: Literal[
ProgressClock.Solutions, ProgressClock.Objective, ProgressClock.Gap
] = ...,
absdiff: float | None = ...,
reldiff: float | None = ...,
) -> None: ...
def requires_solution(self) -> bool: ...
def notify_solution(self, s: SolveSolution) -> None: ...
def notify_start(self) -> None: ...
def accept(self, pdata: ProgressData) -> bool: ...
class SolutionRecorder(SolutionListener):
def __init__(
self,
clock: Literal[
ProgressClock.Solutions, ProgressClock.Objective, ProgressClock.Gap
] = ...,
absdiff: float | None = ...,
reldiff: float | None = ...,
) -> None: ...
def notify_start(self) -> None: ...
def notify_solution(self, s: SolveSolution) -> None: ...
def iter_solutions(self) -> Iterator[SolveSolution]: ...
@property
def number_of_solutions(self) -> int: ...
@property
def current_solution(self) -> SolveSolution | None: ...
class FunctionalSolutionListener(SolutionListener):
def __init__(
self,
solution_fn: Callable[[SolveSolution], None],
clock: Literal[
ProgressClock.Solutions, ProgressClock.Objective, ProgressClock.Gap
] = ...,
absdiff: float | None = ...,
reldiff: float | None = ...,
) -> None: ...
def notify_solution(self, s: SolveSolution) -> None: ...
class KpiListener(SolutionListener):
def __init__(
self,
model: Model,
clock: Literal[
ProgressClock.Solutions, ProgressClock.Objective, ProgressClock.Gap
] = ...,
absdiff: float | None = ...,
reldiff: float | None = ...,
) -> None: ...
def publish(self, kpi_dict: Mapping[str, float | str]) -> None: ...
def notify_solution(self, s: SolveSolution) -> None: ...
class KpiPrinter(KpiListener):
def __init__(
self,
model: Model,
clock: Literal[
ProgressClock.Solutions, ProgressClock.Objective, ProgressClock.Gap
] = ...,
absdiff: float | None = ...,
reldiff: float | None = ...,
kpi_format: str = ...,
) -> None: ...
def publish(self, kpi_dict: Mapping[str, float | str]) -> None: ...

View File

@ -0,0 +1,5 @@
from __future__ import annotations
from docplex.mp.basic import Expr
class QuadExpr(Expr): ...

View File

@ -0,0 +1,29 @@
from __future__ import annotations
class SolveDetails:
@property
def time(self) -> float: ...
@property
def status_code(self) -> int: ...
@property
def status(self) -> str: ...
@property
def problem_type(self) -> str: ...
@property
def columns(self) -> int: ...
@property
def nb_linear_nonzeros(self) -> int: ...
@property
def mip_relative_gap(self) -> float: ...
gap = mip_relative_gap
@property
def best_bound(self) -> float: ...
@property
def nb_iterations(self) -> int | tuple[int, ...]: ...
@property
def nb_nodes_processed(self) -> int | tuple[int, ...]: ...
def print_information(self) -> None: ...
def to_string(self) -> str: ...
def has_hit_limit(self) -> bool: ...

View File

@ -0,0 +1,49 @@
from __future__ import annotations
from collections.abc import Iterable, Mapping
from typing import Literal, Sequence, TypeVar
from docplex.mp.constants import WriteLevel
from docplex.mp.dvar import Var
from docplex.mp.model import Model
from docplex.mp.sdetails import SolveDetails
from typing_extensions import TypeAlias
_Key = TypeVar("_Key")
_SolvedBy: TypeAlias = Literal["cplex_local", "cplex_cloud"] | None
class SolveSolution:
def __init__(
self,
model: Model,
var_value_map: Mapping[Var, float] | None = None,
obj: Sequence[float] | float | None = None,
blended_obj_by_priority: Sequence[float] | None = None,
name: str | None = None,
solved_by: _SolvedBy = None,
keep_zeros: bool = True,
) -> None: ...
@property
def problem_name(self) -> str: ...
@property
def solved_by(self) -> _SolvedBy: ...
@property
def name(self) -> str: ...
@property
def solve_details(self) -> SolveDetails: ...
def get_objective_value(self) -> float | list[float]: ...
def get_value(self, arg: Var) -> float: ...
def get_values(self, var_seq: Iterable[Var]) -> list[float]: ...
def get_value_list(self, dvars: Iterable[Var]) -> list[float]: ...
def get_value_dict(
self,
var_dict: Mapping[_Key, Var],
keep_zeros: bool = True,
precision: float = 1e-6,
) -> dict[_Key, float]: ...
def as_mip_start(
self,
write_level: WriteLevel = ...,
complete_vars: bool = False,
eps_zero: float = 1e-6,
) -> SolveSolution: ...

View File

@ -0,0 +1,11 @@
from __future__ import annotations
class VarType:
def is_semi_type(self) -> bool: ...
def is_discrete(self) -> bool: ...
class BinaryVarType(VarType): ...
class ContinuousVarType(VarType): ...
class IntegerVarType(VarType): ...
class SemiContinuousVarType(VarType): ...
class SemiDiscreteVarType(VarType): ...