mapFolding 0.17.0__py3-none-any.whl → 0.18.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- easyRun/NOTcountingFolds.py +16 -10
- easyRun/__init__.py +1 -0
- easyRun/countFolds.py +17 -9
- easyRun/meanders.py +6 -8
- mapFolding/__init__.py +24 -35
- mapFolding/_e/Z0Z_analysisPython/SORTZ0Z_hypothesis.py +189 -0
- mapFolding/_e/Z0Z_analysisPython/SORTZ0Z_p2d6.py +143 -0
- mapFolding/_e/Z0Z_analysisPython/__init__.py +4 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/__init__.py +0 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200.py +369 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/2001.py +694 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/270/211.py +514 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/270/2111.py +480 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/214.py +511 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/2141.py +515 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/214/344/270/211.py +485 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/214/344/270/2111.py +442 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/211.py +313 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/2111.py +343 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/214.py +400 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/2141.py +497 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/214/344/270/211.py +463 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/214/344/270/2111.py +441 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266.py +35 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/2661.py +35 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200.py +382 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/2001.py +630 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/270/211.py +488 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/270/2111.py +475 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/214.py +473 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/2141.py +500 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211.py +465 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111.py +439 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/211.py +599 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/2111.py +536 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/214.py +506 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/2141.py +533 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/214/344/270/211.py +489 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/214/344/270/2111.py +474 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2001.py +2158 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2001Negative.py +2158 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200Negative.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/211.py +1397 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/2111.py +1291 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/2111Negative.py +1291 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/211Negative.py +1397 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214.py +1240 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/2141.py +1420 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/2141Negative.py +1420 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214Negative.py +1240 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/211.py +1366 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/2111.py +1274 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/2111Negative.py +1274 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/211Negative.py +1366 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/211.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2111.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2111Negative.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/211Negative.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214.py +1102 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/2141.py +1422 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/2141Negative.py +1422 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214Negative.py +1102 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/211.py +1240 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/2111.py +1228 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/2111Negative.py +1228 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/211Negative.py +1240 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266.py +32 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/2661.py +1162 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/2661Negative.py +1162 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266Negative.py +32 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2001.py +1926 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2001Negative.py +1926 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200Negative.py +1186 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/211.py +1291 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/2111.py +1176 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/2111Negative.py +1176 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/211Negative.py +1291 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214.py +1228 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/2141.py +1324 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/2141Negative.py +1324 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214Negative.py +1228 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211.py +1274 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111.py +1038 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111Negative.py +1038 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211Negative.py +1274 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/211.py +2158 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2111.py +1926 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2111Negative.py +1926 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/211Negative.py +2158 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214.py +1422 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/2141.py +1364 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/2141Negative.py +1364 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214Negative.py +1422 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/211.py +1420 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/2111.py +1324 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/2111Negative.py +1324 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/211Negative.py +1420 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200.py +3133 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2001.py +6039 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2001Negative.py +6039 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200Negative.py +3133 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/211.py +3527 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/2111.py +2300 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/2111Negative.py +2300 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/211Negative.py +3527 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214.py +3597 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/2141.py +3317 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/2141Negative.py +3317 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214Negative.py +3597 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/211.py +3161 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/2111.py +2877 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/2111Negative.py +2877 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/211Negative.py +3161 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/211.py +2981 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2111.py +3055 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2111Negative.py +3055 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/211Negative.py +2981 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214.py +3221 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/2141.py +3988 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/2141Negative.py +3988 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214Negative.py +3221 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/211.py +3652 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/2111.py +2863 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/2111Negative.py +2863 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/211Negative.py +3652 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200.py +2485 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2001.py +4566 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2001Negative.py +4566 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200Negative.py +2485 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/211.py +3006 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/2111.py +2485 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/2111Negative.py +2485 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/211Negative.py +3006 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214.py +3304 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/2141.py +3015 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/2141Negative.py +3015 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214Negative.py +3304 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211.py +2939 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111.py +2589 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111Negative.py +2589 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211Negative.py +2939 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/211.py +3899 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2111.py +2996 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2111Negative.py +2996 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/211Negative.py +3899 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214.py +3223 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/2141.py +3020 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/2141Negative.py +3020 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214Negative.py +3223 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/211.py +3250 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/2111.py +2667 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/2111Negative.py +2667 -0
- mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/211Negative.py +3250 -0
- mapFolding/_e/Z0Z_analysisPython/measure.py +162 -0
- mapFolding/_e/Z0Z_analysisPython/positionAnalysis.py +403 -0
- mapFolding/_e/Z0Z_analysisPython/positionAnalysisPileRanges2d6.py +110 -0
- mapFolding/_e/Z0Z_analysisPython/theExcluderBeast.py +640 -0
- mapFolding/_e/Z0Z_analysisPython/toolkit.py +166 -0
- mapFolding/_e/Z0Z_analysisPython/toolkitCSVsequences.py +188 -0
- mapFolding/_e/Z0Z_analysisPython/workBenchPatternFinder.py +284 -0
- mapFolding/_e/Z0Z_notes/__init__.py +0 -0
- mapFolding/_e/Z0Z_notes/knowledgeDump.py +214 -0
- mapFolding/_e/__init__.py +45 -0
- mapFolding/_e/_beDRY.py +547 -0
- mapFolding/_e/_dataDynamic.py +1164 -0
- mapFolding/_e/_measure.py +579 -0
- mapFolding/_e/_semiotics.py +363 -0
- mapFolding/_e/_theTypes.py +31 -0
- mapFolding/_e/algorithms/__init__.py +1 -0
- mapFolding/_e/algorithms/constraintPropagation.py +158 -0
- mapFolding/_e/algorithms/elimination.py +118 -0
- mapFolding/_e/algorithms/eliminationCrease.py +66 -0
- mapFolding/_e/algorithms/iff.py +584 -0
- mapFolding/_e/basecamp.py +89 -0
- mapFolding/_e/dataBaskets.py +123 -0
- mapFolding/_e/dataRaw/__init__.py +0 -0
- mapFolding/_e/easyRun/__init__.py +0 -0
- mapFolding/_e/easyRun/eliminateFolds.py +72 -0
- mapFolding/_e/easyRun/pinning.py +62 -0
- mapFolding/_e/filters.py +384 -0
- mapFolding/_e/pin2/344/270/212nDimensions.py +882 -0
- mapFolding/_e/pin2/344/270/212nDimensionsAnnex.py +551 -0
- mapFolding/_e/pin2/344/270/212nDimensionsByCrease.py +190 -0
- mapFolding/_e/pin2/344/270/212nDimensionsByDomain.py +459 -0
- mapFolding/_e/pinIt.py +436 -0
- mapFolding/_semiotics.py +42 -0
- mapFolding/_theSSOT.py +11 -56
- mapFolding/_theTypes.py +52 -68
- mapFolding/algorithms/A086345.py +8 -3
- mapFolding/algorithms/__init__.py +1 -1
- mapFolding/algorithms/matrixMeandersNumPyndas.py +18 -18
- mapFolding/algorithms/oeisIDbyFormula.py +4 -4
- mapFolding/algorithms/zCuzDocStoopidoeisIDbyFormula.py +3 -3
- mapFolding/basecamp.py +13 -28
- mapFolding/beDRY.py +108 -99
- mapFolding/filesystemToolkit.py +15 -11
- mapFolding/oeis.py +17 -16
- mapFolding/reference/matrixMeandersAnalysis/prefixNotationNotes.py +2 -2
- mapFolding/reference/meandersDumpingGround/matrixMeandersBaselineV2.py +0 -1
- mapFolding/reference/meandersDumpingGround/matrixMeandersNumPyV1finalForm.py +8 -10
- mapFolding/someAssemblyRequired/RecipeJob.py +5 -5
- mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +5 -2
- mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +9 -11
- mapFolding/someAssemblyRequired/mapFoldingModules/makeMapFoldingModules.py +2 -1
- mapFolding/someAssemblyRequired/transformationTools.py +2 -2
- mapFolding/tests/Z0Z_test_e_excluder.py +155 -0
- mapFolding/tests/conftest.py +193 -314
- mapFolding/tests/dataSamples/A001417.py +455 -0
- mapFolding/tests/dataSamples/__init__.py +1 -0
- mapFolding/tests/dataSamples/measurementData.py +1818 -0
- mapFolding/tests/dataSamples/p2DnDomain3_2_/351/246/226/344/270/200_/351/246/226/351/233/266/344/270/200.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain3_/351/246/226/344/270/200.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain5_4.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain6_5.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain6_7_5_4.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain7_6.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain/351/246/226/344/272/214_/351/246/226/351/233/266/344/270/200/344/272/214.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain/351/246/226/344/272/214_/351/246/226/351/233/266/344/272/214_/351/246/226/351/233/266/344/270/200/344/272/214_/351/246/226/344/270/200/344/272/214.py +17 -0
- mapFolding/tests/dataSamples/p2DnDomain/351/246/226/351/233/266/344/270/200/344/272/214_/351/246/226/344/270/200/344/272/214.py +15 -0
- mapFolding/tests/dataSamples/p2DnDomain/351/246/226/351/233/266/344/272/214_/351/246/226/344/272/214.py +15 -0
- mapFolding/tests/dataSamples/semioticsData.py +135 -0
- mapFolding/tests/test_computations.py +133 -88
- mapFolding/tests/test_e_computations.py +42 -0
- mapFolding/tests/test_e_dataDynamic.py +189 -0
- mapFolding/tests/test_e_measurements.py +257 -0
- mapFolding/tests/test_e_pinning.py +61 -0
- mapFolding/tests/test_e_semiotics.py +128 -0
- mapFolding/tests/test_filesystem.py +39 -17
- mapFolding/tests/{test_other.py → test_parameterValidation.py} +3 -3
- mapFolding/tests/{test_tasks.py → test_taskDivisions.py} +42 -23
- mapFolding/zCuzDocStoopid/makeDocstrings.py +3 -2
- {mapfolding-0.17.0.dist-info → mapfolding-0.18.0.dist-info}/METADATA +15 -9
- mapfolding-0.18.0.dist-info/RECORD +305 -0
- {mapfolding-0.17.0.dist-info → mapfolding-0.18.0.dist-info}/WHEEL +1 -1
- easyRun/A000682.py +0 -25
- easyRun/A005316.py +0 -20
- mapFolding/algorithms/A000136constraintPropagation.py +0 -95
- mapFolding/algorithms/A000136elimination.py +0 -163
- mapFolding/algorithms/A000136eliminationParallel.py +0 -77
- mapfolding-0.17.0.dist-info/RECORD +0 -107
- {mapfolding-0.17.0.dist-info → mapfolding-0.18.0.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.17.0.dist-info → mapfolding-0.18.0.dist-info}/licenses/LICENSE +0 -0
- {mapfolding-0.17.0.dist-info → mapfolding-0.18.0.dist-info}/top_level.txt +0 -0
mapFolding/_e/_beDRY.py
ADDED
|
@@ -0,0 +1,547 @@
|
|
|
1
|
+
"""You can use this module to share elimination-algorithm utilities that avoid `EliminationState` imports.
|
|
2
|
+
|
|
3
|
+
This module is a workbench utility layer for `mapFolding._e` algorithms. The module primarily contains utilities that are intended
|
|
4
|
+
to work beyond the $2^n$-dimensional special case.
|
|
5
|
+
|
|
6
|
+
You should avoid putting functions in this module that only work on $2^n$-dimensional maps. You cannot import `EliminationState`
|
|
7
|
+
into this module without causing circular import problems. This constraint exists as of 2026-01-26.
|
|
8
|
+
|
|
9
|
+
Contents
|
|
10
|
+
--------
|
|
11
|
+
Group-by functions
|
|
12
|
+
bifurcatePermutationSpace
|
|
13
|
+
You can split a `PermutationSpace` into pinned leaves and pile-range domains.
|
|
14
|
+
|
|
15
|
+
Disaggregation and deconstruction functions
|
|
16
|
+
DOTitems
|
|
17
|
+
You can iterate over `(key, value)` pairs in a `Mapping`.
|
|
18
|
+
DOTkeys
|
|
19
|
+
You can iterate over keys in a `Mapping`.
|
|
20
|
+
DOTvalues
|
|
21
|
+
You can iterate over values in a `Mapping`.
|
|
22
|
+
getIteratorOfLeaves
|
|
23
|
+
You can iterate over each `Leaf` bit that is set in a `PileRangeOfLeaves`.
|
|
24
|
+
|
|
25
|
+
`PileRangeOfLeaves` functions
|
|
26
|
+
DOTgetPileIfLeaf
|
|
27
|
+
You can read `permutationSpace[pile]` only when `permutationSpace[pile]` is a `Leaf`.
|
|
28
|
+
DOTgetPileIfPileRangeOfLeaves
|
|
29
|
+
You can read `permutationSpace[pile]` only when `permutationSpace[pile]` is a `PileRangeOfLeaves`.
|
|
30
|
+
getAntiPileRangeOfLeaves
|
|
31
|
+
You can build a complement `PileRangeOfLeaves` by clearing each `leaf` bit.
|
|
32
|
+
getPileRangeOfLeaves
|
|
33
|
+
You can build a `PileRangeOfLeaves` by setting each `leaf` bit.
|
|
34
|
+
JeanValjean
|
|
35
|
+
You can normalize a `PileRangeOfLeaves` into a `Leaf` or `None` when the range is degenerate.
|
|
36
|
+
pileRangeOfLeavesAND
|
|
37
|
+
You can AND a `PileRangeOfLeaves` with a disposable mask in a curry-friendly parameter order.
|
|
38
|
+
|
|
39
|
+
Be DRY functions
|
|
40
|
+
getProductsOfDimensions
|
|
41
|
+
You can compute prefix products of `mapShape` dimension lengths.
|
|
42
|
+
getSumsOfProductsOfDimensions
|
|
43
|
+
You can compute prefix sums of `getProductsOfDimensions(mapShape)`.
|
|
44
|
+
getSumsOfProductsOfDimensionsNearest首
|
|
45
|
+
You can compute prefix sums of reversed dimension products for head-first coordinate arithmetic.
|
|
46
|
+
reverseLookup
|
|
47
|
+
You can find a key in a `dict` by matching a value.
|
|
48
|
+
|
|
49
|
+
Flow control
|
|
50
|
+
indicesMapShapeDimensionLengthsAreEqual
|
|
51
|
+
You can group dimension indices by repeated dimension lengths.
|
|
52
|
+
mapShapeIs2上nDimensions
|
|
53
|
+
You can test whether `mapShape` is a $2^n$-dimensional map, optionally with a minimum dimension count.
|
|
54
|
+
|
|
55
|
+
References
|
|
56
|
+
----------
|
|
57
|
+
[1] mapFolding._e.dataBaskets.EliminationState
|
|
58
|
+
Internal package reference
|
|
59
|
+
|
|
60
|
+
"""
|
|
61
|
+
from collections.abc import Iterable, Iterator, Mapping
|
|
62
|
+
from cytoolz.dicttoolz import dissoc as dissociatePiles
|
|
63
|
+
from cytoolz.functoolz import curry as syntacticCurry
|
|
64
|
+
from cytoolz.itertoolz import unique
|
|
65
|
+
from functools import partial, reduce
|
|
66
|
+
from gmpy2 import bit_clear, bit_mask, bit_set, xmpz
|
|
67
|
+
from hunterMakesPy import raiseIfNone
|
|
68
|
+
from itertools import accumulate
|
|
69
|
+
from mapFolding import inclusive, zeroIndexed
|
|
70
|
+
from mapFolding._e import (
|
|
71
|
+
Leaf, LeafOrPileRangeOfLeaves, PermutationSpace, Pile, PileRangeOfLeaves, PilesWithPileRangeOfLeaves, PinnedLeaves)
|
|
72
|
+
from mapFolding._e.filters import extractPinnedLeaves, thisIsALeaf, thisIsAPileRangeOfLeaves
|
|
73
|
+
from more_itertools import iter_index
|
|
74
|
+
from operator import add, mul
|
|
75
|
+
from typing import Any
|
|
76
|
+
|
|
77
|
+
#======== Group-by functions ================================================
|
|
78
|
+
|
|
79
|
+
def bifurcatePermutationSpace(permutationSpace: PermutationSpace) -> tuple[PinnedLeaves, PilesWithPileRangeOfLeaves]:
|
|
80
|
+
"""Separate `permutationSpace` into two dictionaries: one of `pile: leaf` and one of `pile: pileRangeOfLeaves`.
|
|
81
|
+
|
|
82
|
+
Parameters
|
|
83
|
+
----------
|
|
84
|
+
permutationSpace : PermutationSpace
|
|
85
|
+
Dictionary of `pile: leaf` and `pile: pileRangeOfLeaves`.
|
|
86
|
+
|
|
87
|
+
Returns
|
|
88
|
+
-------
|
|
89
|
+
leavesPinned, pilesWithPileRangeOfLeaves : tuple[PinnedLeaves, PilesWithPileRangeOfLeaves]
|
|
90
|
+
"""
|
|
91
|
+
leavesPinned: PinnedLeaves = extractPinnedLeaves(permutationSpace)
|
|
92
|
+
return (leavesPinned, dissociatePiles(permutationSpace, *DOTkeys(leavesPinned))) # pyright: ignore[reportReturnType] # ty:ignore[invalid-return-type]
|
|
93
|
+
|
|
94
|
+
#======== Disaggregation and deconstruction functions ================================================
|
|
95
|
+
|
|
96
|
+
def DOTitems[文件, 文义](dictionary: Mapping[文件, 文义], /) -> Iterator[tuple[文件, 文义]]:
|
|
97
|
+
"""Analogous to `dict.items()`: create an `Iterator` with the "items" from `dictionary`.
|
|
98
|
+
|
|
99
|
+
Parameters
|
|
100
|
+
----------
|
|
101
|
+
dictionary : Mapping[文件, 文义]
|
|
102
|
+
Source mapping.
|
|
103
|
+
|
|
104
|
+
Returns
|
|
105
|
+
-------
|
|
106
|
+
aRiverOfItems : Iterator[tuple[文件, 文义]]
|
|
107
|
+
`Iterator` of items from `dictionary`.
|
|
108
|
+
"""
|
|
109
|
+
return iter(dictionary.items())
|
|
110
|
+
|
|
111
|
+
def DOTkeys[个](dictionary: Mapping[个, Any], /) -> Iterator[个]:
|
|
112
|
+
"""Analogous to `dict.keys()`: create an `Iterator` with the "keys" from `dictionary`.
|
|
113
|
+
|
|
114
|
+
Parameters
|
|
115
|
+
----------
|
|
116
|
+
dictionary : Mapping[个, Any]
|
|
117
|
+
Source mapping.
|
|
118
|
+
|
|
119
|
+
Returns
|
|
120
|
+
-------
|
|
121
|
+
aRiverOfKeys : Iterator[个]
|
|
122
|
+
`Iterator` of keys from `dictionary`.
|
|
123
|
+
"""
|
|
124
|
+
return iter(dictionary.keys())
|
|
125
|
+
|
|
126
|
+
def DOTvalues[个](dictionary: Mapping[Any, 个], /) -> Iterator[个]:
|
|
127
|
+
"""Analogous to `dict.values()`: create an `Iterator` with the "values" from `dictionary`.
|
|
128
|
+
|
|
129
|
+
Parameters
|
|
130
|
+
----------
|
|
131
|
+
dictionary : Mapping[Any, 个]
|
|
132
|
+
Source mapping.
|
|
133
|
+
|
|
134
|
+
Returns
|
|
135
|
+
-------
|
|
136
|
+
aRiverOfValues : Iterator[个]
|
|
137
|
+
`Iterator` of values from `dictionary`.
|
|
138
|
+
"""
|
|
139
|
+
return iter(dictionary.values())
|
|
140
|
+
|
|
141
|
+
def getIteratorOfLeaves(pileRangeOfLeaves: PileRangeOfLeaves) -> Iterator[Leaf]:
|
|
142
|
+
"""Convert `pileRangeOfLeaves` to an `Iterator` of `type` `int` `leaf`.
|
|
143
|
+
|
|
144
|
+
Parameters
|
|
145
|
+
----------
|
|
146
|
+
pileRangeOfLeaves : PileRangeOfLeaves
|
|
147
|
+
An integer with one bit for each `leaf` in `leavesTotal`, plus an extra bit that means "I'm a `pileRangeOfLeaves` not a `leaf`.
|
|
148
|
+
|
|
149
|
+
Returns
|
|
150
|
+
-------
|
|
151
|
+
iteratorOfLeaves : Iterator[int]
|
|
152
|
+
An `Iterator` with one `int` for each `leaf` in `pileRangeOfLeaves`.
|
|
153
|
+
|
|
154
|
+
See Also
|
|
155
|
+
--------
|
|
156
|
+
https://gmpy2.readthedocs.io/en/latest/advmpz.html#gmpy2.xmpz.iter_set
|
|
157
|
+
"""
|
|
158
|
+
iteratorOfLeaves: xmpz = xmpz(pileRangeOfLeaves)
|
|
159
|
+
iteratorOfLeaves[-1] = 0
|
|
160
|
+
return iteratorOfLeaves.iter_set()
|
|
161
|
+
|
|
162
|
+
#======== `PileRangeOfLeaves` functions ================================================
|
|
163
|
+
|
|
164
|
+
# TODO Should `PermutationSpace` be a subclass of `dict` so I can add methods? NOTE I REFUSE TO BE AN OBJECT-ORIENTED
|
|
165
|
+
# PROGRAMMER!!! But, I'll use some OOP if it makes sense. I think collections has some my-first-dict-subclass functions.
|
|
166
|
+
def DOTgetPileIfLeaf(permutationSpace: PermutationSpace, pile: Pile, default: Leaf | None = None) -> Leaf | None:
|
|
167
|
+
"""Like `permutationSpace.get(pile)`, but only return a `leaf` or `default`."""
|
|
168
|
+
ImaLeaf: LeafOrPileRangeOfLeaves | None = permutationSpace.get(pile)
|
|
169
|
+
if thisIsALeaf(ImaLeaf):
|
|
170
|
+
return ImaLeaf
|
|
171
|
+
return default
|
|
172
|
+
|
|
173
|
+
def DOTgetPileIfPileRangeOfLeaves(permutationSpace: PermutationSpace, pile: Pile, default: PileRangeOfLeaves | None = None) -> PileRangeOfLeaves | None:
|
|
174
|
+
"""You can read `permutationSpace[pile]` only when `permutationSpace[pile]` is a `PileRangeOfLeaves`.
|
|
175
|
+
|
|
176
|
+
This function is a typed analogue of `dict.get`. The function returns a `PileRangeOfLeaves` when `permutationSpace[pile]` is a
|
|
177
|
+
`PileRangeOfLeaves`, and the function returns `default` when `permutationSpace[pile]` is a `Leaf` or `None`.
|
|
178
|
+
|
|
179
|
+
Parameters
|
|
180
|
+
----------
|
|
181
|
+
permutationSpace : PermutationSpace
|
|
182
|
+
Dictionary that maps each `Pile` to either a pinned `Leaf` or a `PileRangeOfLeaves` domain.
|
|
183
|
+
pile : Pile
|
|
184
|
+
`Pile` key to look up.
|
|
185
|
+
default : PileRangeOfLeaves | None = None
|
|
186
|
+
Value to return when `permutationSpace[pile]` is not a `PileRangeOfLeaves`.
|
|
187
|
+
|
|
188
|
+
Returns
|
|
189
|
+
-------
|
|
190
|
+
pileRangeOfLeavesOrNone : PileRangeOfLeaves | None
|
|
191
|
+
`PileRangeOfLeaves` value from `permutationSpace[pile]`, or `default`.
|
|
192
|
+
|
|
193
|
+
Examples
|
|
194
|
+
--------
|
|
195
|
+
The function is used to retrieve a domain bitset with a fallback mask.
|
|
196
|
+
|
|
197
|
+
pileRangeOfLeaves: PileRangeOfLeaves = raiseIfNone(DOTgetPileIfPileRangeOfLeaves(permutationSpace, domain[index], default=bit_mask(len(permutationSpace))))
|
|
198
|
+
|
|
199
|
+
References
|
|
200
|
+
----------
|
|
201
|
+
[1] mapFolding._e.filters.thisIsAPileRangeOfLeaves
|
|
202
|
+
Internal package reference
|
|
203
|
+
[2] gmpy2 - Integer arithmetic
|
|
204
|
+
https://gmpy2.readthedocs.io/en/latest/
|
|
205
|
+
[3] hunterMakesPy - Context7
|
|
206
|
+
https://context7.com/hunterhogan/huntermakespy
|
|
207
|
+
|
|
208
|
+
"""
|
|
209
|
+
ImaPileRangeOfLeaves: LeafOrPileRangeOfLeaves | None = permutationSpace.get(pile)
|
|
210
|
+
if thisIsAPileRangeOfLeaves(ImaPileRangeOfLeaves):
|
|
211
|
+
return ImaPileRangeOfLeaves
|
|
212
|
+
return default
|
|
213
|
+
|
|
214
|
+
# TODO Improve semiotics of identifier `getAntiPileRangeOfLeaves`.
|
|
215
|
+
def getAntiPileRangeOfLeaves(leavesTotal: int, leaves: Iterable[Leaf]) -> PileRangeOfLeaves:
|
|
216
|
+
"""You can build a complement `PileRangeOfLeaves` by clearing each `Leaf` bit in `leaves`.
|
|
217
|
+
|
|
218
|
+
The returned `PileRangeOfLeaves` contains a bit for every `Leaf` in `range(leavesTotal)` except each `Leaf` in `leaves`.
|
|
219
|
+
The returned `PileRangeOfLeaves` also preserves the sentinel bit that indicates the value is a `PileRangeOfLeaves`.
|
|
220
|
+
|
|
221
|
+
Parameters
|
|
222
|
+
----------
|
|
223
|
+
leavesTotal : int
|
|
224
|
+
Total number of leaves in the map.
|
|
225
|
+
leaves : Iterable[Leaf]
|
|
226
|
+
Iterable of `Leaf` indices to exclude from the returned `PileRangeOfLeaves`.
|
|
227
|
+
|
|
228
|
+
Returns
|
|
229
|
+
-------
|
|
230
|
+
antiPileRangeOfLeaves : PileRangeOfLeaves
|
|
231
|
+
`PileRangeOfLeaves` bitset containing each allowed `Leaf` plus the `PileRangeOfLeaves` sentinel bit.
|
|
232
|
+
|
|
233
|
+
Examples
|
|
234
|
+
--------
|
|
235
|
+
The function is used to start from the full domain.
|
|
236
|
+
|
|
237
|
+
antiPileRangeOfLeaves: PileRangeOfLeaves = getAntiPileRangeOfLeaves(state.leavesTotal, frozenset())
|
|
238
|
+
|
|
239
|
+
The function is used to exclude every `Leaf` not in a crease relation.
|
|
240
|
+
|
|
241
|
+
antiPileRangeOfLeaves = getAntiPileRangeOfLeaves(state.leavesTotal, set(range(state.leavesTotal)).difference(leavesCrease))
|
|
242
|
+
|
|
243
|
+
References
|
|
244
|
+
----------
|
|
245
|
+
[1] gmpy2 - Integer arithmetic
|
|
246
|
+
https://gmpy2.readthedocs.io/en/latest/
|
|
247
|
+
[2] mapFolding.inclusive
|
|
248
|
+
Internal package reference
|
|
249
|
+
|
|
250
|
+
"""
|
|
251
|
+
return reduce(bit_clear, leaves, bit_mask(leavesTotal + inclusive))
|
|
252
|
+
|
|
253
|
+
def getPileRangeOfLeaves(leavesTotal: int, leaves: Iterable[Leaf]) -> PileRangeOfLeaves:
|
|
254
|
+
"""You can build a `PileRangeOfLeaves` by setting each `Leaf` bit in `leaves`.
|
|
255
|
+
|
|
256
|
+
The returned `PileRangeOfLeaves` contains the sentinel bit that indicates the value is a `PileRangeOfLeaves`. The returned
|
|
257
|
+
`PileRangeOfLeaves` also contains a bit for each `Leaf` in `leaves`.
|
|
258
|
+
|
|
259
|
+
Parameters
|
|
260
|
+
----------
|
|
261
|
+
leavesTotal : int
|
|
262
|
+
Total number of leaves in the map.
|
|
263
|
+
leaves : Iterable[Leaf]
|
|
264
|
+
Iterable of `Leaf` indices to include in the returned `PileRangeOfLeaves`.
|
|
265
|
+
|
|
266
|
+
Returns
|
|
267
|
+
-------
|
|
268
|
+
pileRangeOfLeaves : PileRangeOfLeaves
|
|
269
|
+
`PileRangeOfLeaves` bitset containing each `Leaf` in `leaves` plus the `PileRangeOfLeaves` sentinel bit.
|
|
270
|
+
|
|
271
|
+
Examples
|
|
272
|
+
--------
|
|
273
|
+
The function is used to create a domain bitset before normalizing with `JeanValjean`.
|
|
274
|
+
|
|
275
|
+
permutationSpace2上nDomainDefaults: PermutationSpace = {pile: raiseIfNone(JeanValjean(getPileRangeOfLeaves(state.leavesTotal, pileRangeOfLeaves)))
|
|
276
|
+
for pile, pileRangeOfLeaves in getDictionaryPileRanges(state).items()}
|
|
277
|
+
|
|
278
|
+
References
|
|
279
|
+
----------
|
|
280
|
+
[1] gmpy2 - Integer arithmetic
|
|
281
|
+
https://gmpy2.readthedocs.io/en/latest/
|
|
282
|
+
[2] mapFolding._e._beDRY.JeanValjean
|
|
283
|
+
Internal package reference
|
|
284
|
+
|
|
285
|
+
"""
|
|
286
|
+
return reduce(bit_set, leaves, bit_set(0, leavesTotal))
|
|
287
|
+
|
|
288
|
+
def JeanValjean(p24601: PileRangeOfLeaves, /) -> LeafOrPileRangeOfLeaves | None:
|
|
289
|
+
"""You can normalize a `PileRangeOfLeaves` into a `Leaf` or `None` when the range is degenerate.
|
|
290
|
+
|
|
291
|
+
When `p24601` is a `PileRangeOfLeaves`, `p24601` contains one sentinel bit that indicates the value is a `PileRangeOfLeaves`.
|
|
292
|
+
This function interprets the total set-bit count as a compact encoding of domain cardinality.
|
|
293
|
+
|
|
294
|
+
- When `p24601.bit_count() == 1`, `p24601` is an empty domain. The only set bit is the sentinel bit, so the function returns `None`.
|
|
295
|
+
- When `p24601.bit_count() == 2`, `p24601` contains exactly one `Leaf` plus the sentinel bit. The function converts the range to a
|
|
296
|
+
`Leaf` by returning `raiseIfNone(p24601.bit_scan1())`.
|
|
297
|
+
- Otherwise, the function returns `p24601` unchanged.
|
|
298
|
+
|
|
299
|
+
Parameters
|
|
300
|
+
----------
|
|
301
|
+
p24601 : PileRangeOfLeaves
|
|
302
|
+
Candidate `PileRangeOfLeaves` value.
|
|
303
|
+
|
|
304
|
+
Returns
|
|
305
|
+
-------
|
|
306
|
+
leafOrPileRangeOfLeavesOrNone : LeafOrPileRangeOfLeaves | None
|
|
307
|
+
A `Leaf` when `p24601` encodes exactly one leaf, `None` when `p24601` encodes an empty domain, or `p24601` otherwise.
|
|
308
|
+
|
|
309
|
+
Examples
|
|
310
|
+
--------
|
|
311
|
+
The function is used to normalize a masked domain.
|
|
312
|
+
|
|
313
|
+
if (ImaLeafOrPileRangeOfLeavesNotAWalrusSubscript := JeanValjean(pileRangeOfLeavesAND(antiPileRangeOfLeaves, pileRangeOfLeaves))) is None:
|
|
314
|
+
return {}
|
|
315
|
+
|
|
316
|
+
The function is used to normalize per-pile domains into pinned leaves when possible.
|
|
317
|
+
|
|
318
|
+
permutationSpace2上nDomainDefaults: PermutationSpace = {pile: raiseIfNone(JeanValjean(getPileRangeOfLeaves(state.leavesTotal, pileRangeOfLeaves)))
|
|
319
|
+
for pile, pileRangeOfLeaves in getDictionaryPileRanges(state).items()}
|
|
320
|
+
|
|
321
|
+
References
|
|
322
|
+
----------
|
|
323
|
+
[1] gmpy2 - Integer arithmetic
|
|
324
|
+
https://gmpy2.readthedocs.io/en/latest/
|
|
325
|
+
[2] mapFolding._e.filters.thisIsAPileRangeOfLeaves
|
|
326
|
+
Internal package reference
|
|
327
|
+
[3] hunterMakesPy - Context7
|
|
328
|
+
https://context7.com/hunterhogan/huntermakespy
|
|
329
|
+
|
|
330
|
+
"""
|
|
331
|
+
whoAmI: LeafOrPileRangeOfLeaves | None = p24601
|
|
332
|
+
if thisIsAPileRangeOfLeaves(p24601):
|
|
333
|
+
if p24601.bit_count() == 1:
|
|
334
|
+
whoAmI = None
|
|
335
|
+
elif p24601.bit_count() == 2:
|
|
336
|
+
whoAmI = raiseIfNone(p24601.bit_scan1())
|
|
337
|
+
return whoAmI
|
|
338
|
+
|
|
339
|
+
@syntacticCurry
|
|
340
|
+
def pileRangeOfLeavesAND(pileRangeOfLeavesDISPOSABLE: PileRangeOfLeaves, pileRangeOfLeaves: PileRangeOfLeaves) -> PileRangeOfLeaves:
|
|
341
|
+
"""Modify `pileRangeOfLeaves` by bitwise AND with `pileRangeOfLeavesDISPOSABLE`.
|
|
342
|
+
|
|
343
|
+
Important
|
|
344
|
+
---------
|
|
345
|
+
The order of the parameters is likely the opposite of what you expect. This is to facilitate currying.
|
|
346
|
+
"""
|
|
347
|
+
return pileRangeOfLeaves & pileRangeOfLeavesDISPOSABLE
|
|
348
|
+
|
|
349
|
+
#======== Be DRY functions ================================================
|
|
350
|
+
|
|
351
|
+
def getProductsOfDimensions(mapShape: tuple[int, ...]) -> tuple[int, ...]:
|
|
352
|
+
"""You can compute prefix products of each dimension length in `mapShape`.
|
|
353
|
+
|
|
354
|
+
The returned tuple starts with the product of zero dimensions, which is `1`. Each subsequent element multiplies the next
|
|
355
|
+
dimension length in `mapShape`.
|
|
356
|
+
|
|
357
|
+
Parameters
|
|
358
|
+
----------
|
|
359
|
+
mapShape : tuple[int, ...]
|
|
360
|
+
Map shape as a tuple of dimension lengths.
|
|
361
|
+
|
|
362
|
+
Returns
|
|
363
|
+
-------
|
|
364
|
+
productsOfDimensions : tuple[int, ...]
|
|
365
|
+
Tuple of prefix products with `productsOfDimensions[0] == 1`.
|
|
366
|
+
|
|
367
|
+
Examples
|
|
368
|
+
--------
|
|
369
|
+
The function is used during `EliminationState` initialization.
|
|
370
|
+
|
|
371
|
+
self.productsOfDimensions = getProductsOfDimensions(self.mapShape)
|
|
372
|
+
|
|
373
|
+
References
|
|
374
|
+
----------
|
|
375
|
+
[1] itertools.accumulate
|
|
376
|
+
https://docs.python.org/3/library/itertools.html#itertools.accumulate
|
|
377
|
+
[2] operator.mul
|
|
378
|
+
https://docs.python.org/3/library/operator.html#operator.mul
|
|
379
|
+
[3] mapFolding._e.dataBaskets.EliminationState
|
|
380
|
+
Internal package reference
|
|
381
|
+
|
|
382
|
+
"""
|
|
383
|
+
return tuple(accumulate(mapShape, mul, initial=1))
|
|
384
|
+
|
|
385
|
+
def getSumsOfProductsOfDimensions(mapShape: tuple[int, ...]) -> tuple[int, ...]:
|
|
386
|
+
"""You can compute prefix sums of `getProductsOfDimensions(mapShape)`.
|
|
387
|
+
|
|
388
|
+
The returned tuple starts with the sum of zero products, which is `0`. Each subsequent element adds the next product from
|
|
389
|
+
`getProductsOfDimensions(mapShape)`.
|
|
390
|
+
|
|
391
|
+
Parameters
|
|
392
|
+
----------
|
|
393
|
+
mapShape : tuple[int, ...]
|
|
394
|
+
Map shape as a tuple of dimension lengths.
|
|
395
|
+
|
|
396
|
+
Returns
|
|
397
|
+
-------
|
|
398
|
+
sumsOfProductsOfDimensions : tuple[int, ...]
|
|
399
|
+
Tuple of prefix sums with `sumsOfProductsOfDimensions[0] == 0`.
|
|
400
|
+
|
|
401
|
+
Examples
|
|
402
|
+
--------
|
|
403
|
+
The function is used during `EliminationState` initialization.
|
|
404
|
+
|
|
405
|
+
self.sumsOfProductsOfDimensions = getSumsOfProductsOfDimensions(self.mapShape)
|
|
406
|
+
|
|
407
|
+
References
|
|
408
|
+
----------
|
|
409
|
+
[1] itertools.accumulate
|
|
410
|
+
https://docs.python.org/3/library/itertools.html#itertools.accumulate
|
|
411
|
+
[2] operator.add
|
|
412
|
+
https://docs.python.org/3/library/operator.html#operator.add
|
|
413
|
+
[3] mapFolding._e._beDRY.getProductsOfDimensions
|
|
414
|
+
Internal package reference
|
|
415
|
+
[4] mapFolding._e.dataBaskets.EliminationState
|
|
416
|
+
Internal package reference
|
|
417
|
+
|
|
418
|
+
"""
|
|
419
|
+
return tuple(accumulate(getProductsOfDimensions(mapShape), add, initial=0))
|
|
420
|
+
|
|
421
|
+
def getSumsOfProductsOfDimensionsNearest首(productsOfDimensions: tuple[int, ...], dimensionsTotal: int | None = None, dimensionFrom首: int | None = None) -> tuple[int, ...]:
|
|
422
|
+
"""Get a useful list of numbers.
|
|
423
|
+
|
|
424
|
+
This list of numbers is useful because I am using integers as a proxy for Cartesian coordinates in multidimensional space--and
|
|
425
|
+
because I am trying to abstract the coordinates whether I am enumerating from the origin (0, 0, ..., 0) as represented by the
|
|
426
|
+
integer 0 or from the "anti-origin", which is represented by an integer: but that integer varies based on the mapShape.
|
|
427
|
+
|
|
428
|
+
By using products of dimensions and sums of products of dimensions, I can use the integer-as-coordinate by referencing its
|
|
429
|
+
relative location in the products and sums of products of dimensions.
|
|
430
|
+
|
|
431
|
+
`sumsOfProductsOfDimensionsNearest首` is yet another perspective on these abstractions. Instead of ordering the products in
|
|
432
|
+
ascending order, I order them descending. Then I sum the descending-ordered products.
|
|
433
|
+
|
|
434
|
+
(At least I think that is what I am doing. 2025 December 29.)
|
|
435
|
+
|
|
436
|
+
`dimensionFrom首` almost certainly needs a better identifier. The purpose of the parameter is to define the list of products
|
|
437
|
+
of which I want the sums.
|
|
438
|
+
|
|
439
|
+
"""
|
|
440
|
+
if dimensionsTotal is None:
|
|
441
|
+
dimensionsTotal = len(productsOfDimensions) - 1
|
|
442
|
+
|
|
443
|
+
if dimensionFrom首 is None:
|
|
444
|
+
dimensionFrom首 = dimensionsTotal
|
|
445
|
+
|
|
446
|
+
productsOfDimensionsTruncator: int = dimensionFrom首 - (dimensionsTotal + zeroIndexed)
|
|
447
|
+
|
|
448
|
+
productsOfDimensionsFrom首: tuple[int, ...] = productsOfDimensions[0:productsOfDimensionsTruncator][::-1]
|
|
449
|
+
|
|
450
|
+
sumsOfProductsOfDimensionsNearest首: tuple[int, ...] = tuple(
|
|
451
|
+
sum(productsOfDimensionsFrom首[0:aProduct], start=0)
|
|
452
|
+
for aProduct in range(len(productsOfDimensionsFrom首) + inclusive)
|
|
453
|
+
)
|
|
454
|
+
return sumsOfProductsOfDimensionsNearest首
|
|
455
|
+
|
|
456
|
+
def reverseLookup[文件, 文义](dictionary: dict[文件, 文义], keyValue: 文义) -> 文件 | None:
|
|
457
|
+
"""Return the key in `dictionary` that corresponds to `keyValue`.
|
|
458
|
+
|
|
459
|
+
- I assume all `dictionary.values()` are distinct. If multiple keys contain `keyValue`, the returned key is not predictable.
|
|
460
|
+
- I return `None` if no key maps to `keyValue`, but it is not an efficient way to check for membership.
|
|
461
|
+
- If you *know* a value will be returned, consider combining with `hunterMakesPy.raiseIfNone`.
|
|
462
|
+
"""
|
|
463
|
+
for key, value in dictionary.items():
|
|
464
|
+
if value == keyValue:
|
|
465
|
+
return key
|
|
466
|
+
return None
|
|
467
|
+
|
|
468
|
+
#======== Flow control ================================================
|
|
469
|
+
|
|
470
|
+
def indicesMapShapeDimensionLengthsAreEqual(mapShape: tuple[int, ...]) -> Iterator[tuple[int, ...]]:
|
|
471
|
+
"""You can group dimension indices in `mapShape` by repeated dimension lengths.
|
|
472
|
+
|
|
473
|
+
The returned `Iterator` yields one `tuple` per distinct dimension length in `mapShape` where the dimension length occurs more
|
|
474
|
+
than once. Each yielded `tuple` contains each index where `mapShape[index]` equals the repeated dimension length.
|
|
475
|
+
|
|
476
|
+
Parameters
|
|
477
|
+
----------
|
|
478
|
+
mapShape : tuple[int, ...]
|
|
479
|
+
Map shape as a tuple of dimension lengths.
|
|
480
|
+
|
|
481
|
+
Returns
|
|
482
|
+
-------
|
|
483
|
+
iteratorIndicesSameDimensionLength : Iterator[tuple[int, ...]]
|
|
484
|
+
Iterator of index tuples. Each tuple has length at least 2.
|
|
485
|
+
|
|
486
|
+
Examples
|
|
487
|
+
--------
|
|
488
|
+
The function is used to iterate repeated dimension magnitudes during elimination.
|
|
489
|
+
|
|
490
|
+
for indicesSameDimensionLength in indicesMapShapeDimensionLengthsAreEqual(state.mapShape):
|
|
491
|
+
state.Theorem4Multiplier *= factorial(len(indicesSameDimensionLength))
|
|
492
|
+
for index_k, index_r in pairwise(indicesSameDimensionLength):
|
|
493
|
+
state = excludeLeaf_rBeforeLeaf_k(state, state.productsOfDimensions[index_k], state.productsOfDimensions[index_r])
|
|
494
|
+
|
|
495
|
+
References
|
|
496
|
+
----------
|
|
497
|
+
[1] cytoolz.itertoolz.unique
|
|
498
|
+
https://toolz.readthedocs.io/en/latest/api.html#toolz.itertoolz.unique
|
|
499
|
+
[2] more_itertools.iter_index
|
|
500
|
+
https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.iter_index
|
|
501
|
+
[3] mapFolding._e.algorithms.elimination.theorem4
|
|
502
|
+
Internal package reference
|
|
503
|
+
|
|
504
|
+
"""
|
|
505
|
+
return filter(lambda indices: 1 < len(indices), map(tuple, map(partial(iter_index, mapShape), unique(mapShape))))
|
|
506
|
+
|
|
507
|
+
# NOTE This 2^n-dimensional function is in this module to avoid `import` problems.
|
|
508
|
+
def mapShapeIs2上nDimensions(mapShape: tuple[int, ...], *, youMustBeDimensionsTallToPinThis: int = 3) -> bool:
|
|
509
|
+
"""You can test whether `mapShape` is a $2^n$-dimensional map with a configurable minimum dimension count.
|
|
510
|
+
|
|
511
|
+
This predicate is used as a flow guard for algorithms and pinning rules that only apply to the `mapShape == (2,) * n` special
|
|
512
|
+
case. The predicate returns `True` only when `len(mapShape) >= youMustBeDimensionsTallToPinThis` and each `dimensionLength` in
|
|
513
|
+
`mapShape` equals `2`.
|
|
514
|
+
|
|
515
|
+
Parameters
|
|
516
|
+
----------
|
|
517
|
+
mapShape : tuple[int, ...]
|
|
518
|
+
Map shape as a tuple of dimension lengths.
|
|
519
|
+
youMustBeDimensionsTallToPinThis : int = 3
|
|
520
|
+
Minimum number of dimensions required before treating a $2^n$-dimensional special case as eligible.
|
|
521
|
+
|
|
522
|
+
Returns
|
|
523
|
+
-------
|
|
524
|
+
is2上nDimensions : bool
|
|
525
|
+
`True` when `mapShape` is a $2^n$-dimensional map with the required minimum dimension count.
|
|
526
|
+
|
|
527
|
+
Examples
|
|
528
|
+
--------
|
|
529
|
+
The predicate is used to gate pinning logic.
|
|
530
|
+
|
|
531
|
+
if not mapShapeIs2上nDimensions(state.mapShape):
|
|
532
|
+
return state
|
|
533
|
+
|
|
534
|
+
The predicate is used to gate deeper special cases.
|
|
535
|
+
|
|
536
|
+
if not mapShapeIs2上nDimensions(state.mapShape, youMustBeDimensionsTallToPinThis=5):
|
|
537
|
+
return state
|
|
538
|
+
|
|
539
|
+
References
|
|
540
|
+
----------
|
|
541
|
+
[1] mapFolding._e.pin2上nDimensions.pinPilesAtEnds
|
|
542
|
+
Internal package reference
|
|
543
|
+
[2] mapFolding._e._dataDynamic.addPileRangesOfLeaves
|
|
544
|
+
Internal package reference
|
|
545
|
+
|
|
546
|
+
"""
|
|
547
|
+
return (youMustBeDimensionsTallToPinThis <= len(mapShape)) and all(dimensionLength == 2 for dimensionLength in mapShape)
|