mapFolding 0.13.1__tar.gz → 0.14.1__tar.gz

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.
Files changed (85) hide show
  1. mapfolding-0.14.1/PKG-INFO +77 -0
  2. mapfolding-0.14.1/README.md +21 -0
  3. mapfolding-0.14.1/mapFolding/_oeisFormulas/A000136.py +4 -0
  4. mapfolding-0.14.1/mapFolding/_oeisFormulas/A000560.py +4 -0
  5. mapfolding-0.14.1/mapFolding/_oeisFormulas/A000682.py +17 -0
  6. mapfolding-0.14.1/mapFolding/_oeisFormulas/A005315.py +4 -0
  7. mapfolding-0.14.1/mapFolding/_oeisFormulas/A005316.py +10 -0
  8. mapfolding-0.14.1/mapFolding/_oeisFormulas/A223094.py +7 -0
  9. mapfolding-0.14.1/mapFolding/_oeisFormulas/A259702.py +4 -0
  10. mapfolding-0.14.1/mapFolding/_oeisFormulas/A301620.py +6 -0
  11. mapfolding-0.14.1/mapFolding/_oeisFormulas/Z0Z_aOFn.py +18 -0
  12. mapfolding-0.14.1/mapFolding/_oeisFormulas/Z0Z_oeisMeanders.py +53 -0
  13. mapfolding-0.14.1/mapFolding/_oeisFormulas/__init__.py +1 -0
  14. mapfolding-0.14.1/mapFolding/_oeisFormulas/matrixMeanders.py +79 -0
  15. mapfolding-0.14.1/mapFolding/_oeisFormulas/matrixMeandersAnnex.py +84 -0
  16. mapfolding-0.14.1/mapFolding/_theSSOT.py +123 -0
  17. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/basecamp.py +2 -2
  18. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/beDRY.py +1 -1
  19. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/oeis.py +56 -167
  20. mapfolding-0.14.1/mapFolding/reference/A005316JavaPort.py +134 -0
  21. mapfolding-0.14.1/mapFolding/reference/A005316imperative.py +101 -0
  22. mapfolding-0.14.1/mapFolding/reference/A005316intOptimized.py +122 -0
  23. mapfolding-0.14.1/mapFolding/reference/A005316optimized128bit.py +79 -0
  24. mapfolding-0.14.1/mapFolding/reference/A005316primitiveOptimized.py +97 -0
  25. mapfolding-0.14.1/mapFolding/reference/A005316redis.py +118 -0
  26. mapfolding-0.14.1/mapFolding/reference/A005316write2disk.py +169 -0
  27. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/reference/irvineJavaPort.py +4 -8
  28. mapfolding-0.14.1/mapFolding/reference/matrixMeandersBaseline.py +65 -0
  29. mapfolding-0.14.1/mapFolding/reference/matrixMeandersBaselineAnnex.py +84 -0
  30. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +45 -17
  31. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/tests/conftest.py +13 -13
  32. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/tests/test_computations.py +4 -4
  33. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/tests/test_oeis.py +7 -14
  34. mapfolding-0.14.1/mapFolding.egg-info/PKG-INFO +77 -0
  35. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding.egg-info/SOURCES.txt +22 -0
  36. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding.egg-info/requires.txt +1 -0
  37. {mapfolding-0.13.1 → mapfolding-0.14.1}/pyproject.toml +79 -7
  38. mapfolding-0.13.1/PKG-INFO +0 -154
  39. mapfolding-0.13.1/README.md +0 -99
  40. mapfolding-0.13.1/mapFolding/_theSSOT.py +0 -81
  41. mapfolding-0.13.1/mapFolding.egg-info/PKG-INFO +0 -154
  42. {mapfolding-0.13.1 → mapfolding-0.14.1}/LICENSE +0 -0
  43. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/__init__.py +0 -0
  44. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/_theTypes.py +0 -0
  45. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/daoOfMapFolding.py +0 -0
  46. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/dataBaskets.py +0 -0
  47. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/filesystemToolkit.py +0 -0
  48. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/py.typed +0 -0
  49. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/reference/__init__.py +0 -0
  50. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/reference/flattened.py +0 -0
  51. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/reference/hunterNumba.py +0 -0
  52. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/reference/jaxCount.py +0 -0
  53. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/reference/jobsCompleted/[2x19]/p2x19.py +0 -0
  54. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/reference/jobsCompleted/__init__.py +0 -0
  55. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/reference/jobsCompleted/p2x19/p2x19.py +0 -0
  56. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/reference/lunnonNumpy.py +0 -0
  57. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/reference/lunnonWhile.py +0 -0
  58. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/reference/rotatedEntryPoint.py +0 -0
  59. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/reference/total_countPlus1vsPlusN.py +0 -0
  60. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/someAssemblyRequired/RecipeJob.py +0 -0
  61. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/someAssemblyRequired/__init__.py +0 -0
  62. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/someAssemblyRequired/_toolIfThis.py +0 -0
  63. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/someAssemblyRequired/_toolkitContainers.py +0 -0
  64. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/someAssemblyRequired/getLLVMforNoReason.py +0 -0
  65. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/someAssemblyRequired/infoBooth.py +0 -0
  66. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/someAssemblyRequired/makeAllModules.py +0 -0
  67. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +0 -0
  68. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/someAssemblyRequired/toolkitNumba.py +0 -0
  69. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/someAssemblyRequired/transformationTools.py +0 -0
  70. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/syntheticModules/__init__.py +0 -0
  71. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/syntheticModules/countParallel.py +0 -0
  72. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/syntheticModules/daoOfMapFolding.py +0 -0
  73. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/syntheticModules/dataPacking.py +0 -0
  74. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/syntheticModules/initializeCount.py +0 -0
  75. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/syntheticModules/theorem2.py +0 -0
  76. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/syntheticModules/theorem2Numba.py +0 -0
  77. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/syntheticModules/theorem2Trimmed.py +0 -0
  78. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/tests/__init__.py +0 -0
  79. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/tests/test_filesystem.py +0 -0
  80. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/tests/test_other.py +0 -0
  81. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding/tests/test_tasks.py +0 -0
  82. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding.egg-info/dependency_links.txt +0 -0
  83. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding.egg-info/entry_points.txt +0 -0
  84. {mapfolding-0.13.1 → mapfolding-0.14.1}/mapFolding.egg-info/top_level.txt +0 -0
  85. {mapfolding-0.13.1 → mapfolding-0.14.1}/setup.cfg +0 -0
