mapFolding 0.8.2__tar.gz → 0.8.3__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.
- {mapfolding-0.8.2 → mapfolding-0.8.3}/PKG-INFO +3 -2
- {mapfolding-0.8.2 → mapfolding-0.8.3}/README.md +2 -1
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/__init__.py +5 -1
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/reference/__init__.py +7 -0
- mapfolding-0.8.3/mapFolding/reference/jobsCompleted/[2x19]/p2x19.py +197 -0
- mapfolding-0.8.3/mapFolding/reference/jobsCompleted/__init__.py +50 -0
- mapfolding-0.8.3/mapFolding/reference/jobsCompleted/p2x19/p2x19.py +29 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/someAssemblyRequired/getLLVMforNoReason.py +20 -1
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/someAssemblyRequired/synthesizeNumbaFlow.py +48 -30
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/someAssemblyRequired/transformDataStructures.py +1 -1
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/someAssemblyRequired/transformationTools.py +21 -14
- mapfolding-0.8.3/mapFolding/syntheticModules/__init__.py +1 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/theSSOT.py +0 -7
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding.egg-info/PKG-INFO +3 -2
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding.egg-info/SOURCES.txt +4 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding.egg-info/top_level.txt +0 -1
- {mapfolding-0.8.2 → mapfolding-0.8.3}/pyproject.toml +3 -2
- {mapfolding-0.8.2 → mapfolding-0.8.3}/tests/test_other.py +4 -3
- {mapfolding-0.8.2 → mapfolding-0.8.3}/LICENSE +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/basecamp.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/beDRY.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/filesystem.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/noHomeYet.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/oeis.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/py.typed +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/reference/flattened.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/reference/hunterNumba.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/reference/irvineJavaPort.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/reference/jaxCount.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/reference/lunnanNumpy.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/reference/lunnanWhile.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/reference/rotatedEntryPoint.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/reference/total_countPlus1vsPlusN.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/someAssemblyRequired/__init__.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/someAssemblyRequired/ingredientsNumba.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/someAssemblyRequired/synthesizeNumbaJobVESTIGIAL.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/syntheticModules/numbaCount_doTheNeedful.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/theDao.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding.egg-info/dependency_links.txt +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding.egg-info/entry_points.txt +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding.egg-info/requires.txt +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/setup.cfg +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/tests/__init__.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/tests/conftest.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/tests/test_computations.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/tests/test_filesystem.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/tests/test_oeis.py +0 -0
- {mapfolding-0.8.2 → mapfolding-0.8.3}/tests/test_tasks.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mapFolding
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.3
|
|
4
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
|
|
@@ -92,7 +92,7 @@ Use `getOEISids` to get the most up-to-date list of available OEIS IDs.
|
|
|
92
92
|
(mapFolding) C:\apps\mapFolding> getOEISids
|
|
93
93
|
|
|
94
94
|
Available OEIS sequences:
|
|
95
|
-
A001415: Number of ways of folding a 2 X n strip of stamps.
|
|
95
|
+
A001415: Number of ways of folding a 2 X n strip of stamps. (Now extended to n=20!)
|
|
96
96
|
A001416: Number of ways of folding a 3 X n strip of stamps.
|
|
97
97
|
A001417: Number of ways of folding a 2 X 2 X ... X 2 n-dimensional map.
|
|
98
98
|
A001418: Number of ways of folding an n X n sheet of stamps.
|
|
@@ -119,6 +119,7 @@ This package offers a comprehensive collection of map folding algorithm implemen
|
|
|
119
119
|
- **Performance Optimized**:
|
|
120
120
|
- Numba-JIT accelerated implementations up to 1000× faster than pure Python (see [benchmarks](https://github.com/hunterhogan/mapFolding/blob/mapFolding/notes/Speed%20highlights.md))
|
|
121
121
|
- Algorithmic optimizations showcasing subtle yet powerful performance differences (`total_countPlus1vsPlusN.py`)
|
|
122
|
+
- **New Computations**: First-ever calculations for 2×19 and 2×20 maps in the `reference/jobsCompleted/` directory
|
|
122
123
|
|
|
123
124
|
The `reference` directory serves as both a historical archive and an educational resource for understanding algorithm evolution.
|
|
124
125
|
|
|
@@ -43,7 +43,7 @@ Use `getOEISids` to get the most up-to-date list of available OEIS IDs.
|
|
|
43
43
|
(mapFolding) C:\apps\mapFolding> getOEISids
|
|
44
44
|
|
|
45
45
|
Available OEIS sequences:
|
|
46
|
-
A001415: Number of ways of folding a 2 X n strip of stamps.
|
|
46
|
+
A001415: Number of ways of folding a 2 X n strip of stamps. (Now extended to n=20!)
|
|
47
47
|
A001416: Number of ways of folding a 3 X n strip of stamps.
|
|
48
48
|
A001417: Number of ways of folding a 2 X 2 X ... X 2 n-dimensional map.
|
|
49
49
|
A001418: Number of ways of folding an n X n sheet of stamps.
|
|
@@ -70,6 +70,7 @@ This package offers a comprehensive collection of map folding algorithm implemen
|
|
|
70
70
|
- **Performance Optimized**:
|
|
71
71
|
- Numba-JIT accelerated implementations up to 1000× faster than pure Python (see [benchmarks](https://github.com/hunterhogan/mapFolding/blob/mapFolding/notes/Speed%20highlights.md))
|
|
72
72
|
- Algorithmic optimizations showcasing subtle yet powerful performance differences (`total_countPlus1vsPlusN.py`)
|
|
73
|
+
- **New Computations**: First-ever calculations for 2×19 and 2×20 maps in the `reference/jobsCompleted/` directory
|
|
73
74
|
|
|
74
75
|
The `reference` directory serves as both a historical archive and an educational resource for understanding algorithm evolution.
|
|
75
76
|
|
|
@@ -22,17 +22,21 @@ Special directories:
|
|
|
22
22
|
- .cache/: Stores cached data from external sources like OEIS to improve performance
|
|
23
23
|
- syntheticModules/: Contains dynamically generated, optimized implementations of the
|
|
24
24
|
core algorithm created by the code transformation framework
|
|
25
|
+
- reference/: Historical implementations and educational resources for algorithm exploration
|
|
26
|
+
- reference/jobsCompleted/: Contains successful computations for previously unknown values,
|
|
27
|
+
including first-ever calculations for 2×19 and 2×20 maps (OEIS A001415)
|
|
25
28
|
|
|
26
29
|
This package strives to balance algorithm readability and understandability with
|
|
27
30
|
high-performance computation capabilities, allowing users to compute map folding
|
|
28
31
|
totals for larger dimensions than previously feasible.
|
|
29
32
|
"""
|
|
30
33
|
from mapFolding.basecamp import countFolds as countFolds
|
|
31
|
-
from mapFolding.oeis import clearOEIScache, getOEISids, OEIS_for_n
|
|
34
|
+
from mapFolding.oeis import clearOEIScache, getOEISids, OEIS_for_n, oeisIDfor_n
|
|
32
35
|
|
|
33
36
|
__all__ = [
|
|
34
37
|
'clearOEIScache',
|
|
35
38
|
'countFolds',
|
|
36
39
|
'getOEISids',
|
|
37
40
|
'OEIS_for_n',
|
|
41
|
+
'oeisIDfor_n',
|
|
38
42
|
]
|
|
@@ -26,11 +26,18 @@ Categories of reference implementations:
|
|
|
26
26
|
- total_countPlus1vsPlusN.py - Optimized counting with different increment strategies
|
|
27
27
|
- rotatedEntryPoint.py - Alternative entry point implementation (demonstration)
|
|
28
28
|
|
|
29
|
+
5. Published computations:
|
|
30
|
+
- jobsCompleted/ - Contains the source code and results of significant new computations:
|
|
31
|
+
- [2,19] - First-ever computation of the 2x19 map (completed Jan 2025)
|
|
32
|
+
- [2,20] - First-ever computation of the 2x20 map (completed Jan 2025)
|
|
33
|
+
- These calculations extend the known values for OEIS sequence A001415
|
|
34
|
+
|
|
29
35
|
These reference implementations are valuable for:
|
|
30
36
|
- Understanding the algorithm's historical development
|
|
31
37
|
- Comparing performance characteristics across implementation strategies
|
|
32
38
|
- Studying optimization techniques and their effects
|
|
33
39
|
- Verifying the correctness of the core algorithm against known solutions
|
|
40
|
+
- Reproducing published computational results that extend mathematical knowledge
|
|
34
41
|
|
|
35
42
|
Note: These implementations are for reference only and not used in the production
|
|
36
43
|
code path of the package. The active implementation resides in theDao.py with
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import numpy
|
|
2
|
+
import numba
|
|
3
|
+
|
|
4
|
+
@numba.jit(numba.types.int64(), cache=True, parallel=False, boundscheck=False, error_model='numpy', fastmath=True, nopython=True, forceinline=True, looplift=True, no_cfunc_wrapper=False, no_cpython_wrapper=False, _nrt=True, )
|
|
5
|
+
def goGoGadgetAbsurdity():
|
|
6
|
+
|
|
7
|
+
foldsTotal = numba.types.int64(0)
|
|
8
|
+
my = numpy.array([3,1,1,2,1,2,3,2,0], dtype=numpy.int64)
|
|
9
|
+
foldsSubTotals = numpy.array([0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], dtype=numpy.int64)
|
|
10
|
+
gapsWhere = numpy.array([1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
11
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
12
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
13
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
14
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
15
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
16
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
17
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
18
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
19
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
20
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
21
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
22
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
23
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
|
|
24
|
+
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], dtype=numpy.int64)
|
|
25
|
+
track = numpy.array([[1,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
26
|
+
[2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
27
|
+
[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],
|
|
28
|
+
[0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]], dtype=numpy.int64)
|
|
29
|
+
|
|
30
|
+
the = numpy.array([ 2,38, 0], dtype=numpy.int64)
|
|
31
|
+
connectionGraph = numpy.array([[[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
32
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
33
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
34
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
35
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
36
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
37
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
38
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
39
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
40
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
41
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
42
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
43
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
44
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
45
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
46
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
47
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
48
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
49
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
50
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
51
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
52
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
53
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
54
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
55
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
56
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
57
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
58
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
59
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
60
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
61
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
62
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
63
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
64
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
65
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
66
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
67
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
68
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
69
|
+
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]],
|
|
70
|
+
|
|
71
|
+
[[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
72
|
+
[ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
73
|
+
[ 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
74
|
+
[ 0, 1, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
75
|
+
[ 0, 2, 1, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
76
|
+
[ 0, 1, 2, 3, 4, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
77
|
+
[ 0, 2, 1, 4, 3, 6, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
78
|
+
[ 0, 1, 2, 3, 4, 5, 6, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
79
|
+
[ 0, 2, 1, 4, 3, 6, 5, 8, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
80
|
+
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
81
|
+
[ 0, 2, 1, 4, 3, 6, 5, 8, 7,10, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
82
|
+
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
83
|
+
[ 0, 2, 1, 4, 3, 6, 5, 8, 7,10, 9,12,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
84
|
+
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
85
|
+
[ 0, 2, 1, 4, 3, 6, 5, 8, 7,10, 9,12,11,14,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
86
|
+
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
87
|
+
[ 0, 2, 1, 4, 3, 6, 5, 8, 7,10, 9,12,11,14,13,16,15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
88
|
+
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
89
|
+
[ 0, 2, 1, 4, 3, 6, 5, 8, 7,10, 9,12,11,14,13,16,15,18,17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
90
|
+
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
91
|
+
[ 0, 2, 1, 4, 3, 6, 5, 8, 7,10, 9,12,11,14,13,16,15,18,17,20,19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
92
|
+
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
93
|
+
[ 0, 2, 1, 4, 3, 6, 5, 8, 7,10, 9,12,11,14,13,16,15,18,17,20,19,22,21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
94
|
+
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
95
|
+
[ 0, 2, 1, 4, 3, 6, 5, 8, 7,10, 9,12,11,14,13,16,15,18,17,20,19,22,21,24,23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
96
|
+
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
97
|
+
[ 0, 2, 1, 4, 3, 6, 5, 8, 7,10, 9,12,11,14,13,16,15,18,17,20,19,22,21,24,23,26,25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
98
|
+
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
99
|
+
[ 0, 2, 1, 4, 3, 6, 5, 8, 7,10, 9,12,11,14,13,16,15,18,17,20,19,22,21,24,23,26,25,28,27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
100
|
+
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
101
|
+
[ 0, 2, 1, 4, 3, 6, 5, 8, 7,10, 9,12,11,14,13,16,15,18,17,20,19,22,21,24,23,26,25,28,27,30,29, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
102
|
+
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31, 0, 0, 0, 0, 0, 0, 0],
|
|
103
|
+
[ 0, 2, 1, 4, 3, 6, 5, 8, 7,10, 9,12,11,14,13,16,15,18,17,20,19,22,21,24,23,26,25,28,27,30,29,32,31, 0, 0, 0, 0, 0, 0],
|
|
104
|
+
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33, 0, 0, 0, 0, 0],
|
|
105
|
+
[ 0, 2, 1, 4, 3, 6, 5, 8, 7,10, 9,12,11,14,13,16,15,18,17,20,19,22,21,24,23,26,25,28,27,30,29,32,31,34,33, 0, 0, 0, 0],
|
|
106
|
+
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35, 0, 0, 0],
|
|
107
|
+
[ 0, 2, 1, 4, 3, 6, 5, 8, 7,10, 9,12,11,14,13,16,15,18,17,20,19,22,21,24,23,26,25,28,27,30,29,32,31,34,33,36,35, 0, 0],
|
|
108
|
+
[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37, 0],
|
|
109
|
+
[ 0, 2, 1, 4, 3, 6, 5, 8, 7,10, 9,12,11,14,13,16,15,18,17,20,19,22,21,24,23,26,25,28,27,30,29,32,31,34,33,36,35,38,37]],
|
|
110
|
+
|
|
111
|
+
[[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
112
|
+
[ 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
113
|
+
[ 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
114
|
+
[ 0, 3, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
115
|
+
[ 0, 3, 4, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
116
|
+
[ 0, 1, 2, 5, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
117
|
+
[ 0, 1, 2, 5, 6, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
118
|
+
[ 0, 3, 4, 1, 2, 7, 6, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
119
|
+
[ 0, 3, 4, 1, 2, 7, 8, 5, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
120
|
+
[ 0, 1, 2, 5, 6, 3, 4, 9, 8, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
121
|
+
[ 0, 1, 2, 5, 6, 3, 4, 9,10, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
122
|
+
[ 0, 3, 4, 1, 2, 7, 8, 5, 6,11,10, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
123
|
+
[ 0, 3, 4, 1, 2, 7, 8, 5, 6,11,12, 9,10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
124
|
+
[ 0, 1, 2, 5, 6, 3, 4, 9,10, 7, 8,13,12,11, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
125
|
+
[ 0, 1, 2, 5, 6, 3, 4, 9,10, 7, 8,13,14,11,12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
126
|
+
[ 0, 3, 4, 1, 2, 7, 8, 5, 6,11,12, 9,10,15,14,13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
127
|
+
[ 0, 3, 4, 1, 2, 7, 8, 5, 6,11,12, 9,10,15,16,13,14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
128
|
+
[ 0, 1, 2, 5, 6, 3, 4, 9,10, 7, 8,13,14,11,12,17,16,15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
129
|
+
[ 0, 1, 2, 5, 6, 3, 4, 9,10, 7, 8,13,14,11,12,17,18,15,16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
130
|
+
[ 0, 3, 4, 1, 2, 7, 8, 5, 6,11,12, 9,10,15,16,13,14,19,18,17, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
131
|
+
[ 0, 3, 4, 1, 2, 7, 8, 5, 6,11,12, 9,10,15,16,13,14,19,20,17,18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
132
|
+
[ 0, 1, 2, 5, 6, 3, 4, 9,10, 7, 8,13,14,11,12,17,18,15,16,21,20,19, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
133
|
+
[ 0, 1, 2, 5, 6, 3, 4, 9,10, 7, 8,13,14,11,12,17,18,15,16,21,22,19,20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
134
|
+
[ 0, 3, 4, 1, 2, 7, 8, 5, 6,11,12, 9,10,15,16,13,14,19,20,17,18,23,22,21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
135
|
+
[ 0, 3, 4, 1, 2, 7, 8, 5, 6,11,12, 9,10,15,16,13,14,19,20,17,18,23,24,21,22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
136
|
+
[ 0, 1, 2, 5, 6, 3, 4, 9,10, 7, 8,13,14,11,12,17,18,15,16,21,22,19,20,25,24,23, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
137
|
+
[ 0, 1, 2, 5, 6, 3, 4, 9,10, 7, 8,13,14,11,12,17,18,15,16,21,22,19,20,25,26,23,24, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
138
|
+
[ 0, 3, 4, 1, 2, 7, 8, 5, 6,11,12, 9,10,15,16,13,14,19,20,17,18,23,24,21,22,27,26,25, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
139
|
+
[ 0, 3, 4, 1, 2, 7, 8, 5, 6,11,12, 9,10,15,16,13,14,19,20,17,18,23,24,21,22,27,28,25,26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
140
|
+
[ 0, 1, 2, 5, 6, 3, 4, 9,10, 7, 8,13,14,11,12,17,18,15,16,21,22,19,20,25,26,23,24,29,28,27, 0, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
141
|
+
[ 0, 1, 2, 5, 6, 3, 4, 9,10, 7, 8,13,14,11,12,17,18,15,16,21,22,19,20,25,26,23,24,29,30,27,28, 0, 0, 0, 0, 0, 0, 0, 0],
|
|
142
|
+
[ 0, 3, 4, 1, 2, 7, 8, 5, 6,11,12, 9,10,15,16,13,14,19,20,17,18,23,24,21,22,27,28,25,26,31,30,29, 0, 0, 0, 0, 0, 0, 0],
|
|
143
|
+
[ 0, 3, 4, 1, 2, 7, 8, 5, 6,11,12, 9,10,15,16,13,14,19,20,17,18,23,24,21,22,27,28,25,26,31,32,29,30, 0, 0, 0, 0, 0, 0],
|
|
144
|
+
[ 0, 1, 2, 5, 6, 3, 4, 9,10, 7, 8,13,14,11,12,17,18,15,16,21,22,19,20,25,26,23,24,29,30,27,28,33,32,31, 0, 0, 0, 0, 0],
|
|
145
|
+
[ 0, 1, 2, 5, 6, 3, 4, 9,10, 7, 8,13,14,11,12,17,18,15,16,21,22,19,20,25,26,23,24,29,30,27,28,33,34,31,32, 0, 0, 0, 0],
|
|
146
|
+
[ 0, 3, 4, 1, 2, 7, 8, 5, 6,11,12, 9,10,15,16,13,14,19,20,17,18,23,24,21,22,27,28,25,26,31,32,29,30,35,34,33, 0, 0, 0],
|
|
147
|
+
[ 0, 3, 4, 1, 2, 7, 8, 5, 6,11,12, 9,10,15,16,13,14,19,20,17,18,23,24,21,22,27,28,25,26,31,32,29,30,35,36,33,34, 0, 0],
|
|
148
|
+
[ 0, 1, 2, 5, 6, 3, 4, 9,10, 7, 8,13,14,11,12,17,18,15,16,21,22,19,20,25,26,23,24,29,30,27,28,33,34,31,32,37,36,35, 0],
|
|
149
|
+
[ 0, 1, 2, 5, 6, 3, 4, 9,10, 7, 8,13,14,11,12,17,18,15,16,21,22,19,20,25,26,23,24,29,30,27,28,33,34,31,32,37,38,35,36]]], dtype=numpy.int64)
|
|
150
|
+
while my[6] > 0:
|
|
151
|
+
if my[6] <= 1 or track[1, 0] == 1:
|
|
152
|
+
if my[6] > the[1]:
|
|
153
|
+
foldsSubTotals[my[8]] += the[1]
|
|
154
|
+
else:
|
|
155
|
+
my[1] = 0
|
|
156
|
+
my[3] = track[3, my[6] - 1]
|
|
157
|
+
my[0] = 1
|
|
158
|
+
while my[0] <= the[0]:
|
|
159
|
+
if connectionGraph[my[0], my[6], my[6]] == my[6]:
|
|
160
|
+
my[1] += 1
|
|
161
|
+
else:
|
|
162
|
+
my[7] = connectionGraph[my[0], my[6], my[6]]
|
|
163
|
+
while my[7] != my[6]:
|
|
164
|
+
gapsWhere[my[3]] = my[7]
|
|
165
|
+
if track[2, my[7]] == 0:
|
|
166
|
+
my[3] += 1
|
|
167
|
+
track[2, my[7]] += 1
|
|
168
|
+
my[7] = connectionGraph[my[0], my[6], track[1, my[7]]]
|
|
169
|
+
my[0] += 1
|
|
170
|
+
my[5] = my[2]
|
|
171
|
+
while my[5] < my[3]:
|
|
172
|
+
gapsWhere[my[2]] = gapsWhere[my[5]]
|
|
173
|
+
if track[2, gapsWhere[my[5]]] == the[0] - my[1]:
|
|
174
|
+
my[2] += 1
|
|
175
|
+
track[2, gapsWhere[my[5]]] = 0
|
|
176
|
+
my[5] += 1
|
|
177
|
+
while my[6] > 0 and my[2] == track[3, my[6] - 1]:
|
|
178
|
+
my[6] -= 1
|
|
179
|
+
track[1, track[0, my[6]]] = track[1, my[6]]
|
|
180
|
+
track[0, track[1, my[6]]] = track[0, my[6]]
|
|
181
|
+
if my[6] > 0:
|
|
182
|
+
my[2] -= 1
|
|
183
|
+
track[0, my[6]] = gapsWhere[my[2]]
|
|
184
|
+
track[1, my[6]] = track[1, track[0, my[6]]]
|
|
185
|
+
track[1, track[0, my[6]]] = my[6]
|
|
186
|
+
track[0, track[1, my[6]]] = my[6]
|
|
187
|
+
track[3, my[6]] = my[2]
|
|
188
|
+
my[6] += 1
|
|
189
|
+
|
|
190
|
+
foldsTotal = foldsSubTotals.sum().item()
|
|
191
|
+
print(foldsTotal)
|
|
192
|
+
with numba.objmode():
|
|
193
|
+
open('c:/apps/mapFolding/mapFolding/jobs/[2x19]/[2x19].foldsTotal', 'w').write(str(foldsTotal))
|
|
194
|
+
return foldsTotal
|
|
195
|
+
|
|
196
|
+
if __name__ == '__main__':
|
|
197
|
+
goGoGadgetAbsurdity()
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""
|
|
2
|
+
New Contribution to OEIS A001415: First-ever calculations for 2x19 and 2x20 maps
|
|
3
|
+
|
|
4
|
+
My first computation of the 2x19 map completed on 01/10/2025.
|
|
5
|
+
My first computation of the 2x20 map completed on 01/14/2025.
|
|
6
|
+
|
|
7
|
+
These represent the first-ever calculations of fold patterns for these dimensions
|
|
8
|
+
and extend the known values in the Online Encyclopedia of Integer Sequences (OEIS)
|
|
9
|
+
for series A001415 "Number of ways of folding a 2 X n strip of stamps".
|
|
10
|
+
|
|
11
|
+
Directory Structure:
|
|
12
|
+
--------------------------------------------------------------------------
|
|
13
|
+
(.venv) > dir mapFolding/reference/jobsCompleted
|
|
14
|
+
|
|
15
|
+
01/10/2025 02:27 AM 14 [2,19].foldsTotal # First 2x19 calculation
|
|
16
|
+
01/14/2025 02:04 PM 15 [2,20].foldsTotal # First 2x20 calculation
|
|
17
|
+
--------------------------------------------------------------------------
|
|
18
|
+
|
|
19
|
+
In the subfolder [2x19]:
|
|
20
|
+
--------------------------------------------------------------------------
|
|
21
|
+
(.venv) > dir mapFolding/reference/jobsCompleted/[2x19]
|
|
22
|
+
|
|
23
|
+
02/12/2025 03:48 PM 19,822 p2x19.py # Optimized algorithm implementation
|
|
24
|
+
01/21/2025 03:36 AM 50,219 stateJob.pkl # Serialized computation state
|
|
25
|
+
01/22/2025 07:15 AM 14 [2x19].foldsTotal # Result of calculation
|
|
26
|
+
01/21/2025 03:37 AM 9,678,080 [2x19].ll # LLVM IR code generated from the optimized algorithm
|
|
27
|
+
--------------------------------------------------------------------------
|
|
28
|
+
|
|
29
|
+
A version of the algorithm tuned to compute a 2x19 map took approximately 28 hours of computation.
|
|
30
|
+
The LLVM IR file ([2x19].ll) was generated using the getLLVMforNoReason module and provides
|
|
31
|
+
insight into the low-level optimizations that made this computation possible.
|
|
32
|
+
|
|
33
|
+
Alternative Implementation:
|
|
34
|
+
--------------------------------------------------------------------------
|
|
35
|
+
(.venv) > dir mapFolding/reference/jobsCompleted/p2x19
|
|
36
|
+
|
|
37
|
+
02/16/2025 07:01 PM 14 p2x19.foldsTotal # Alternative implementation result
|
|
38
|
+
02/16/2025 12:40 AM 6,423 p2x19.py # Alternative optimized algorithm
|
|
39
|
+
--------------------------------------------------------------------------
|
|
40
|
+
|
|
41
|
+
This alternative implementation took approximately 18 hours of computation and demonstrates
|
|
42
|
+
how code transformation and algorithm optimization can significantly reduce computation time.
|
|
43
|
+
|
|
44
|
+
To use these values in your own research, you can access them through the OEIS_for_n function:
|
|
45
|
+
```
|
|
46
|
+
from mapFolding import oeisIDfor_n
|
|
47
|
+
result = oeisIDfor_n('A001415', 19) # For the 2x19 calculation
|
|
48
|
+
result = oeisIDfor_n('A001415', 20) # For the 2x20 calculation
|
|
49
|
+
```
|
|
50
|
+
"""
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
from numba import uint8,jit,int64
|
|
2
|
+
from numpy import uint8
|
|
3
|
+
from numpy import array
|
|
4
|
+
@jit(int64(),_nrt=True,boundscheck=False,cache=True,error_model='numpy',fastmath=True,forceinline=True,inline='always',looplift=False,no_cfunc_wrapper=False,no_cpython_wrapper=False,nopython=True,parallel=False)
|
|
5
|
+
def countSequential()->int64:
|
|
6
|
+
groupsOfFolds=int64(0);leafAbove=array([1,2]+[0]*37,dtype=uint8);countDimensionsGapped=array([0]*39,dtype=uint8);gapRangeStart=array([0]*2+[1]+[0]*36,dtype=uint8);leafBelow=array([2,0,1]+[0]*36,dtype=uint8);gap1ndex=uint8(1);indexMiniGap=uint8(2);leafConnectee=uint8(2);indexDimension=uint8(2);gap1ndexCeiling=uint8(2);dimensionsUnconstrained=uint8(1);leaf1ndex=uint8(3);gapsWhere=array([1]+[0]*1444,dtype=uint8);connectionGraph=array([[[0]*39,[0,1]+[0]*37,[0,2,1]+[0]*36,[0,1,2,3]+[0]*35,[0,2,1,4,3]+[0]*34,[*range(0,6)]+[0]*33,[0,2,1,4,3,6,5]+[0]*32,[*range(0,8)]+[0]*31,[0,2,1,4,3,6,5,8,7]+[0]*30,[*range(0,10)]+[0]*29,[0,2,1,4,3,6,5,8,7,10,9]+[0]*28,[*range(0,12)]+[0]*27,[0,2,1,4,3,6,5,8,7,10,9,12,11]+[0]*26,[*range(0,14)]+[0]*25,[0,2,1,4,3,6,5,8,7,10,9,12,11,14,13]+[0]*24,[*range(0,16)]+[0]*23,[0,2,1,4,3,6,5,8,7,10,9,12,11,14,13,16,15]+[0]*22,[*range(0,18)]+[0]*21,[0,2,1,4,3,6,5,8,7,10,9,12,11,14,13,16,15,18,17]+[0]*20,[*range(0,20)]+[0]*19,[0,2,1,4,3,6,5,8,7,10,9,12,11,14,13,16,15,18,17,20,19]+[0]*18,[*range(0,22)]+[0]*17,[0,2,1,4,3,6,5,8,7,10,9,12,11,14,13,16,15,18,17,20,19,22,21]+[0]*16,[*range(0,24)]+[0]*15,[0,2,1,4,3,6,5,8,7,10,9,12,11,14,13,16,15,18,17,20,19,22,21,24,23]+[0]*14,[*range(0,26)]+[0]*13,[0,2,1,4,3,6,5,8,7,10,9,12,11,14,13,16,15,18,17,20,19,22,21,24,23,26,25]+[0]*12,[*range(0,28)]+[0]*11,[0,2,1,4,3,6,5,8,7,10,9,12,11,14,13,16,15,18,17,20,19,22,21,24,23,26,25,28,27]+[0]*10,[*range(0,30)]+[0]*9,[0,2,1,4,3,6,5,8,7,10,9,12,11,14,13,16,15,18,17,20,19,22,21,24,23,26,25,28,27,30,29]+[0]*8,[*range(0,32)]+[0]*7,[0,2,1,4,3,6,5,8,7,10,9,12,11,14,13,16,15,18,17,20,19,22,21,24,23,26,25,28,27,30,29,32,31]+[0]*6,[*range(0,34)]+[0]*5,[0,2,1,4,3,6,5,8,7,10,9,12,11,14,13,16,15,18,17,20,19,22,21,24,23,26,25,28,27,30,29,32,31,34,33]+[0]*4,[*range(0,36)]+[0]*3,[0,2,1,4,3,6,5,8,7,10,9,12,11,14,13,16,15,18,17,20,19,22,21,24,23,26,25,28,27,30,29,32,31,34,33,36,35]+[0]*2,[*range(0,38),0],[0,2,1,4,3,6,5,8,7,10,9,12,11,14,13,16,15,18,17,20,19,22,21,24,23,26,25,28,27,30,29,32,31,34,33,36,35,38,37]],[[0]*39,[0,1]+[0]*37,[0,1,2]+[0]*36,[0,3,2,1]+[0]*35,[0,3,4,1,2]+[0]*34,[0,1,2,5,4,3]+[0]*33,[0,1,2,5,6,3,4]+[0]*32,[0,3,4,1,2,7,6,5]+[0]*31,[0,3,4,1,2,7,8,5,6]+[0]*30,[0,1,2,5,6,3,4,9,8,7]+[0]*29,[0,1,2,5,6,3,4,9,10,7,8]+[0]*28,[0,3,4,1,2,7,8,5,6,11,10,9]+[0]*27,[0,3,4,1,2,7,8,5,6,11,12,9,10]+[0]*26,[0,1,2,5,6,3,4,9,10,7,8,13,12,11]+[0]*25,[0,1,2,5,6,3,4,9,10,7,8,13,14,11,12]+[0]*24,[0,3,4,1,2,7,8,5,6,11,12,9,10,15,14,13]+[0]*23,[0,3,4,1,2,7,8,5,6,11,12,9,10,15,16,13,14]+[0]*22,[0,1,2,5,6,3,4,9,10,7,8,13,14,11,12,17,16,15]+[0]*21,[0,1,2,5,6,3,4,9,10,7,8,13,14,11,12,17,18,15,16]+[0]*20,[0,3,4,1,2,7,8,5,6,11,12,9,10,15,16,13,14,19,18,17]+[0]*19,[0,3,4,1,2,7,8,5,6,11,12,9,10,15,16,13,14,19,20,17,18]+[0]*18,[0,1,2,5,6,3,4,9,10,7,8,13,14,11,12,17,18,15,16,21,20,19]+[0]*17,[0,1,2,5,6,3,4,9,10,7,8,13,14,11,12,17,18,15,16,21,22,19,20]+[0]*16,[0,3,4,1,2,7,8,5,6,11,12,9,10,15,16,13,14,19,20,17,18,23,22,21]+[0]*15,[0,3,4,1,2,7,8,5,6,11,12,9,10,15,16,13,14,19,20,17,18,23,24,21,22]+[0]*14,[0,1,2,5,6,3,4,9,10,7,8,13,14,11,12,17,18,15,16,21,22,19,20,25,24,23]+[0]*13,[0,1,2,5,6,3,4,9,10,7,8,13,14,11,12,17,18,15,16,21,22,19,20,25,26,23,24]+[0]*12,[0,3,4,1,2,7,8,5,6,11,12,9,10,15,16,13,14,19,20,17,18,23,24,21,22,27,26,25]+[0]*11,[0,3,4,1,2,7,8,5,6,11,12,9,10,15,16,13,14,19,20,17,18,23,24,21,22,27,28,25,26]+[0]*10,[0,1,2,5,6,3,4,9,10,7,8,13,14,11,12,17,18,15,16,21,22,19,20,25,26,23,24,29,28,27]+[0]*9,[0,1,2,5,6,3,4,9,10,7,8,13,14,11,12,17,18,15,16,21,22,19,20,25,26,23,24,29,30,27,28]+[0]*8,[0,3,4,1,2,7,8,5,6,11,12,9,10,15,16,13,14,19,20,17,18,23,24,21,22,27,28,25,26,31,30,29]+[0]*7,[0,3,4,1,2,7,8,5,6,11,12,9,10,15,16,13,14,19,20,17,18,23,24,21,22,27,28,25,26,31,32,29,30]+[0]*6,[0,1,2,5,6,3,4,9,10,7,8,13,14,11,12,17,18,15,16,21,22,19,20,25,26,23,24,29,30,27,28,33,32,31]+[0]*5,[0,1,2,5,6,3,4,9,10,7,8,13,14,11,12,17,18,15,16,21,22,19,20,25,26,23,24,29,30,27,28,33,34,31,32]+[0]*4,[0,3,4,1,2,7,8,5,6,11,12,9,10,15,16,13,14,19,20,17,18,23,24,21,22,27,28,25,26,31,32,29,30,35,34,33]+[0]*3,[0,3,4,1,2,7,8,5,6,11,12,9,10,15,16,13,14,19,20,17,18,23,24,21,22,27,28,25,26,31,32,29,30,35,36,33,34]+[0]*2,[0,1,2,5,6,3,4,9,10,7,8,13,14,11,12,17,18,15,16,21,22,19,20,25,26,23,24,29,30,27,28,33,34,31,32,37,36,35,0],[0,1,2,5,6,3,4,9,10,7,8,13,14,11,12,17,18,15,16,21,22,19,20,25,26,23,24,29,30,27,28,33,34,31,32,37,38,35,36]]],dtype=uint8)
|
|
7
|
+
while leaf1ndex:
|
|
8
|
+
if leaf1ndex<=1 or leafBelow[0]==1:
|
|
9
|
+
if leaf1ndex>38:groupsOfFolds+=1
|
|
10
|
+
else:
|
|
11
|
+
dimensionsUnconstrained=2;gap1ndexCeiling=gapRangeStart[leaf1ndex-1];indexDimension=0
|
|
12
|
+
while indexDimension<2:
|
|
13
|
+
if connectionGraph[indexDimension,leaf1ndex,leaf1ndex]==leaf1ndex:dimensionsUnconstrained-=1
|
|
14
|
+
else:
|
|
15
|
+
leafConnectee=connectionGraph[indexDimension,leaf1ndex,leaf1ndex]
|
|
16
|
+
while leafConnectee!=leaf1ndex:
|
|
17
|
+
gapsWhere[gap1ndexCeiling]=leafConnectee
|
|
18
|
+
if countDimensionsGapped[leafConnectee]==0:gap1ndexCeiling+=1
|
|
19
|
+
countDimensionsGapped[leafConnectee]+=1;leafConnectee=connectionGraph[indexDimension,leaf1ndex,leafBelow[leafConnectee]]
|
|
20
|
+
indexDimension+=1
|
|
21
|
+
indexMiniGap=gap1ndex
|
|
22
|
+
while indexMiniGap<gap1ndexCeiling:
|
|
23
|
+
gapsWhere[gap1ndex]=gapsWhere[indexMiniGap]
|
|
24
|
+
if countDimensionsGapped[gapsWhere[indexMiniGap]]==dimensionsUnconstrained:gap1ndex+=1
|
|
25
|
+
countDimensionsGapped[gapsWhere[indexMiniGap]]=0;indexMiniGap+=1
|
|
26
|
+
while leaf1ndex and gap1ndex==gapRangeStart[leaf1ndex-1]:leaf1ndex-=1;leafBelow[leafAbove[leaf1ndex]]=leafBelow[leaf1ndex];leafAbove[leafBelow[leaf1ndex]]=leafAbove[leaf1ndex]
|
|
27
|
+
if leaf1ndex:gap1ndex-=1;leafAbove[leaf1ndex]=gapsWhere[gap1ndex];leafBelow[leaf1ndex]=leafBelow[leafAbove[leaf1ndex]];leafBelow[leafAbove[leaf1ndex]]=leaf1ndex;leafAbove[leafBelow[leaf1ndex]]=leaf1ndex;gapRangeStart[leaf1ndex]=gap1ndex;leaf1ndex+=1
|
|
28
|
+
return groupsOfFolds*38
|
|
29
|
+
if __name__=='__main__':import time;timeStart=time.perf_counter();foldsTotal=countSequential();print(foldsTotal,time.perf_counter()-timeStart);writeStream=open('C:/apps/mapFolding/mapFolding/jobs/p2x19.foldsTotal','w');writeStream.write(str(foldsTotal));writeStream.close()
|
|
@@ -12,6 +12,14 @@ The extracted LLVM IR can be valuable for debugging, optimization analysis, or e
|
|
|
12
12
|
purposes, as it provides a view into how high-level Python code is translated into
|
|
13
13
|
lower-level representations for machine execution.
|
|
14
14
|
|
|
15
|
+
Example of successful use:
|
|
16
|
+
The LLVM IR for the groundbreaking 2x19 map calculation can be found at:
|
|
17
|
+
mapFolding/reference/jobsCompleted/[2x19]/[2x19].ll
|
|
18
|
+
|
|
19
|
+
This file demonstrates the low-level optimizations that made this previously
|
|
20
|
+
intractable calculation possible. The IR reveals how the abstract algorithm was
|
|
21
|
+
transformed into efficient machine code through Numba's compilation pipeline.
|
|
22
|
+
|
|
15
23
|
While originally part of a tighter integration with the code generation pipeline,
|
|
16
24
|
this module now operates as a standalone utility that can be applied to any module
|
|
17
25
|
containing Numba-compiled functions.
|
|
@@ -23,7 +31,18 @@ import importlib.util
|
|
|
23
31
|
import llvmlite.binding
|
|
24
32
|
|
|
25
33
|
def writeModuleLLVM(pathFilename: Path, identifierCallable: str) -> Path:
|
|
26
|
-
"""Import the generated module directly and get its LLVM IR.
|
|
34
|
+
"""Import the generated module directly and get its LLVM IR.
|
|
35
|
+
|
|
36
|
+
Parameters
|
|
37
|
+
pathFilename: Path to the Python module file containing the Numba-compiled function
|
|
38
|
+
identifierCallable: Name of the function within the module to extract LLVM IR from
|
|
39
|
+
|
|
40
|
+
Returns
|
|
41
|
+
Path to the generated .ll file containing the extracted LLVM IR
|
|
42
|
+
|
|
43
|
+
For an example of the output, see reference/jobsCompleted/[2x19]/[2x19].ll,
|
|
44
|
+
which contains the IR for the historically significant 2x19 map calculation.
|
|
45
|
+
"""
|
|
27
46
|
specTarget: ModuleSpec | None = importlib.util.spec_from_file_location("generatedModule", pathFilename)
|
|
28
47
|
if specTarget is None or specTarget.loader is None:
|
|
29
48
|
raise ImportError(f"Could not create module spec or loader for {pathFilename}")
|
{mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/someAssemblyRequired/synthesizeNumbaFlow.py
RENAMED
|
@@ -22,6 +22,7 @@ to generate a fresh optimized implementation.
|
|
|
22
22
|
"""
|
|
23
23
|
|
|
24
24
|
from mapFolding.someAssemblyRequired import (
|
|
25
|
+
ast_Identifier,
|
|
25
26
|
extractFunctionDef,
|
|
26
27
|
ifThis,
|
|
27
28
|
IngredientsFunction,
|
|
@@ -42,7 +43,17 @@ from mapFolding.someAssemblyRequired.transformDataStructures import shatter_data
|
|
|
42
43
|
from mapFolding.theSSOT import raiseIfNoneGitHubIssueNumber3
|
|
43
44
|
import ast
|
|
44
45
|
|
|
46
|
+
def astModuleToIngredientsFunction(astModule: ast.Module, identifierFunctionDef: ast_Identifier) -> IngredientsFunction:
|
|
47
|
+
astFunctionDef = extractFunctionDef(astModule, identifierFunctionDef)
|
|
48
|
+
if not astFunctionDef: raise raiseIfNoneGitHubIssueNumber3
|
|
49
|
+
return IngredientsFunction(astFunctionDef, LedgerOfImports(astModule))
|
|
50
|
+
|
|
51
|
+
|
|
45
52
|
def makeNumbaFlow(numbaFlow: RecipeSynthesizeFlow = RecipeSynthesizeFlow()) -> None:
|
|
53
|
+
# TODO a tool to automatically remove unused variables from the ArgumentsSpecification (return, and returns) _might_ be nice.
|
|
54
|
+
# TODO remember that `sequentialCallable` and `sourceSequentialCallable` are two different values.
|
|
55
|
+
# Figure out dynamic flow control to synthesized modules https://github.com/hunterhogan/mapFolding/issues/4
|
|
56
|
+
# ===========================================================
|
|
46
57
|
"""
|
|
47
58
|
Think about a better organization of this function.
|
|
48
59
|
|
|
@@ -61,17 +72,39 @@ def makeNumbaFlow(numbaFlow: RecipeSynthesizeFlow = RecipeSynthesizeFlow()) -> N
|
|
|
61
72
|
would be automatically triggered. I have no idea how that would happen, but the transformations are highly predictable,
|
|
62
73
|
so using a programming language to construct if-this-then-that cascades shouldn't be a problem, you know?
|
|
63
74
|
|
|
64
|
-
# TODO a tool to automatically remove unused variables from the ArgumentsSpecification (return, and returns) _might_ be nice.
|
|
65
75
|
"""
|
|
76
|
+
ingredientsDispatcher: IngredientsFunction = astModuleToIngredientsFunction(numbaFlow.source_astModule, numbaFlow.sourceDispatcherCallable)
|
|
77
|
+
ingredientsInitialize: IngredientsFunction = astModuleToIngredientsFunction(numbaFlow.source_astModule, numbaFlow.sourceInitializeCallable)
|
|
78
|
+
ingredientsParallel: IngredientsFunction = astModuleToIngredientsFunction(numbaFlow.source_astModule, numbaFlow.sourceParallelCallable)
|
|
79
|
+
ingredientsSequential: IngredientsFunction = astModuleToIngredientsFunction(numbaFlow.source_astModule, numbaFlow.sourceSequentialCallable)
|
|
80
|
+
|
|
81
|
+
# Inline functions
|
|
82
|
+
# NOTE Replacements statements are based on the identifiers in the _source_
|
|
66
83
|
dictionaryReplacementStatements = makeDictionaryReplacementStatements(numbaFlow.source_astModule)
|
|
67
|
-
|
|
68
|
-
|
|
84
|
+
ingredientsInitialize.astFunctionDef = inlineThisFunctionWithTheseValues(ingredientsInitialize.astFunctionDef, dictionaryReplacementStatements)
|
|
85
|
+
ingredientsParallel.astFunctionDef = inlineThisFunctionWithTheseValues(ingredientsParallel.astFunctionDef, dictionaryReplacementStatements)
|
|
86
|
+
ingredientsSequential.astFunctionDef = inlineThisFunctionWithTheseValues(ingredientsSequential.astFunctionDef, dictionaryReplacementStatements)
|
|
87
|
+
|
|
88
|
+
# Assign CALLABLE identifiers per the recipe.
|
|
89
|
+
# TODO Assign the other identifiers.
|
|
90
|
+
listIngredientsFunctions = [ingredientsDispatcher, ingredientsInitialize, ingredientsParallel, ingredientsSequential]
|
|
91
|
+
listFindReplace = [(numbaFlow.sourceDispatcherCallable, numbaFlow.dispatcherCallable),
|
|
92
|
+
(numbaFlow.sourceInitializeCallable, numbaFlow.initializeCallable),
|
|
93
|
+
(numbaFlow.sourceParallelCallable, numbaFlow.parallelCallable),
|
|
94
|
+
(numbaFlow.sourceSequentialCallable, numbaFlow.sequentialCallable)]
|
|
95
|
+
for ingredients in listIngredientsFunctions:
|
|
96
|
+
ImaNode = ingredients.astFunctionDef
|
|
97
|
+
for source_Identifier, Z0Z_Identifier in listFindReplace:
|
|
98
|
+
findThis = ifThis.isCall_Identifier(source_Identifier)
|
|
99
|
+
doThis = Then.replaceDOTfuncWith(Make.astName(Z0Z_Identifier))
|
|
100
|
+
NodeReplacer(findThis, doThis).visit(ImaNode)
|
|
69
101
|
|
|
102
|
+
ingredientsDispatcher.astFunctionDef.name = numbaFlow.dispatcherCallable
|
|
103
|
+
ingredientsInitialize.astFunctionDef.name = numbaFlow.initializeCallable
|
|
104
|
+
ingredientsParallel.astFunctionDef.name = numbaFlow.parallelCallable
|
|
105
|
+
ingredientsSequential.astFunctionDef.name = numbaFlow.sequentialCallable
|
|
70
106
|
# ===========================================================
|
|
71
|
-
|
|
72
|
-
astFunctionDef = extractFunctionDef(sourcePython, numbaFlow.source_astModule)
|
|
73
|
-
if not astFunctionDef: raise raiseIfNoneGitHubIssueNumber3
|
|
74
|
-
ingredientsDispatcher = IngredientsFunction(astFunctionDef, LedgerOfImports(numbaFlow.source_astModule))
|
|
107
|
+
# Old organization
|
|
75
108
|
|
|
76
109
|
# sourceParallelCallable
|
|
77
110
|
shatteredDataclass = shatter_dataclassesDOTdataclass(numbaFlow.logicalPathModuleDataclass, numbaFlow.sourceDataclassIdentifier, numbaFlow.sourceDataclassInstanceTaskDistribution)
|
|
@@ -116,34 +149,20 @@ def makeNumbaFlow(numbaFlow: RecipeSynthesizeFlow = RecipeSynthesizeFlow()) -> N
|
|
|
116
149
|
ingredientsDispatcher.imports.update(shatteredDataclass.ledgerDataclassANDFragments)
|
|
117
150
|
|
|
118
151
|
NodeReplacer(
|
|
119
|
-
findThis = ifThis.isAssignAndValueIsCall_Identifier(numbaFlow.sourceSequentialCallable)
|
|
152
|
+
findThis = ifThis.isAssignAndValueIsCall_Identifier(numbaFlow.sourceSequentialCallable) # NOTE source
|
|
120
153
|
, doThat = Then.insertThisAbove(shatteredDataclass.listAnnAssign4DataclassUnpack)
|
|
121
154
|
).visit(ingredientsDispatcher.astFunctionDef)
|
|
122
155
|
NodeReplacer(
|
|
123
|
-
findThis = ifThis.isAssignAndValueIsCall_Identifier(numbaFlow.sourceSequentialCallable)
|
|
156
|
+
findThis = ifThis.isAssignAndValueIsCall_Identifier(numbaFlow.sourceSequentialCallable) # NOTE source
|
|
124
157
|
, doThat = Then.insertThisBelow([shatteredDataclass.astAssignDataclassRepack])
|
|
125
158
|
).visit(ingredientsDispatcher.astFunctionDef)
|
|
126
159
|
NodeReplacer(
|
|
127
|
-
findThis = ifThis.isAssignAndValueIsCall_Identifier(numbaFlow.sourceSequentialCallable)
|
|
160
|
+
findThis = ifThis.isAssignAndValueIsCall_Identifier(numbaFlow.sourceSequentialCallable) # NOTE source
|
|
128
161
|
, doThat = Then.replaceWith(Make.astAssign(listTargets=[shatteredDataclass.astTuple4AssignTargetsToFragments], value=Make.astCall(Make.astName(numbaFlow.sequentialCallable), shatteredDataclass.listNameDataclassFragments4Parameters)))
|
|
129
162
|
).visit(ingredientsDispatcher.astFunctionDef)
|
|
130
163
|
|
|
131
|
-
ingredientsDispatcher.astFunctionDef.name = numbaFlow.dispatcherCallable
|
|
132
|
-
|
|
133
|
-
# ===========================================================
|
|
134
|
-
sourcePython = numbaFlow.sourceInitializeCallable
|
|
135
|
-
astFunctionDef = extractFunctionDef(sourcePython, numbaFlow.source_astModule)
|
|
136
|
-
if not astFunctionDef: raise raiseIfNoneGitHubIssueNumber3
|
|
137
|
-
astFunctionDef = inlineThisFunctionWithTheseValues(astFunctionDef, dictionaryReplacementStatements)
|
|
138
|
-
ingredientsInitialize = IngredientsFunction(astFunctionDef, LedgerOfImports(numbaFlow.source_astModule))
|
|
139
164
|
|
|
140
165
|
# ===========================================================
|
|
141
|
-
sourcePython = numbaFlow.sourceParallelCallable
|
|
142
|
-
astFunctionDef = extractFunctionDef(sourcePython, numbaFlow.source_astModule)
|
|
143
|
-
if not astFunctionDef: raise raiseIfNoneGitHubIssueNumber3
|
|
144
|
-
astFunctionDef = inlineThisFunctionWithTheseValues(astFunctionDef, dictionaryReplacementStatements)
|
|
145
|
-
ingredientsParallel = IngredientsFunction(astFunctionDef, LedgerOfImports(numbaFlow.source_astModule))
|
|
146
|
-
ingredientsParallel.astFunctionDef.name = numbaFlow.parallelCallable
|
|
147
166
|
ingredientsParallel.astFunctionDef.args = Make.astArgumentsSpecification(args=shatteredDataclass.list_ast_argAnnotated4ArgumentsSpecification)
|
|
148
167
|
NodeReplacer(
|
|
149
168
|
findThis = ifThis.isReturn
|
|
@@ -160,12 +179,6 @@ def makeNumbaFlow(numbaFlow: RecipeSynthesizeFlow = RecipeSynthesizeFlow()) -> N
|
|
|
160
179
|
ingredientsParallel = decorateCallableWithNumba(ingredientsParallel)
|
|
161
180
|
|
|
162
181
|
# ===========================================================
|
|
163
|
-
sourcePython = numbaFlow.sourceSequentialCallable
|
|
164
|
-
astFunctionDef = extractFunctionDef(sourcePython, numbaFlow.source_astModule)
|
|
165
|
-
if not astFunctionDef: raise raiseIfNoneGitHubIssueNumber3
|
|
166
|
-
astFunctionDef = inlineThisFunctionWithTheseValues(astFunctionDef, dictionaryReplacementStatements)
|
|
167
|
-
ingredientsSequential = IngredientsFunction(astFunctionDef, LedgerOfImports(numbaFlow.source_astModule))
|
|
168
|
-
ingredientsSequential.astFunctionDef.name = numbaFlow.sequentialCallable
|
|
169
182
|
ingredientsSequential.astFunctionDef.args = Make.astArgumentsSpecification(args=shatteredDataclass.list_ast_argAnnotated4ArgumentsSpecification)
|
|
170
183
|
NodeReplacer(
|
|
171
184
|
findThis = ifThis.isReturn
|
|
@@ -179,8 +192,13 @@ def makeNumbaFlow(numbaFlow: RecipeSynthesizeFlow = RecipeSynthesizeFlow()) -> N
|
|
|
179
192
|
replacementMap = {statement.value: statement.target for statement in shatteredDataclass.listAnnAssign4DataclassUnpack}
|
|
180
193
|
ingredientsSequential.astFunctionDef = Z0Z_replaceMatchingASTnodes(ingredientsSequential.astFunctionDef, replacementMap) # type: ignore
|
|
181
194
|
ingredientsSequential = decorateCallableWithNumba(ingredientsSequential)
|
|
195
|
+
# End old organization
|
|
196
|
+
# ===========================================================
|
|
182
197
|
|
|
183
198
|
# ===========================================================
|
|
199
|
+
# End function-level transformations
|
|
200
|
+
# ===========================================================
|
|
201
|
+
# Module-level transformations
|
|
184
202
|
ingredientsModuleNumbaUnified = IngredientsModule(
|
|
185
203
|
ingredientsFunction=[ingredientsInitialize,
|
|
186
204
|
ingredientsParallel,
|
{mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/someAssemblyRequired/transformDataStructures.py
RENAMED
|
@@ -74,7 +74,7 @@ def shatter_dataclassesDOTdataclass(logicalPathModule: strDotStrCuzPyStoopid, da
|
|
|
74
74
|
module: ast.Module = ast.parse(inspect_getsource(importlib_import_module(logicalPathModule)))
|
|
75
75
|
astName_dataclassesDOTdataclass = Make.astName(dataclass_Identifier)
|
|
76
76
|
|
|
77
|
-
dataclass = extractClassDef(
|
|
77
|
+
dataclass = extractClassDef(module, dataclass_Identifier)
|
|
78
78
|
if not isinstance(dataclass, ast.ClassDef):
|
|
79
79
|
raise ValueError(f"I could not find {dataclass_Identifier=} in {logicalPathModule=}.")
|
|
80
80
|
|
{mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/someAssemblyRequired/transformationTools.py
RENAMED
|
@@ -189,7 +189,8 @@ class ifThis:
|
|
|
189
189
|
return isinstance(node, ast.Call)
|
|
190
190
|
@staticmethod
|
|
191
191
|
def isCall_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Call] | bool]:
|
|
192
|
-
|
|
192
|
+
def workhorse(node: ast.AST) -> TypeGuard[ast.Call] | bool: return ifThis.isCall(node) and ifThis.isName_Identifier(identifier)(node.func)
|
|
193
|
+
return workhorse
|
|
193
194
|
@staticmethod
|
|
194
195
|
def isCallNamespace_Identifier(namespace: ast_Identifier, identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Call] | bool]:
|
|
195
196
|
return lambda node: ifThis.isCall(node) and ifThis.is_nameDOTnameNamespace_Identifier(namespace, identifier)(node.func)
|
|
@@ -215,8 +216,7 @@ class ifThis:
|
|
|
215
216
|
def isExpr(node: ast.AST) -> TypeGuard[ast.Expr]:
|
|
216
217
|
return isinstance(node, ast.Expr)
|
|
217
218
|
@staticmethod
|
|
218
|
-
def isFunctionDef(node: ast.AST) -> TypeGuard[ast.FunctionDef]:
|
|
219
|
-
return isinstance(node, ast.FunctionDef)
|
|
219
|
+
def isFunctionDef(node: ast.AST) -> TypeGuard[ast.FunctionDef]: return isinstance(node, ast.FunctionDef)
|
|
220
220
|
@staticmethod
|
|
221
221
|
def isFunctionDef_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.FunctionDef] | bool]:
|
|
222
222
|
return lambda node: ifThis.isFunctionDef(node) and node.name == identifier
|
|
@@ -266,9 +266,9 @@ class ifThis:
|
|
|
266
266
|
Parameters:
|
|
267
267
|
identifier: The identifier to look for in the value chain
|
|
268
268
|
Returns:
|
|
269
|
-
|
|
269
|
+
workhorse: function that checks if a node matches the criteria
|
|
270
270
|
"""
|
|
271
|
-
def
|
|
271
|
+
def workhorse(node: ast.AST) -> TypeGuard[ast.Subscript]:
|
|
272
272
|
if not ifThis.isSubscript(node):
|
|
273
273
|
return False
|
|
274
274
|
def checkNodeDOTvalue(nodeDOTvalue: ast.AST) -> bool:
|
|
@@ -279,7 +279,7 @@ class ifThis:
|
|
|
279
279
|
return checkNodeDOTvalue(nodeDOTvalue.value) # type: ignore
|
|
280
280
|
return False
|
|
281
281
|
return checkNodeDOTvalue(node.value)
|
|
282
|
-
return
|
|
282
|
+
return workhorse
|
|
283
283
|
@staticmethod
|
|
284
284
|
def isSubscriptIsName_Identifier(identifier: ast_Identifier) -> Callable[[ast.AST], TypeGuard[ast.Subscript] | bool]:
|
|
285
285
|
return lambda node: ifThis.isSubscript(node) and ifThis.isName_Identifier(identifier)(node.value)
|
|
@@ -309,12 +309,12 @@ class ifThis:
|
|
|
309
309
|
@staticmethod
|
|
310
310
|
def matchesNoDescendant(predicate: Callable[[ast.AST], bool]) -> Callable[[ast.AST], bool]:
|
|
311
311
|
"""Create a predicate that returns True if no descendant of the node matches the given predicate."""
|
|
312
|
-
def
|
|
312
|
+
def workhorse(node: ast.AST) -> bool:
|
|
313
313
|
for descendant in ast.walk(node):
|
|
314
314
|
if descendant is not node and predicate(descendant):
|
|
315
315
|
return False
|
|
316
316
|
return True
|
|
317
|
-
return
|
|
317
|
+
return workhorse
|
|
318
318
|
@staticmethod
|
|
319
319
|
def onlyReturnAnyCompare(astFunctionDef: ast.AST) -> TypeGuard[ast.FunctionDef]:
|
|
320
320
|
return ifThis.isFunctionDef(astFunctionDef) and len(astFunctionDef.body) == 1 and ifThis.isReturnAnyCompare(astFunctionDef.body[0])
|
|
@@ -476,11 +476,15 @@ class Then:
|
|
|
476
476
|
def insertThisBelow(list_astAST: Sequence[ast.AST]) -> Callable[[ast.AST], Sequence[ast.AST]]:
|
|
477
477
|
return lambda belowMe: [belowMe, *list_astAST]
|
|
478
478
|
@staticmethod
|
|
479
|
-
def removeThis(_node: ast.AST) -> None:
|
|
480
|
-
return None
|
|
479
|
+
def removeThis(_node: ast.AST) -> None: return None
|
|
481
480
|
@staticmethod
|
|
482
|
-
def replaceWith(astAST: ast.AST) -> Callable[[ast.AST], ast.AST]:
|
|
483
|
-
|
|
481
|
+
def replaceWith(astAST: ast.AST) -> Callable[[ast.AST], ast.AST]: return lambda _replaceMe: astAST
|
|
482
|
+
@staticmethod
|
|
483
|
+
def replaceDOTfuncWith(ast_expr: ast.expr) -> Callable[[ast.Call], ast.Call]:
|
|
484
|
+
def workhorse(node: ast.Call) -> ast.Call:
|
|
485
|
+
node.func = ast_expr
|
|
486
|
+
return node
|
|
487
|
+
return workhorse
|
|
484
488
|
@staticmethod
|
|
485
489
|
def updateThis(dictionaryOf_astMosDef: dict[ast_Identifier, astMosDef]) -> Callable[[astMosDef], astMosDef]:
|
|
486
490
|
return lambda node: dictionaryOf_astMosDef.setdefault(node.name, node)
|
|
@@ -597,6 +601,9 @@ class RecipeSynthesizeFlow:
|
|
|
597
601
|
initializeCallable: str = sourceInitializeCallable
|
|
598
602
|
parallelCallable: str = sourceParallelCallable
|
|
599
603
|
sequentialCallable: str = sourceSequentialCallable
|
|
604
|
+
# initializeCallable: str = 'StartTheCommotion'
|
|
605
|
+
# parallelCallable: str = sourceParallelCallable
|
|
606
|
+
# sequentialCallable: str = sourceSequentialCallable
|
|
600
607
|
|
|
601
608
|
dataclassIdentifier: str = sourceDataclassIdentifier
|
|
602
609
|
|
|
@@ -623,14 +630,14 @@ class RecipeSynthesizeFlow:
|
|
|
623
630
|
def pathFilenameDispatcher(self) -> PurePosixPath:
|
|
624
631
|
return self._makePathFilename(filenameStem=self.moduleDispatcher, logicalPathINFIX=self.Z0Z_flowLogicalPathRoot)
|
|
625
632
|
|
|
626
|
-
def extractClassDef(
|
|
633
|
+
def extractClassDef(module: ast.Module, identifier: ast_Identifier) -> ast.ClassDef | None:
|
|
627
634
|
sherpa: list[ast.ClassDef] = []
|
|
628
635
|
extractor = NodeCollector(ifThis.isClassDef_Identifier(identifier), [Then.appendTo(sherpa)])
|
|
629
636
|
extractor.visit(module)
|
|
630
637
|
astClassDef = sherpa[0] if sherpa else None
|
|
631
638
|
return astClassDef
|
|
632
639
|
|
|
633
|
-
def extractFunctionDef(
|
|
640
|
+
def extractFunctionDef(module: ast.Module, identifier: ast_Identifier) -> ast.FunctionDef | None:
|
|
634
641
|
sherpa: list[ast.FunctionDef] = []
|
|
635
642
|
extractor = NodeCollector(ifThis.isFunctionDef_Identifier(identifier), [Then.appendTo(sherpa)])
|
|
636
643
|
extractor.visit(module)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""Everything in this directory is synthesized by other modules in the package."""
|
|
@@ -179,13 +179,6 @@ def getPathJobRootDEFAULT() -> Path:
|
|
|
179
179
|
pathJobDEFAULT = The.pathPackage / "jobs"
|
|
180
180
|
return pathJobDEFAULT
|
|
181
181
|
|
|
182
|
-
_datatypePackage: str = ''
|
|
183
|
-
def getDatatypePackage() -> str:
|
|
184
|
-
global _datatypePackage
|
|
185
|
-
if not _datatypePackage:
|
|
186
|
-
_datatypePackage = The.datatypePackage
|
|
187
|
-
return _datatypePackage
|
|
188
|
-
|
|
189
182
|
# =============================================================================
|
|
190
183
|
# The coping way.
|
|
191
184
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: mapFolding
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.3
|
|
4
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
|
|
@@ -92,7 +92,7 @@ Use `getOEISids` to get the most up-to-date list of available OEIS IDs.
|
|
|
92
92
|
(mapFolding) C:\apps\mapFolding> getOEISids
|
|
93
93
|
|
|
94
94
|
Available OEIS sequences:
|
|
95
|
-
A001415: Number of ways of folding a 2 X n strip of stamps.
|
|
95
|
+
A001415: Number of ways of folding a 2 X n strip of stamps. (Now extended to n=20!)
|
|
96
96
|
A001416: Number of ways of folding a 3 X n strip of stamps.
|
|
97
97
|
A001417: Number of ways of folding a 2 X 2 X ... X 2 n-dimensional map.
|
|
98
98
|
A001418: Number of ways of folding an n X n sheet of stamps.
|
|
@@ -119,6 +119,7 @@ This package offers a comprehensive collection of map folding algorithm implemen
|
|
|
119
119
|
- **Performance Optimized**:
|
|
120
120
|
- Numba-JIT accelerated implementations up to 1000× faster than pure Python (see [benchmarks](https://github.com/hunterhogan/mapFolding/blob/mapFolding/notes/Speed%20highlights.md))
|
|
121
121
|
- Algorithmic optimizations showcasing subtle yet powerful performance differences (`total_countPlus1vsPlusN.py`)
|
|
122
|
+
- **New Computations**: First-ever calculations for 2×19 and 2×20 maps in the `reference/jobsCompleted/` directory
|
|
122
123
|
|
|
123
124
|
The `reference` directory serves as both a historical archive and an educational resource for understanding algorithm evolution.
|
|
124
125
|
|
|
@@ -25,6 +25,9 @@ mapFolding/reference/lunnanNumpy.py
|
|
|
25
25
|
mapFolding/reference/lunnanWhile.py
|
|
26
26
|
mapFolding/reference/rotatedEntryPoint.py
|
|
27
27
|
mapFolding/reference/total_countPlus1vsPlusN.py
|
|
28
|
+
mapFolding/reference/jobsCompleted/__init__.py
|
|
29
|
+
mapFolding/reference/jobsCompleted/[2x19]/p2x19.py
|
|
30
|
+
mapFolding/reference/jobsCompleted/p2x19/p2x19.py
|
|
28
31
|
mapFolding/someAssemblyRequired/__init__.py
|
|
29
32
|
mapFolding/someAssemblyRequired/getLLVMforNoReason.py
|
|
30
33
|
mapFolding/someAssemblyRequired/ingredientsNumba.py
|
|
@@ -32,6 +35,7 @@ mapFolding/someAssemblyRequired/synthesizeNumbaFlow.py
|
|
|
32
35
|
mapFolding/someAssemblyRequired/synthesizeNumbaJobVESTIGIAL.py
|
|
33
36
|
mapFolding/someAssemblyRequired/transformDataStructures.py
|
|
34
37
|
mapFolding/someAssemblyRequired/transformationTools.py
|
|
38
|
+
mapFolding/syntheticModules/__init__.py
|
|
35
39
|
mapFolding/syntheticModules/numbaCount_doTheNeedful.py
|
|
36
40
|
tests/__init__.py
|
|
37
41
|
tests/conftest.py
|
|
@@ -68,7 +68,7 @@ readme = { file = "README.md", content-type = "text/markdown" }
|
|
|
68
68
|
requires-python = ">=3.10"
|
|
69
69
|
scripts = { getOEISids = "mapFolding.oeis:getOEISids", clearOEIScache = "mapFolding.oeis:clearOEIScache", OEIS_for_n = "mapFolding.oeis:OEIS_for_n" }
|
|
70
70
|
urls = { Donate = "https://www.patreon.com/integrated", Homepage = "https://github.com/hunterhogan/mapFolding", Repository = "https://github.com/hunterhogan/mapFolding.git" }
|
|
71
|
-
version = "0.8.
|
|
71
|
+
version = "0.8.3"
|
|
72
72
|
|
|
73
73
|
[tool.coverage]
|
|
74
74
|
report = { exclude_lines = [
|
|
@@ -93,7 +93,8 @@ addopts = ["--color=yes", "-n 2"]
|
|
|
93
93
|
testpaths = ["tests"]
|
|
94
94
|
|
|
95
95
|
[tool.pytest_env]
|
|
96
|
-
NUMBA_JIT_COVERAGE = "1"
|
|
96
|
+
# NUMBA_JIT_COVERAGE = "1"
|
|
97
|
+
# NUMBA_DISABLE_JIT = "1"
|
|
97
98
|
|
|
98
99
|
[tool.setuptools]
|
|
99
100
|
package-data = { "*" = ["py.typed"] }
|
|
@@ -5,6 +5,7 @@ from tests.conftest import standardizedEqualToCallableReturn
|
|
|
5
5
|
from typing import Any, Literal
|
|
6
6
|
from Z0Z_tools import intInnit
|
|
7
7
|
from Z0Z_tools.pytestForYourUse import PytestFor_intInnit, PytestFor_oopsieKwargsie
|
|
8
|
+
import multiprocessing
|
|
8
9
|
import numba
|
|
9
10
|
import pytest
|
|
10
11
|
import sys
|
|
@@ -78,6 +79,6 @@ def testOopsieKwargsie(nameOfTest: str, callablePytest: Callable[[], None]) -> N
|
|
|
78
79
|
(0, numba.get_num_threads()),
|
|
79
80
|
(1, 1),
|
|
80
81
|
])
|
|
81
|
-
def
|
|
82
|
-
|
|
83
|
-
|
|
82
|
+
def test_setCPUlimitNumba(CPUlimit: None | float | bool | Literal[4] | Literal[-2] | Literal[0] | Literal[1], expectedLimit: Any | int) -> None:
|
|
83
|
+
numba.set_num_threads(multiprocessing.cpu_count())
|
|
84
|
+
standardizedEqualToCallableReturn(expectedLimit, setCPUlimit, CPUlimit, 'numba')
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/someAssemblyRequired/synthesizeNumbaJobVESTIGIAL.py
RENAMED
|
File without changes
|
{mapfolding-0.8.2 → mapfolding-0.8.3}/mapFolding/syntheticModules/numbaCount_doTheNeedful.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|