mapFolding 0.8.0__py3-none-any.whl → 0.8.1__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.
Files changed (34) hide show
  1. mapFolding/__init__.py +33 -4
  2. mapFolding/basecamp.py +14 -0
  3. mapFolding/beDRY.py +16 -1
  4. mapFolding/filesystem.py +124 -90
  5. mapFolding/noHomeYet.py +12 -0
  6. mapFolding/oeis.py +16 -1
  7. mapFolding/reference/__init__.py +0 -0
  8. mapFolding/reference/flattened.py +46 -45
  9. mapFolding/reference/hunterNumba.py +4 -4
  10. mapFolding/reference/irvineJavaPort.py +1 -1
  11. mapFolding/reference/lunnanNumpy.py +3 -4
  12. mapFolding/reference/lunnanWhile.py +5 -7
  13. mapFolding/reference/rotatedEntryPoint.py +2 -3
  14. mapFolding/someAssemblyRequired/__init__.py +29 -0
  15. mapFolding/someAssemblyRequired/getLLVMforNoReason.py +32 -14
  16. mapFolding/someAssemblyRequired/ingredientsNumba.py +22 -1
  17. mapFolding/someAssemblyRequired/synthesizeNumbaFlow.py +196 -0
  18. mapFolding/someAssemblyRequired/synthesizeNumbaJobVESTIGIAL.py +3 -4
  19. mapFolding/someAssemblyRequired/transformDataStructures.py +162 -0
  20. mapFolding/someAssemblyRequired/transformationTools.py +216 -199
  21. mapFolding/theDao.py +19 -5
  22. mapFolding/theSSOT.py +19 -1
  23. {mapfolding-0.8.0.dist-info → mapfolding-0.8.1.dist-info}/METADATA +50 -44
  24. mapfolding-0.8.1.dist-info/RECORD +39 -0
  25. {mapfolding-0.8.0.dist-info → mapfolding-0.8.1.dist-info}/WHEEL +1 -1
  26. mapFolding/reference/lunnan.py +0 -153
  27. mapFolding/someAssemblyRequired/Z0Z_workbench.py +0 -350
  28. mapFolding/someAssemblyRequired/synthesizeDataConverters.py +0 -117
  29. mapFolding/syntheticModules/numbaCountHistoricalExample.py +0 -158
  30. mapFolding/syntheticModules/numba_doTheNeedfulHistoricalExample.py +0 -13
  31. mapfolding-0.8.0.dist-info/RECORD +0 -41
  32. {mapfolding-0.8.0.dist-info → mapfolding-0.8.1.dist-info}/entry_points.txt +0 -0
  33. {mapfolding-0.8.0.dist-info → mapfolding-0.8.1.dist-info/licenses}/LICENSE +0 -0
  34. {mapfolding-0.8.0.dist-info → mapfolding-0.8.1.dist-info}/top_level.txt +0 -0
mapFolding/theDao.py CHANGED
@@ -1,14 +1,28 @@
1
- from concurrent.futures import Future as ConcurrentFuture, ProcessPoolExecutor
2
- from copy import deepcopy
3
- from mapFolding.theSSOT import ComputationState
4
- from multiprocessing import set_start_method as multiprocessing_set_start_method
5
-
6
1
  """
2
+ Core computational algorithm for map folding counting and enumeration.
3
+
4
+ This module implements the core algorithms for enumerating and counting the various ways
5
+ a rectangular map can be folded. It uses a functional state-transformation approach, where
6
+ each function performs a specific state mutation and returns the updated state. The module
7
+ provides three main counting algorithms:
8
+
9
+ 1. countInitialize: Sets up the initial state for computation
10
+ 2. countSequential: Processes the folding computation sequentially
11
+ 3. countParallel: Distributes the computation across multiple processes
12
+
13
+ All algorithms operate on a ComputationState object that tracks the folding process, including:
7
14
  - A "leaf" is a unit square in the map
8
15
  - A "gap" is a potential position where a new leaf can be folded
9
16
  - Connections track how leaves can connect above/below each other
10
17
  - Leaves are enumerated starting from 1, not 0; hence, leaf1ndex not leafIndex
18
+
19
+ The doTheNeedful function is the main entry point that orchestrates the computation strategy
20
+ based on task divisions and concurrency parameters.
11
21
  """
