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.
- mapFolding/__init__.py +33 -4
- mapFolding/basecamp.py +14 -0
- mapFolding/beDRY.py +16 -1
- mapFolding/filesystem.py +124 -90
- mapFolding/noHomeYet.py +12 -0
- mapFolding/oeis.py +16 -1
- mapFolding/reference/__init__.py +0 -0
- mapFolding/reference/flattened.py +46 -45
- mapFolding/reference/hunterNumba.py +4 -4
- mapFolding/reference/irvineJavaPort.py +1 -1
- mapFolding/reference/lunnanNumpy.py +3 -4
- mapFolding/reference/lunnanWhile.py +5 -7
- mapFolding/reference/rotatedEntryPoint.py +2 -3
- mapFolding/someAssemblyRequired/__init__.py +29 -0
- mapFolding/someAssemblyRequired/getLLVMforNoReason.py +32 -14
- mapFolding/someAssemblyRequired/ingredientsNumba.py +22 -1
- mapFolding/someAssemblyRequired/synthesizeNumbaFlow.py +196 -0
- mapFolding/someAssemblyRequired/synthesizeNumbaJobVESTIGIAL.py +3 -4
- mapFolding/someAssemblyRequired/transformDataStructures.py +162 -0
- mapFolding/someAssemblyRequired/transformationTools.py +216 -199
- mapFolding/theDao.py +19 -5
- mapFolding/theSSOT.py +19 -1
- {mapfolding-0.8.0.dist-info → mapfolding-0.8.1.dist-info}/METADATA +50 -44
- mapfolding-0.8.1.dist-info/RECORD +39 -0
- {mapfolding-0.8.0.dist-info → mapfolding-0.8.1.dist-info}/WHEEL +1 -1
- mapFolding/reference/lunnan.py +0 -153
- mapFolding/someAssemblyRequired/Z0Z_workbench.py +0 -350
- mapFolding/someAssemblyRequired/synthesizeDataConverters.py +0 -117
- mapFolding/syntheticModules/numbaCountHistoricalExample.py +0 -158
- mapFolding/syntheticModules/numba_doTheNeedfulHistoricalExample.py +0 -13
- mapfolding-0.8.0.dist-info/RECORD +0 -41
- {mapfolding-0.8.0.dist-info → mapfolding-0.8.1.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.8.0.dist-info → mapfolding-0.8.1.dist-info/licenses}/LICENSE +0 -0
- {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.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: mapFolding
|
|
3
|
-
Version: 0.8.
|
|
4
|
-
Summary:
|
|
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
|
[](https://github.com/hunterhogan/mapFolding/actions/workflows/pythonTests.yml)
|
|
52
55
|

|
|
53
56
|
[](https://creativecommons.org/licenses/by-nc/4.0/)
|
|
54
|
-

|
|
55
|
-

|
|
56
57
|
|
|
57
58
|
---
|
|
58
59
|
|
|
@@ -100,44 +101,49 @@ Available OEIS sequences:
|
|
|
100
101
|
|
|
101
102
|
### 2. **Algorithm Zoo** 🦒
|
|
102
103
|
|
|
103
|
-
- **Lunnon
|
|
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
|
-
|
|
110
|
-
|
|
111
|
-
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
-
|
|
116
|
-
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
-
|
|
120
|
-
-
|
|
121
|
-
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
-
|
|
130
|
-
-
|
|
131
|
-
- Use
|
|
132
|
-
|
|
133
|
-
-
|
|
134
|
-
-
|
|
135
|
-
|
|
136
|
-
-
|
|
137
|
-
|
|
138
|
-
-
|
|
139
|
-
|
|
140
|
-
|
|
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
|
[](https://HunterThinks.com/support)
|
|
155
161
|
[](https://www.youtube.com/@HunterHogan)
|
|
156
162
|
|
|
157
|
-
[](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,,
|
mapFolding/reference/lunnan.py
DELETED
|
@@ -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
|