@@ -0,0 +1,77 @@
1
+ Metadata-Version: 2.4
2
+ Name: mapFolding
3
+ Version: 0.14.1
4
+ Summary: Map folding, meanders, stamp folding, semi-meanders. Experiment with algorithm transformations and code optimization.
5
+ Author-email: Hunter Hogan <HunterHogan@pm.me>
6
+ License: CC-BY-NC-4.0
7
+ Project-URL: Donate, https://www.patreon.com/integrated
8
+ Project-URL: Homepage, https://github.com/hunterhogan/mapFolding
9
+ Project-URL: Issues, https://github.com/hunterhogan/mapFolding/issues
10
+ Project-URL: Repository, https://github.com/hunterhogan/mapFolding.git
11
+ Keywords: A000136,A000560,A000682,A001415,A001416,A001417,A001418,A005315,A005316,A195646,A223094,A259702,A301620,abstract syntax tree,algorithmic combinatorics,algorithmic optimization,arch configurations,AST manipulation,automated code generation,bit-packed arrays,bitwise state machines,cache-efficient algorithms,closed meandric numbers,code generation,code optimization,code synthesis,code transformation,codon optimization,combinatorial computing,combinatorial enumeration,combinatorial geometry,combinatorial mathematics,combinatorial problem solver,combinatorics,computational combinatorics,computational geometry,crossing patterns,curve crossings,dataclass transformation,discrete mathematics,dynamic compilation,enumerative combinatorics,folding pattern enumeration,folding problems,GPU acceleration,high-performance computing,integer sequences,JIT compilation,just-in-time compilation,kernel optimization,labeled stamp folding,low-level computation,map folding,mapFolding,mathematical algorithms,mathematical modeling,mathematical optimization,mathematical patterns,mathematical software,mathematical tool,mathematical visualization,meander enumeration,meanders,meandric systems,memory-efficient enumeration,metaprogramming,Numba optimization,numerical algorithms,numerical computation,OEIS,open meandric systems,paper folding mathematics,parallel computing,pattern recognition,performance optimization,permutation patterns,permutations,post-setup optimization,pyproject,Python optimization,scientific computing,semi-meanders,sequence analysis,sequence calculator,sequence enumeration,sequence explorer,sequence generation,source code analysis,stamp folding,symbolic computation,topological combinatorics,topological patterns,typed Python
12
+ Classifier: Development Status :: 4 - Beta
13
+ Classifier: Environment :: Console
14
+ Classifier: Intended Audience :: Developers
15
+ Classifier: Intended Audience :: Education
16
+ Classifier: Intended Audience :: Science/Research
17
+ Classifier: Natural Language :: English
18
+ Classifier: Operating System :: MacOS
19
+ Classifier: Operating System :: OS Independent
20
+ Classifier: Operating System :: POSIX :: Linux
21
+ Classifier: Programming Language :: Python
22
+ Classifier: Programming Language :: Python :: 3
23
+ Classifier: Programming Language :: Python :: 3 :: Only
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
26
+ Classifier: Programming Language :: Python :: Implementation :: CPython
27
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
28
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
29
+ Classifier: Topic :: Software Development :: Code Generators
30
+ Classifier: Topic :: Software Development :: Compilers
31
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
32
+ Classifier: Topic :: Software Development :: Pre-processors
33
+ Classifier: Typing :: Typed
34
+ Requires-Python: >=3.12
35
+ Description-Content-Type: text/markdown
36
+ License-File: LICENSE
37
+ Requires-Dist: astToolkit
38
+ Requires-Dist: hunterMakesPy
39
+ Requires-Dist: numpy
40
+ Requires-Dist: platformdirs
41
+ Provides-Extra: development
42
+ Requires-Dist: mypy; extra == "development"
43
+ Requires-Dist: pyupgrade; extra == "development"
44
+ Requires-Dist: py-spy; extra == "development"
45
+ Requires-Dist: setuptools-scm; extra == "development"
46
+ Provides-Extra: numba
47
+ Requires-Dist: numba; extra == "numba"
48
+ Requires-Dist: numba_progress; extra == "numba"
49
+ Provides-Extra: testing
50
+ Requires-Dist: numba; extra == "testing"
51
+ Requires-Dist: pytest-cov; extra == "testing"
52
+ Requires-Dist: pytest-env; extra == "testing"
53
+ Requires-Dist: pytest-xdist; extra == "testing"
54
+ Requires-Dist: pytest; extra == "testing"
55
+ Dynamic: license-file
56
+
57
+ # mapFolding
58
+
59
+ [![pip install mapFolding](https://img.shields.io/badge/pip%20install-mapFolding-gray.svg?colorB=3b434b)](https://pypi.org/project/mapFolding/)
60
+
61
+ Map folding, meanders, stamp folding, semi-meanders. Experiment with algorithm transformations and code optimization.
62
+
63
+ Command line:
64
+
65
+ - getOEISids
66
+ - OEIS_for_n
67
+
68
+ The package is focused on mapFolding and stamp folding. But "mapFolding/_oeisFormulas" has some infrastructure for meanders and semi-meanders.
69
+
70
+ There are innovations and insights in the mapFolding stuff.
71
+
72
+ ## My recovery
73
+
74
+ [![Static Badge](https://img.shields.io/badge/2011_August-Homeless_since-blue?style=flat)](https://HunterThinks.com/support)
75
+ [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UC3Gx7kz61009NbhpRtPP7tw)](https://www.youtube.com/@HunterHogan)
76
+
77
+ [![CC-BY-NC-4.0](https://github.com/hunterhogan/mapFolding/blob/main/CC-BY-NC-4.0.png)](https://creativecommons.org/licenses/by-nc/4.0/)
@@ -0,0 +1,21 @@
1
+ # mapFolding
2
+
3
+ [![pip install mapFolding](https://img.shields.io/badge/pip%20install-mapFolding-gray.svg?colorB=3b434b)](https://pypi.org/project/mapFolding/)
4
+
5
+ Map folding, meanders, stamp folding, semi-meanders. Experiment with algorithm transformations and code optimization.
6
+
7
+ Command line:
8
+
9
+ - getOEISids
10
+ - OEIS_for_n
11
+
12
+ The package is focused on mapFolding and stamp folding. But "mapFolding/_oeisFormulas" has some infrastructure for meanders and semi-meanders.
13
+
14
+ There are innovations and insights in the mapFolding stuff.
15
+
16
+ ## My recovery
17
+
18
+ [![Static Badge](https://img.shields.io/badge/2011_August-Homeless_since-blue?style=flat)](https://HunterThinks.com/support)
19
+ [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UC3Gx7kz61009NbhpRtPP7tw)](https://www.youtube.com/@HunterHogan)
20
+
21
+ [![CC-BY-NC-4.0](https://github.com/hunterhogan/mapFolding/blob/main/CC-BY-NC-4.0.png)](https://creativecommons.org/licenses/by-nc/4.0/)
@@ -0,0 +1,4 @@
1
+ from mapFolding._oeisFormulas.A000682 import A000682
2
+
3
+ def A000136(n: int) -> int:
4
+ return n * A000682(n)
@@ -0,0 +1,4 @@
1
+ from mapFolding._oeisFormulas.A000682 import A000682
2
+
3
+ def A000560(n: int) -> int:
4
+ return A000682(n + 1) // 2
@@ -0,0 +1,17 @@
1
+ from mapFolding._oeisFormulas.matrixMeanders import count, curveMaximum
2
+
3
+ def initializeA000682(n: int) -> dict[int, int]:
4
+ curveLocationsMAXIMUM = curveMaximum[n].curveLocationsMAXIMUM
5
+
6
+ curveSeed: int = 5 - (n & 0b1) * 4
7
+ listCurveLocations = [(curveSeed << 1) | curveSeed]
8
+
9
+ while listCurveLocations[-1] < curveLocationsMAXIMUM:
10
+ curveSeed = (curveSeed << 4) | 0b101
11
+ listCurveLocations.append((curveSeed << 1) | curveSeed)
12
+
13
+ return dict.fromkeys(listCurveLocations, 1)
14
+
15
+ def A000682(n: int) -> int:
16
+ return count(n - 1, initializeA000682(n - 1))
17
+
@@ -0,0 +1,4 @@
1
+ from mapFolding._oeisFormulas.A005316 import A005316
2
+
3
+ def A005315(n: int) -> int:
4
+ return A005316(2 * n - 1)
@@ -0,0 +1,10 @@
1
+ from mapFolding._oeisFormulas.matrixMeanders import count
2
+
3
+ def initializeA005316(n: int) -> dict[int, int]:
4
+ if n & 0b1:
5
+ return {22: 1}
6
+ else:
7
+ return {15: 1}
8
+
9
+ def A005316(n: int) -> int:
10
+ return count(n-1, initializeA005316(n-1))
@@ -0,0 +1,7 @@
1
+ from mapFolding._oeisFormulas.A000136 import A000136
2
+ from mapFolding._oeisFormulas.A000682 import A000682
3
+
4
+ def A223094(n: int) -> int:
5
+ return A000136(n) - A000682(n + 1)
6
+
7
+ # %F A223094 For n >= 3: a(n) = n! - Sum_{k=3..n-1} (a(k)*n!/k!) - A000682(n+1). - _Roger Ford_, Aug 24 2024
@@ -0,0 +1,4 @@
1
+ from mapFolding._oeisFormulas.A000682 import A000682
2
+
3
+ def A259702(n: int) -> int:
4
+ return A000682(n) // 2 - A000682(n - 1)
@@ -0,0 +1,6 @@
1
+ from mapFolding._oeisFormulas.A000682 import A000682
2
+
3
+ def A301620(n: int) -> int:
4
+ return A000682(n + 2) - 2 * A000682(n + 1)
5
+
6
+ # %F A301620 a(n) = Sum_{k=3..floor((n+3)/2)} (A259689(n+1,k)*(k-2)). - _Roger Ford_, Dec 10 2018
@@ -0,0 +1,18 @@
1
+ from mapFolding._oeisFormulas.A000136 import A000136
2
+ from mapFolding.oeis import dictionaryOEIS
3
+ import sys
4
+ import time
5
+
6
+ # ruff: noqa: ERA001
7
+
8
+ if __name__ == '__main__':
9
+ oeisID = 'A000136'
10
+ for n in range(3,30):
11
+
12
+ # print(n)
13
+
14
+ timeStart = time.perf_counter()
15
+ foldsTotal = A000136(n)
16
+ # sys.stdout.write(f"{n} {foldsTotal} {time.perf_counter() - timeStart:.2f}\n")
17
+ sys.stdout.write(f"{foldsTotal == dictionaryOEIS[oeisID]['valuesKnown'][n]} {n} {foldsTotal} {time.perf_counter() - timeStart:.2f}\n")
18
+
@@ -0,0 +1,53 @@
1
+ from mapFolding._oeisFormulas.A000560 import A000560
2
+ from mapFolding._oeisFormulas.A000682 import A000682
3
+ from mapFolding._oeisFormulas.A005315 import A005315
4
+ from mapFolding._oeisFormulas.A005316 import A005316
5
+ from mapFolding._oeisFormulas.A223094 import A223094
6
+ from mapFolding._oeisFormulas.A259702 import A259702
7
+ from mapFolding._oeisFormulas.A301620 import A301620
8
+ from mapFolding.oeis import getOEISidInformation, getOEISidValues
9
+ import sys
10
+
11
+ oeisIDsMeanders: list[str] = [
12
+ 'A000560',
13
+ 'A000682',
14
+ 'A005315',
15
+ 'A005316',
16
+ 'A223094',
17
+ 'A259702',
18
+ 'A301620',
19
+ ]
20
+
21
+ dictionaryOEISMeanders: dict[str, dict[str, dict[int, int] | str | int]] = {
22
+ oeisID: {
23
+ 'valuesKnown': getOEISidValues(oeisID),
24
+ 'description': getOEISidInformation(oeisID)[0],
25
+ 'offset': getOEISidInformation(oeisID)[1],
26
+ }
27
+ for oeisID in oeisIDsMeanders
28
+ }
29
+
30
+ # ruff: noqa: S101
31
+ # pyright: reportIndexIssue=false
32
+
33
+ rangeTest = range(5, 13)
34
+
35
+ if __name__ == '__main__':
36
+ for n in rangeTest:
37
+
38
+ A000560for_n = A000560(n)
39
+ assert A000560for_n == dictionaryOEISMeanders['A000560']['valuesKnown'][n]
40
+ A000682for_n = A000682(n)
41
+ assert A000682for_n == dictionaryOEISMeanders['A000682']['valuesKnown'][n]
42
+ A005315for_n = A005315(n)
43
+ assert A005315for_n == dictionaryOEISMeanders['A005315']['valuesKnown'][n]
44
+ A005316for_n = A005316(n)
45
+ assert A005316for_n == dictionaryOEISMeanders['A005316']['valuesKnown'][n]
46
+ A223094for_n = A223094(n)
47
+ assert A223094for_n == dictionaryOEISMeanders['A223094']['valuesKnown'][n]
48
+ A259702for_n = A259702(n)
49
+ assert A259702for_n == dictionaryOEISMeanders['A259702']['valuesKnown'][n]
50
+ A301620for_n = A301620(n)
51
+ assert A301620for_n == dictionaryOEISMeanders['A301620']['valuesKnown'][n]
52
+
53
+ sys.stdout.write(f"\nTrue for {str(rangeTest)}\n")
@@ -0,0 +1 @@
1
+ """OEIS formula collection and analysis."""
@@ -0,0 +1,79 @@
1
+ from mapFolding._oeisFormulas.matrixMeandersAnnex import curveMaximum as curveMaximum
2
+ from typing import NamedTuple
3
+
4
+ class BifurcatedCurves(NamedTuple):
5
+ bifurcationEven: int
6
+ bifurcationOdd: int
7
+ distinctCrossings: int
8
+ curveLocationsMAXIMUM: int
9
+
10
+ dictionaryCurveLocations: dict[int, list[int]] = {}
11
+
12
+ def getCurveLocations(bridges: int) -> list[BifurcatedCurves]:
13
+ global dictionaryCurveLocations # noqa: PLW0603
14
+ curveLocationsMAXIMUM, bifurcationEvenLocator, bifurcationOddLocator = curveMaximum[bridges]
15
+ listBifurcatedCurves: list[BifurcatedCurves] = []
16
+ # TODO This is ready for concurrency and/or vectorization.
17
+ for curveLocations, listDistinctCrossings in dictionaryCurveLocations.items():
18
+ bifurcationEven = (curveLocations & bifurcationEvenLocator) >> 1
19
+ bifurcationOdd = (curveLocations & bifurcationOddLocator)
20
+ distinctCrossings = sum(listDistinctCrossings)
21
+ listBifurcatedCurves.append(BifurcatedCurves(bifurcationEven, bifurcationOdd, distinctCrossings, curveLocationsMAXIMUM))
22
+ dictionaryCurveLocations = {}
23
+ return listBifurcatedCurves
24
+
25
+ def recordAnalysis(curveLocationAnalysis: int, curveLocationsMAXIMUM: int, distinctCrossings: int) -> None:
26
+ if curveLocationAnalysis < curveLocationsMAXIMUM:
27
+ dictionaryCurveLocations.setdefault(curveLocationAnalysis, []).append(distinctCrossings)
28
+
29
+ def analyzeCurve(bifurcationEven: int, bifurcationOdd: int, distinctCrossings: int, curveLocationsMAXIMUM: int) -> None:
30
+ bifurcationEvenFinalZero = (bifurcationEven & 0b1) == 0
31
+ bifurcationEvenHasCurves = bifurcationEven != 1
32
+ bifurcationOddFinalZero = (bifurcationOdd & 0b1) == 0
33
+ bifurcationOddHasCurves = bifurcationOdd != 1
34
+
35
+ if bifurcationEvenHasCurves:
36
+ curveLocationAnalysis = (bifurcationEven >> 1) | (bifurcationOdd << 2) | bifurcationEvenFinalZero
37
+ recordAnalysis(curveLocationAnalysis, curveLocationsMAXIMUM, distinctCrossings)
38
+
39
+ if bifurcationOddHasCurves:
40
+ curveLocationAnalysis = (bifurcationOdd >> 2) | (bifurcationEven << 3) | (bifurcationOddFinalZero << 1)
41
+ recordAnalysis(curveLocationAnalysis, curveLocationsMAXIMUM, distinctCrossings)
42
+
43
+ curveLocationAnalysis = ((bifurcationOdd | (bifurcationEven << 1)) << 2) | 3
44
+ recordAnalysis(curveLocationAnalysis, curveLocationsMAXIMUM, distinctCrossings)
45
+
46
+ if bifurcationEvenHasCurves and bifurcationOddHasCurves and (bifurcationEvenFinalZero or bifurcationOddFinalZero):
47
+ XOrHere2makePair = 0b1
48
+ findUnpairedBinary1 = 0
49
+
50
+ if bifurcationEvenFinalZero and not bifurcationOddFinalZero:
51
+ while findUnpairedBinary1 >= 0:
52
+ XOrHere2makePair <<= 2
53
+ findUnpairedBinary1 += 1 if (bifurcationEven & XOrHere2makePair) == 0 else -1
54
+ bifurcationEven ^= XOrHere2makePair
55
+
56
+ elif bifurcationOddFinalZero and not bifurcationEvenFinalZero:
57
+ while findUnpairedBinary1 >= 0:
58
+ XOrHere2makePair <<= 2
59
+ findUnpairedBinary1 += 1 if (bifurcationOdd & XOrHere2makePair) == 0 else -1
60
+ bifurcationOdd ^= XOrHere2makePair
61
+
62
+ curveLocationAnalysis = ((bifurcationEven >> 2) << 1) | (bifurcationOdd >> 2)
63
+ recordAnalysis(curveLocationAnalysis, curveLocationsMAXIMUM, distinctCrossings)
64
+
65
+ def initializeCurveLocations(startingCurveLocations: dict[int, int]) -> None:
66
+ global dictionaryCurveLocations # noqa: PLW0603
67
+ dictionaryCurveLocations = {curve: [distinctCrossings] for curve, distinctCrossings in startingCurveLocations.items()}
68
+
69
+ def count(bridges: int, startingCurveLocations: dict[int, int]) -> int:
70
+ initializeCurveLocations(startingCurveLocations)
71
+
72
+ while bridges > 0:
73
+ bridges -= 1
74
+
75
+ # TODO This could be parallelized when `recordAnalysis` is thread-safe
76
+ for bifurcatedCurve in getCurveLocations(bridges):
77
+ analyzeCurve(*bifurcatedCurve)
78
+
79
+ return getCurveLocations(bridges)[0].distinctCrossings
@@ -0,0 +1,84 @@
1
+ from typing import NamedTuple
2
+ import sys
3
+
4
+ class limitLocators(NamedTuple):
5
+ curveLocationsMAXIMUM: int
6
+ bifurcationEvenLocator: int
7
+ bifurcationOddLocator: int
8
+
9
+ curveMaximum: dict[int, limitLocators] = {
10
+ 0: limitLocators(16, 0x2a, 0x15),
11
+ 1: limitLocators(64, 0xaa, 0x55),
12
+ 2: limitLocators(256, 0x2aa, 0x155),
13
+ 3: limitLocators(1024, 0xaaa, 0x555),
14
+ 4: limitLocators(4096, 0x2aaa, 0x1555),
15
+ 5: limitLocators(16384, 0xaaaa, 0x5555),
16
+ 6: limitLocators(65536, 0x2aaaa, 0x15555),
17
+ 7: limitLocators(262144, 0xaaaaa, 0x55555),
18
+ 8: limitLocators(1048576, 0x2aaaaa, 0x155555),
19
+ 9: limitLocators(4194304, 0xaaaaaa, 0x555555),
20
+ 10: limitLocators(16777216, 0x2aaaaaa, 0x1555555),
21
+ 11: limitLocators(67108864, 0xaaaaaaa, 0x5555555),
22
+ 12: limitLocators(268435456, 0x2aaaaaaa, 0x15555555),
23
+ 13: limitLocators(1073741824, 0xaaaaaaaa, 0x55555555),
24
+ 14: limitLocators(4294967296, 0x2aaaaaaaa, 0x155555555),
25
+ 15: limitLocators(17179869184, 0xaaaaaaaaa, 0x555555555),
26
+ 16: limitLocators(68719476736, 0x2aaaaaaaaa, 0x1555555555),
27
+ 17: limitLocators(274877906944, 0xaaaaaaaaaa, 0x5555555555),
28
+ 18: limitLocators(1099511627776, 0x2aaaaaaaaaa, 0x15555555555),
29
+ 19: limitLocators(4398046511104, 0xaaaaaaaaaaa, 0x55555555555),
30
+ 20: limitLocators(17592186044416, 0x2aaaaaaaaaaa, 0x155555555555),
31
+ 21: limitLocators(70368744177664, 0xaaaaaaaaaaaa, 0x555555555555),
32
+ 22: limitLocators(281474976710656, 0x2aaaaaaaaaaaa, 0x1555555555555),
33
+ 23: limitLocators(1125899906842624, 0xaaaaaaaaaaaaa, 0x5555555555555),
34
+ 24: limitLocators(4503599627370496, 0x2aaaaaaaaaaaaa, 0x15555555555555),
35
+ 25: limitLocators(18014398509481984, 0xaaaaaaaaaaaaaa, 0x55555555555555),
36
+ 26: limitLocators(72057594037927936, 0x2aaaaaaaaaaaaaa, 0x155555555555555),
37
+ 27: limitLocators(288230376151711744, 0xaaaaaaaaaaaaaaa, 0x555555555555555),
38
+ 28: limitLocators(1152921504606846976, 0x2aaaaaaaaaaaaaaa, 0x1555555555555555), # 0x2aaaaaaaaaaaaaaa.bit_length() = 62
39
+ 29: limitLocators(4611686018427387904, 0xaaaaaaaaaaaaaaaa, 0x5555555555555555),
40
+ 30: limitLocators(18446744073709551616, 0x2aaaaaaaaaaaaaaaa, 0x15555555555555555),
41
+ 31: limitLocators(73786976294838206464, 0xaaaaaaaaaaaaaaaaa, 0x55555555555555555),
42
+ 32: limitLocators(295147905179352825856, 0x2aaaaaaaaaaaaaaaaa, 0x155555555555555555),
43
+ 33: limitLocators(1180591620717411303424, 0xaaaaaaaaaaaaaaaaaa, 0x555555555555555555),
44
+ 34: limitLocators(4722366482869645213696, 0x2aaaaaaaaaaaaaaaaaa, 0x1555555555555555555),
45
+ 35: limitLocators(18889465931478580854784, 0xaaaaaaaaaaaaaaaaaaa, 0x5555555555555555555),
46
+ 36: limitLocators(75557863725914323419136, 0x2aaaaaaaaaaaaaaaaaaa, 0x15555555555555555555),
47
+ 37: limitLocators(302231454903657293676544, 0xaaaaaaaaaaaaaaaaaaaa, 0x55555555555555555555),
48
+ 38: limitLocators(1208925819614629174706176, 0x2aaaaaaaaaaaaaaaaaaaa, 0x155555555555555555555),
49
+ 39: limitLocators(4835703278458516698824704, 0xaaaaaaaaaaaaaaaaaaaaa, 0x555555555555555555555),
50
+ 40: limitLocators(19342813113834066795298816, 0x2aaaaaaaaaaaaaaaaaaaaa, 0x1555555555555555555555),
51
+ 41: limitLocators(77371252455336267181195264, 0xaaaaaaaaaaaaaaaaaaaaaa, 0x5555555555555555555555),
52
+ 42: limitLocators(309485009821345068724781056, 0x2aaaaaaaaaaaaaaaaaaaaaa, 0x15555555555555555555555),
53
+ 43: limitLocators(1237940039285380274899124224, 0xaaaaaaaaaaaaaaaaaaaaaaa, 0x55555555555555555555555),
54
+ 44: limitLocators(4951760157141521099596496896, 0x2aaaaaaaaaaaaaaaaaaaaaaa, 0x155555555555555555555555),
55
+ 45: limitLocators(19807040628566084398385987584, 0xaaaaaaaaaaaaaaaaaaaaaaaa, 0x555555555555555555555555),
56
+ 46: limitLocators(79228162514264337593543950336, 0x2aaaaaaaaaaaaaaaaaaaaaaaa, 0x1555555555555555555555555),
57
+ 47: limitLocators(316912650057057350374175801344, 0xaaaaaaaaaaaaaaaaaaaaaaaaa, 0x5555555555555555555555555),
58
+ 48: limitLocators(1267650600228229401496703205376, 0x2aaaaaaaaaaaaaaaaaaaaaaaaa, 0x15555555555555555555555555),
59
+ 49: limitLocators(5070602400912917605986812821504, 0xaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x55555555555555555555555555),
60
+ 50: limitLocators(20282409603651670423947251286016, 0x2aaaaaaaaaaaaaaaaaaaaaaaaaa, 0x155555555555555555555555555),
61
+ 51: limitLocators(81129638414606681695789005144064, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x555555555555555555555555555),
62
+ 52: limitLocators(324518553658426726783156020576256, 0x2aaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x1555555555555555555555555555),
63
+ 53: limitLocators(1298074214633706907132624082305024, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x5555555555555555555555555555),
64
+ 54: limitLocators(5192296858534827628530496329220096, 0x2aaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x15555555555555555555555555555),
65
+ 55: limitLocators(20769187434139310514121985316880384, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x55555555555555555555555555555),
66
+ 56: limitLocators(83076749736557242056487941267521536, 0x2aaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x155555555555555555555555555555),
67
+ 57: limitLocators(332306998946228968225951765070086144, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x555555555555555555555555555555),
68
+ 58: limitLocators(1329227995784915872903807060280344576, 0x2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x1555555555555555555555555555555),
69
+ 59: limitLocators(5316911983139663491615228241121378304, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x5555555555555555555555555555555),
70
+ 60: limitLocators(21267647932558653966460912964485513216, 0x2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x15555555555555555555555555555555),
71
+ 61: limitLocators(85070591730234615865843651857942052864, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x55555555555555555555555555555555),
72
+ }
73
+
74
+ def makeCurveMaximum() -> None:
75
+ sys.stdout.write("curveMaximum: dict[int, limitLocators] = {\n")
76
+ for n in range(62):
77
+ curveLocationsMAXIMUM = 1 << (2 * n + 4)
78
+ bifurcationOddLocator = int('01' * ((curveLocationsMAXIMUM.bit_length() + 1) // 2), 2)
79
+ sys.stdout.write(f"{n}: limitLocators({curveLocationsMAXIMUM}, {hex(bifurcationOddLocator << 1)}, {hex(bifurcationOddLocator)}),\n")
80
+ sys.stdout.write("}\n")
81
+
82
+ if __name__ == '__main__':
83
+ makeCurveMaximum()
84
+
@@ -0,0 +1,123 @@
1
+ """Primary goal: access and configure package settings and metadata.
2
+
3
+ Secondary goal: store hardcoded values until I implement a dynamic solution.
4
+ """
5
+
6
+ from collections.abc import Callable
7
+ from hunterMakesPy import PackageSettings
8
+ from pathlib import Path
9
+ from typing import TypedDict
10
+ import dataclasses
11
+ import random
12
+
13
+ # TODO eliminate hardcoding
14
+ concurrencyPackageHARDCODED = 'multiprocessing'
15
+ """Default package identifier for concurrent execution operations."""
16
+
17
+ class MetadataOEISidManuallySet(TypedDict):
18
+ """Settings that are best selected by a human instead of algorithmically."""
19
+
20
+ getMapShape: Callable[[int], tuple[int, ...]]
21
+ """Function to convert the OEIS sequence index, 'n', to its `mapShape` tuple."""
22
+ valuesBenchmark: list[int]
23
+ """List of index values, 'n', to use when benchmarking the algorithm performance."""
24
+ valuesTestParallelization: list[int]
25
+ """List of index values, 'n', to use when testing parallelization performance."""
26
+ valuesTestValidation: list[int]
27
+ """List of index values, 'n', to use when testing validation performance."""
28
+
29
+ @dataclasses.dataclass
30
+ class mapFoldingPackageSettings(PackageSettings):
31
+ """Centralized configuration container for all package-wide settings.
32
+
33
+ (AI generated docstring)
34
+
35
+ This dataclass serves as the single source of truth for package configuration,
36
+ providing both static and dynamically-resolved values needed throughout the
37
+ package lifecycle. The metadata on each field indicates when that value is
38
+ determined - either during packaging or at installation/runtime.
39
+
40
+ The design supports different evaluation phases to optimize performance and
41
+ reliability. Packaging-time values can be determined during package creation,
42
+ while installing-time values require filesystem access or module introspection.
43
+
44
+ Attributes
45
+ ----------
46
+ fileExtension : str = '.py'
47
+ Standard file extension for Python modules in this package.
48
+ packageName : str
49
+ Canonical name of the package as defined in project configuration.
50
+ pathPackage : Path
51
+ Absolute filesystem path to the installed package directory.
52
+ concurrencyPackage : str | None = None
53
+ Package identifier for concurrent execution operations.
54
+
55
+ """
56
+
57
+ concurrencyPackage: str | None = None
58
+ """
59
+ Package identifier for concurrent execution operations.
60
+
61
+ (AI generated docstring)
62
+
63
+ Specifies which Python package should be used for parallel processing
64
+ in computationally intensive operations. When None, the default concurrency
65
+ package specified in the module constants is used. Accepted values include
66
+ 'multiprocessing' for standard parallel processing and 'numba' for
67
+ specialized numerical computations.
68
+ """
69
+
70
+ identifierPackageFALLBACK = "mapFolding"
71
+ """Hardcoded package name used as fallback when dynamic resolution fails."""
72
+
73
+ concurrencyPackage = concurrencyPackageHARDCODED
74
+ """Active concurrency package configuration for the current session."""
75
+
76
+ # TODO I made a `TypedDict` before I knew how to make dataclasses and classes. Think about other data structures.
77
+ settingsOEISManuallySelected: dict[str, MetadataOEISidManuallySet] = {
78
+ 'A000136': {
79
+ 'getMapShape': lambda n: tuple(sorted([1, n])),
80
+ 'valuesBenchmark': [14],
81
+ 'valuesTestParallelization': [*range(3, 7)],
82
+ 'valuesTestValidation': [random.randint(2, 9)], # noqa: S311
83
+ },
84
+ 'A001415': {
85
+ 'getMapShape': lambda n: tuple(sorted([2, n])),
86
+ 'valuesBenchmark': [14],
87
+ 'valuesTestParallelization': [*range(3, 7)],
88
+ 'valuesTestValidation': [random.randint(2, 9)], # noqa: S311
89
+ },
90
+ 'A001416': {
91
+ 'getMapShape': lambda n: tuple(sorted([3, n])),
92
+ 'valuesBenchmark': [9],
93
+ 'valuesTestParallelization': [*range(3, 5)],
94
+ 'valuesTestValidation': [random.randint(2, 6)], # noqa: S311
95
+ },
96
+ 'A001417': {
97
+ 'getMapShape': lambda n: tuple(2 for _dimension in range(n)),
98
+ 'valuesBenchmark': [6],
99
+ 'valuesTestParallelization': [*range(2, 4)],
100
+ 'valuesTestValidation': [random.randint(2, 4)], # noqa: S311
101
+ },
102
+ 'A195646': {
103
+ 'getMapShape': lambda n: tuple(3 for _dimension in range(n)),
104
+ 'valuesBenchmark': [3],
105
+ 'valuesTestParallelization': [*range(2, 3)],
106
+ 'valuesTestValidation': [2],
107
+ },
108
+ 'A001418': {
109
+ 'getMapShape': lambda n: (n, n),
110
+ 'valuesBenchmark': [5],
111
+ 'valuesTestParallelization': [*range(2, 4)],
112
+ 'valuesTestValidation': [random.randint(2, 4)], # noqa: S311
113
+ },
114
+ }
115
+
116
+ packageSettings = mapFoldingPackageSettings(
117
+ identifierPackageFALLBACK=identifierPackageFALLBACK
118
+ , concurrencyPackage=concurrencyPackage)
119
+ """Global package settings."""
120
+ cacheDays = 30
121
+ """Number of days to retain cached OEIS data before refreshing from the online source."""
122
+ pathCache: Path = packageSettings.pathPackage / ".cache"
123
+ """Local directory path for storing cached OEIS sequence data and metadata."""
@@ -96,9 +96,9 @@ def countFolds(listDimensions: Sequence[int] | None = None # noqa: C901, PLR091
96
96
  pass
97
97
  else:
98
98
  if oeisID and oeis_n:
99
- from mapFolding.oeis import settingsOEIS # noqa: PLC0415
99
+ from mapFolding.oeis import dictionaryOEIS # noqa: PLC0415
100
100
  with contextlib.suppress(KeyError):
101
- mapShape = settingsOEIS[oeisID]['getMapShape'](oeis_n)
101
+ mapShape = dictionaryOEIS[oeisID]['getMapShape'](oeis_n)
102
102
  if not mapShape and listDimensions:
103
103
  mapShape = validateListDimensions(listDimensions)
104
104
 
@@ -319,7 +319,7 @@ def validateListDimensions(listDimensions: Sequence[int]) -> tuple[int, ...]:
319
319
  message = f"I received `{dimension = }` in `{listDimensions = }`, but all dimensions must be a non-negative integer."
320
320
  raise ValueError(message)
321
321
  mapDimensions.append(dimension)
322
- if len(mapDimensions) < 2: # noqa: PLR2004
322
+ if len(mapDimensions) < 2:
323
323
  message = f"This function requires `{listDimensions = }` to have at least two dimensions greater than 0. You may want to look at https://oeis.org/."
324
324
  raise NotImplementedError(message)
325
325