22
+ from concurrent.futures import Future as ConcurrentFuture, ProcessPoolExecutor
23
+ from copy import deepcopy
24
+ from mapFolding.theSSOT import ComputationState
25
+ from multiprocessing import set_start_method as multiprocessing_set_start_method
12
26
 
13
27
  # When to use multiprocessing.set_start_method https://github.com/hunterhogan/mapFolding/issues/6
14
28
  if __name__ == '__main__':
mapFolding/theSSOT.py CHANGED
@@ -1,3 +1,21 @@
1
+ """
2
+ Single Source of Truth module for configuration, types, and computational state management.
3
+
4
+ This module defines the core data structures, type definitions, and configuration settings
5
+ used throughout the mapFolding package. It implements the Single Source of Truth (SSOT)
6
+ principle to ensure consistency across the package's components.
7
+
8
+ Key features:
9
+ 1. The ComputationState dataclass, which encapsulates the state of the folding computation
10
+ 2. Unified type definitions for integers and arrays used in the computation
11
+ 3. Configuration settings for synthetic module generation and dispatching
12
+ 4. Path resolution and management for package resources and job output
13
+ 5. Dynamic dispatch functionality for algorithm implementations
14
+
15
+ The module differentiates between "the" identifiers (package defaults) and other identifiers
16
+ to avoid namespace collisions when transforming algorithms.
17
+ """
18
+
1
19
  from collections.abc import Callable
2
20
  from importlib import import_module as importlib_import_module
3
21
  from inspect import getfile as inspect_getfile
@@ -149,7 +167,7 @@ class ComputationState:
149
167
  foldsTotal: DatatypeFoldsTotal = DatatypeFoldsTotal(0)
150
168
  gap1ndex: DatatypeLeavesTotal = DatatypeLeavesTotal(0)
151
169
  gap1ndexCeiling: DatatypeElephino = DatatypeElephino(0)
152
- groupsOfFolds: DatatypeFoldsTotal = DatatypeFoldsTotal(0)
170
+ groupsOfFolds: DatatypeFoldsTotal = dataclasses.field(default=DatatypeFoldsTotal(0), metadata={'theCountingIdentifier': True})
153
171
  indexDimension: DatatypeLeavesTotal = DatatypeLeavesTotal(0)
154
172
  indexLeaf: DatatypeLeavesTotal = DatatypeLeavesTotal(0)
155
173
  indexMiniGap: DatatypeElephino = DatatypeElephino(0)
@@ -1,18 +1,17 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: mapFolding
3
- Version: 0.8.0
4
- Summary: Count distinct ways to fold a map (or a strip of stamps)
3
+ Version: 0.8.1
4
+ Summary: Map folding algorithm with code transformation framework for optimizing numerical computations
5
5
  Author-email: Hunter Hogan <HunterHogan@pm.me>
6
6
  License: CC-BY-NC-4.0
7
7
  Project-URL: Donate, https://www.patreon.com/integrated
8
8
  Project-URL: Homepage, https://github.com/hunterhogan/mapFolding
9
9
  Project-URL: Repository, https://github.com/hunterhogan/mapFolding.git
10
- Keywords: A001415,A001416,A001417,A001418,A195646,combinatorics,folding,map folding,OEIS,optimization,stamp folding
10
+ Keywords: A001415,A001416,A001417,A001418,A195646,algorithmic optimization,AST manipulation,code generation,code transformation,combinatorics,computational geometry,dataclass transformation,folding pattern enumeration,just-in-time compilation,map folding,Numba optimization,OEIS,performance optimization,source code analysis,stamp folding
11
11
  Classifier: Development Status :: 4 - Beta
12
12
  Classifier: Environment :: Console
13
+ Classifier: Intended Audience :: Developers
13
14
  Classifier: Intended Audience :: Education
14
- Classifier: Intended Audience :: End Users/Desktop
15
- Classifier: Intended Audience :: Other Audience
16
15
  Classifier: Intended Audience :: Science/Research
17
16
  Classifier: Natural Language :: English
18
17
  Classifier: Operating System :: OS Independent
@@ -23,7 +22,10 @@ Classifier: Programming Language :: Python :: 3.11
23
22
  Classifier: Programming Language :: Python :: 3.12
24
23
  Classifier: Programming Language :: Python :: 3.13
25
24
  Classifier: Topic :: Scientific/Engineering :: Mathematics
25
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
26
+ Classifier: Topic :: Software Development :: Code Generators
26
27
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
28
+ Classifier: Topic :: Software Development :: Compilers
27
29
  Classifier: Typing :: Typed
28
30
  Requires-Python: >=3.10
29
31
  Description-Content-Type: text/markdown
@@ -43,6 +45,7 @@ Requires-Dist: pytest-cov; extra == "testing"
43
45
  Requires-Dist: pytest-env; extra == "testing"
44
46
  Requires-Dist: pytest-xdist; extra == "testing"
45
47
  Requires-Dist: pyupgrade; extra == "testing"
48
+ Dynamic: license-file
46
49
 
47
50
  # mapFolding: Algorithms for enumerating distinct map/stamp folding patterns 🗺️
48
51
 
@@ -51,8 +54,6 @@ Requires-Dist: pyupgrade; extra == "testing"
51
54
  [![Python Tests](https://github.com/hunterhogan/mapFolding/actions/workflows/pythonTests.yml/badge.svg)](https://github.com/hunterhogan/mapFolding/actions/workflows/pythonTests.yml)
52
55
  ![Static Badge](https://img.shields.io/badge/issues-I%20have%20them-brightgreen)
53
56
  [![License: CC-BY-NC-4.0](https://img.shields.io/badge/License-CC_BY--NC_4.0-3b434b)](https://creativecommons.org/licenses/by-nc/4.0/)
54
- ![PyPI - Downloads](https://img.shields.io/pypi/dd/mapFolding)
55
- ![GitHub repo size](https://img.shields.io/github/repo-size/hunterhogan/mapFolding)
56
57
 
57
58
  ---
58
59
 
@@ -100,44 +101,49 @@ Available OEIS sequences:
100
101
 
101
102
  ### 2. **Algorithm Zoo** 🦒
102
103
 
103
- - **Lunnons 1971 Algorithm**: A painstakingly debugged version of [the original typo-riddled code](https://github.com/hunterhogan/mapFolding/blob/mapFolding/reference/foldings.txt)
104
+ - **Lunnon's 1971 Algorithm**: A painstakingly debugged version of [the original typo-riddled code](https://github.com/hunterhogan/mapFolding/blob/mapFolding/reference/foldings.txt)
104
105
  - The /reference directory.
105
106
  - **Numba-JIT Accelerated**: Up to 1000× faster than pure Python ([benchmarks](https://github.com/hunterhogan/mapFolding/blob/mapFolding/notes/Speed%20highlights.md))
106
107
 
107
- ### 3. **For Researchers** 🔬
108
-
109
- - Change multiple minute settings, such as the bit width of the data types.
110
- - Transform the algorithm using AST
111
- - Create hyper-optimized modules to compute a specific map.
112
-
113
- ### 4. **Customizing your algorithm**
114
-
115
- - Renovations in progress: ~~mapFolding\someAssemblyRequired\synthesizeNumbaJob.py (and/or synthesizeNumba____.py, as applicable)~~
116
- - Synthesize a Numba-optimized module for a specific mapShape
117
- - Synthesize _from_ a module in mapFolding\syntheticModules or from any source you select
118
- - Use the existing transformation options
119
- - Or create new ways of transforming the algorithm from its source to a specific job
120
- - Renovations in progress: ~~mapFolding\someAssemblyRequired\makeJob.py~~
121
- - Initialize data for a specific mapShape
122
- - Renovations in progress: ~~mapFolding\someAssemblyRequired\synthesizeNumbaModules.py (and/or synthesizeNumba____.py, as applicable)~~
123
- - Synthesize one or more Numba-optimized modules for parallel or sequential computation
124
- - Overwrite the modules in mapFolding\syntheticModules or save the module(s) to a custom path
125
- - Synthesize _from_ the algorithm(s) in mapFolding\theDao.py or from any source you select
126
- - Use the existing transformation options
127
- - Or create new ways of transforming the algorithm from its source to a new module
128
- - Use your new module in synthesizeNumbaJob.py, above, as the source to create a mapShape-specific job module
129
- - mapFolding\theDao.py
130
- - Modify the algorithms for initializing values, parallel computation, and/or sequential computation
131
- - Use the modified algorithm(s) in synthesizeNumbaModules.py, above, to create Numba-optimized version(s)
132
- - Then use a Numba-optimized version in synthesizeNumbaJob.py, above, to create a hyper-optimized version for a specific mapShape
133
- - mapFolding\theSSOT.py
134
- - Modify broad settings or find functions to modify broad settings, such as data structures and their data types
135
- - Create new settings or groups of settings
136
- - mapFolding\beDRY.py
137
- - Functions to handle common tasks, such as parsing parameters or creating the `connectionGraph` for a mapShape (a Cartesian product decomposition)
138
- - mapFolding\someAssemblyRequired
139
- - Create new transformations to optimize the algorithm, such as for JAX, CuPy, or CUDA
140
- - (mapFolding\reference\jax.py has a once-functional JAX implementation, and synthesizeModuleJAX.py might be a useful starting point)
108
+ ### 3. **For Researchers and Power Users** 🔬
109
+
110
+ This package provides a sophisticated code transformation framework that can turn readable algorithm implementations into highly-optimized computational engines:
111
+
112
+ - **Algorithmic Exploration**: Study the core algorithm in `theDao.py`, which uses a functional state-transformation approach with clear, isolated functions
113
+ - **Performance Optimization**: Generate specialized implementations with the `someAssemblyRequired` transformation pipeline:
114
+ - AST-based code analysis and manipulation
115
+ - Dataclass "shattering" to decompose complex state objects into primitive components
116
+ - Just-in-time compilation with Numba and various optimization profiles
117
+ - LLVM IR extraction for low-level algorithmic analysis
118
+
119
+ - **Extensible Design**: The transformation framework is abstract and generic, enabling:
120
+ - Creation of new optimization targets beyond the included Numba implementation
121
+ - Customization of compilation parameters and optimization levels
122
+ - Development of specialized algorithms for specific map dimensions
123
+
124
+ ### 4. **Customization and Extension Guide**
125
+
126
+ The package architecture supports multiple levels of customization:
127
+
128
+ - **Basic Usage**: Work with the high-level API in `basecamp.py` for standard computations
129
+ - **Algorithm Modification**:
130
+ - Modify the core algorithm in `theDao.py` while preserving its functional approach
131
+ - Configure system-wide settings in `theSSOT.py` to adjust data types and performance characteristics
132
+ - Use utility functions in `beDRY.py` for common operations
133
+
134
+ - **Advanced Transformation**:
135
+ - The `someAssemblyRequired` package provides tools to transform code at the AST level:
136
+ - `transformationTools.py` contains utilities for AST manipulation and code generation
137
+ - `transformDataStructures.py` handles complex data structure transformations
138
+ - `ingredientsNumba.py` provides Numba-specific configuration profiles
139
+ - `synthesizeNumbaFlow.py` orchestrates the transformation process
140
+
141
+ - **Custom Deployment**:
142
+ - Generate specialized implementations for specific dimensions
143
+ - Create optimized modules that can be executed as standalone scripts
144
+ - Extract LLVM IR for further analysis or optimization
145
+
146
+ The package's multi-level design allows you to start with simple API calls and progressively delve deeper into optimization as your computational needs grow.
141
147
 
142
148
  ## Map-folding Video
143
149
 
@@ -154,4 +160,4 @@ Available OEIS sequences:
154
160
  [![Static Badge](https://img.shields.io/badge/2011_August-Homeless_since-blue?style=flat)](https://HunterThinks.com/support)
155
161
  [![YouTube Channel Subscribers](https://img.shields.io/youtube/channel/subscribers/UC3Gx7kz61009NbhpRtPP7tw)](https://www.youtube.com/@HunterHogan)
156
162
 
157
- [![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/)
163
+ [![CC-BY-NC-4.0](https://github.com/hunterhogan/mapFolding/blob/main/CC-BY-NC-4.0.svg)](https://creativecommons.org/licenses/by-nc/4.0/)
@@ -0,0 +1,39 @@
1
+ mapFolding/__init__.py,sha256=hYxPUBU6A1_XCbKEseSDamooTsb1mzN_XHqaRLPvpGk,1701
2
+ mapFolding/basecamp.py,sha256=7ghnbEcgMaGJYCy08GpOg0O28gY5P36ZibJkjs_r-Rg,4481
3
+ mapFolding/beDRY.py,sha256=WRbvissfUGAmYbj1o0ZpGvq_9hwllDqpNwuC2_yxFyM,9785
4
+ mapFolding/filesystem.py,sha256=-pYpWugd0p3TrAz7xf9YIJW-pn1X-iRCGtJgEAF9Rns,5923
5
+ mapFolding/noHomeYet.py,sha256=UKZeWlyn0SKlF9dhYoud7E6gWXpiSEekZOOoJp88WeI,1362
6
+ mapFolding/oeis.py,sha256=xArJ8X3HqzopKIKYdKwxk7Y62vtXZFxvZ0jEqv-8GO0,12625
7
+ mapFolding/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ mapFolding/theDao.py,sha256=Blzm5j24x1BE2nvgXjdzHEeuc2na6kAH9b_eP6PcwlI,9836
9
+ mapFolding/theSSOT.py,sha256=pyetKz_Yuofm_z2XhNaQT_CWTatuAykZO2bxEPy9wS4,13670
10
+ mapFolding/reference/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ mapFolding/reference/flattened.py,sha256=KEIR8hhOW0NHDX52LHJrrTUY5QaCzexZF0S6P2wvogY,15209
12
+ mapFolding/reference/hunterNumba.py,sha256=9MEy2szRSENZc9l1_VnRqBnnd71z4KjoPwOWnOwb9Pw,6105
13
+ mapFolding/reference/irvineJavaPort.py,sha256=UkOSX0_dkKR84hp8aqHPuf7KLz_nVnji9M0IF_hRVm8,3418
14
+ mapFolding/reference/jax.py,sha256=7ji9YWia6Kof0cjcNdiS1GG1rMbC5SBjcyVr_07AeUk,13845
15
+ mapFolding/reference/lunnanNumpy.py,sha256=isI0dOYZM1CZi1P4NEojl9L2Kh45mOYtc2C8yXUit8E,3731
16
+ mapFolding/reference/lunnanWhile.py,sha256=z1hcE6SeK0CFJSS4LggmzzsLNjU3dU26LsL5y_ZGBxM,3231
17
+ mapFolding/reference/rotatedEntryPoint.py,sha256=S3y5hSUTYOR_lKBnd5SwufvjNvg3UP-Je4wpYRB-_78,9328
18
+ mapFolding/reference/total_countPlus1vsPlusN.py,sha256=wpgay-uqPOBd64Z4Pg6tg40j7-4pzWHGMM6v0bnmjhE,6288
19
+ mapFolding/someAssemblyRequired/__init__.py,sha256=xA5a-nZjXIwcqEOig5PEZSxde4_m3JJ5Pb0CN4aiRjw,2488
20
+ mapFolding/someAssemblyRequired/getLLVMforNoReason.py,sha256=bGI8RZY-RnyR9TNF0r0OXwA6fm4TYH2cHy7WzhsnddQ,1895
21
+ mapFolding/someAssemblyRequired/ingredientsNumba.py,sha256=g6Z7t35NpoDskzm0OLwTQhHw5CYiYktVYxI2NhCQHww,8435
22
+ mapFolding/someAssemblyRequired/synthesizeNumbaFlow.py,sha256=EtzULVeivQ_4G2E2UKqXoZLx6XwRcbBDzhtzwCTOEfs,10627
23
+ mapFolding/someAssemblyRequired/synthesizeNumbaJobVESTIGIAL.py,sha256=RBSrtr7US2P7mkY-EA-b2WIOxjs2b0WJaCln1ERxOcI,22314
24
+ mapFolding/someAssemblyRequired/transformDataStructures.py,sha256=0qtILOuH8I4CWFog64SPAyOWTylCa2Yh7L_hILrQY9Q,8279
25
+ mapFolding/someAssemblyRequired/transformationTools.py,sha256=vLRKAtaXa9RmoISUbFvQIWHDHor6CYctm7NEgU11T_E,40743
26
+ mapFolding/syntheticModules/numbaCount_doTheNeedful.py,sha256=52RuwJVH2fROvWU2dT8wYcQvLgRuvkNZPq01kujCC_U,15725
27
+ mapfolding-0.8.1.dist-info/licenses/LICENSE,sha256=NxH5Y8BdC-gNU-WSMwim3uMbID2iNDXJz7fHtuTdXhk,19346
28
+ tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
+ tests/conftest.py,sha256=rRlXOhihwheHyQ8ggjRBbmgPVERxWjupajguVBzBkVE,10783
30
+ tests/test_computations.py,sha256=YhadlskBh_r5RiefHRy0FlrYQ0FelYbqcSNNSkSJMIY,3368
31
+ tests/test_filesystem.py,sha256=Kou0gj5T72oISao6umYfU6L_W5Hi7QS9_IxTv2hU0Pw,3147
32
+ tests/test_oeis.py,sha256=uxvwmgbnylSDdsVJfuAT0LuYLbIVFwSgdLxHm-xUGBM,5043
33
+ tests/test_other.py,sha256=1uuApByNWPiTf0zaro2dETkvyWQFfMweU_ge4aJuVgM,4244
34
+ tests/test_tasks.py,sha256=hkZygihT8bCEO2zc-2VcxReQrZJBwgLNbYx0YP4lTDg,2853
35
+ mapfolding-0.8.1.dist-info/METADATA,sha256=Upa7kSAeKLeSk33CiII-W08xLugqgnqwIBVQu4VLEQg,7892
36
+ mapfolding-0.8.1.dist-info/WHEEL,sha256=tTnHoFhvKQHCh4jz3yCn0WPTYIy7wXx3CJtJ7SJGV7c,91
37
+ mapfolding-0.8.1.dist-info/entry_points.txt,sha256=F3OUeZR1XDTpoH7k3wXuRb3KF_kXTTeYhu5AGK1SiOQ,146
38
+ mapfolding-0.8.1.dist-info/top_level.txt,sha256=1gP2vFaqPwHujGwb3UjtMlLEGN-943VSYFR7V4gDqW8,17
39
+ mapfolding-0.8.1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (76.1.0)
2
+ Generator: setuptools (77.0.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,153 +0,0 @@
1
- """
2
- An unnecessarily literal translation of the original Atlas Autocode code by W. F. Lunnon to Python.
3
- W. F. Lunnon, Multi-dimensional map-folding, The Computer Journal, Volume 14, Issue 1, 1971, Pages 75-80, https://doi.org/10.1093/comjnl/14.1.75
4
- """# NOTE not functional yet
5
- def foldings(p, job=None):
6
- """An unnecessarily literal translation of the original Atlas Autocode code."""
7
- p = list(p)
8
- p.append(None) # NOTE mimics Atlas `array` type
9
- p.insert(0, None) # NOTE mimics Atlas `array` type
10
-
11
- if job is None:
12
- global G
13
- G = 0
14
- def job(A, B):
15
- global G
16
- G = G + 1
17
- return foldings(p, job)
18
- # perform job (A, B) on each folding of a p[1] x ... x p[d] map,
19
- # where A and B are the above and below vectors. p[d + 1] < 0 terminates p;
20
-
21
- d: int
22
- n: int
23
- j: int
24
- i: int
25
- m: int
26
- l: int
27
- g: int
28
- gg: int
29
- dd: int
30
-
31
- n = 1
32
- i, d = 0, 0
33
-
34
- while (i := i + 1) and p[i] is not None:
35
- d = i
36
- n = n * p[i]
37
-
38
- # d dimensions and n leaves;
39
-
40
- # A: list[int] = [None] * (n + 1) # type: ignore
41
- # B: list[int] = [None] * (n + 1) # type: ignore
42
- # count: list[int] = [None] * (n + 1) # type: ignore
43
- # gapter: list[int] = [None] * (n + 1) # type: ignore
44
- # gap: list[int] = [None] * (n * n + 1) # type: ignore
45
- A: list[int] = [0] * (n + 1) # type: ignore
46
- B: list[int] = [0] * (n + 1) # type: ignore
47
- count: list[int] = [0] * (n + 1) # type: ignore
48
- gapter: list[int] = [0] * (n + 1) # type: ignore
49
- gap: list[int] = [0] * (n * n + 1) # type: ignore
50
-
51
- # B[m] is the leaf below leaf m in the current folding,
52
- # A[m] the leaf above. count[m] is the no. of sections in which
53
- # there is a gap for the new leaf l below leaf m,
54
- # gap[gapter[l - 1] + j] is the j-th (possible or actual) gap for leaf l,
55
- # and later gap[gapter[l]] is the gap where leaf l is currently inserted;
56
-
57
- P: list[int] = [0] * (d + 1) # type: ignore
58
- C: list[list[int]] = [[0] * (n + 1) for dimension1 in range(d + 1)] # type: ignore
59
- # D: list[list[list[int]]] = [[[None] * (n + 1) for dimension2 in range(n + 1)] for dimension1 in range(d + 1)] # type: ignore
60
- D: list[list[list[int]]] = [[[0] * (n + 1) for dimension2 in range(n + 1)] for dimension1 in range(d + 1)]
61
-
62
- P[0] = 1
63
- for i in range(1, d + 1):
64
- P[i] = P[i - 1] * p[i]
65
-
66
- for i in range(1, d + 1):
67
- for m in range(1, n + 1):
68
- C[i][m] = ((m - 1) // P[i - 1]) - ((m - 1) // P[i]) * p[i] + 1
69
-
70
- for i in range(1, d + 1):
71
- for l in range(1, n + 1):
72
- for m in range(1, l + 1):
73
- D[i][l][m] = (0 if m == 0
74
- else
75
- ((m if C[i][m] == 1
76
- else m - P[i - 1])
77
- if C[i][l] - C[i][m] == (C[i][l] - C[i][m]) // 2 * 2
78
- else
79
- (m if C[i][m] == p[i] or m + P[i - 1] > l
80
- else m + P[i - 1])))
81
- # P[i] = p[1] x ... x p[i], C[i][m] = i-th co-ordinate of leaf m,
82
- # D[i][l][m] = leaf connected to m in section i when inserting l;
83
-
84
- for m in range(n + 1):
85
- count[m] = 0
86
-
87
- A[0], B[0], g, l = 0, 0, 0, 0
88
-
89
- state = 'entry'
90
- while True:
91
- if state == 'entry':
92
- gapter[l] = g
93
- l = l + 1
94
- if l <= n:
95
- state = 'down'
96
- continue
97
- else:
98
- job(A, B)
99
- state = 'up'
100
- continue
101
-
102
- elif state == 'down':
103
- dd = 0
104
- gg = gapter[l - 1]
105
- g = gg
106
- for i in range(1, d + 1):
107
- if D[i][l][l] == l:
108
- dd = dd + 1
109
- else:
110
- m = D[i][l][l]
111
- while m != l:
112
- gap[gg] = m
113
- if count[m] == 0:
114
- gg = gg + 1
115
- count[m] = count[m] + 1
116
- m = D[i][l][B[m]]
117
-
118
- if dd == d:
119
- for m in range(l):
120
- gap[gg] = m
121
- gg = gg + 1
122
-
123
- for j in range(g, gg):
124
- gap[g] = gap[j]
125
- if count[gap[j]] == d - dd:
126
- g = g + 1
127
- count[gap[j]] = 0
128
- state = 'along'
129
- continue
130
-
131
- elif state == 'along':
132
- if g == gapter[l - 1]:
133
- state = 'up'
134
- continue
135
- g = g - 1
136
- A[l] = gap[g]
137
- B[l] = B[A[l]]
138
- B[A[l]] = l
139
- A[B[l]] = l
140
- state = 'entry'
141
- continue
142
-
143
- elif state == 'up':
144
- l = l - 1
145
- B[A[l]] = B[l]
146
- A[B[l]] = A[l]
147
- if l > 0:
148
- state = 'along'
149
- continue
150
- else:
151
- break
152
-
153
- return G #if job.__closure__ else None