mapFolding 0.3.9__tar.gz → 0.3.11__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.3.9 → mapfolding-0.3.11}/PKG-INFO +3 -7
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/__init__.py +27 -9
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/basecamp.py +1 -1
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/beDRY.py +25 -13
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/oeis.py +81 -71
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/someAssemblyRequired/makeJob.py +5 -6
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/someAssemblyRequired/synthesizeModuleJAX.py +2 -2
- mapfolding-0.3.11/mapFolding/someAssemblyRequired/synthesizeNumba.py +805 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/syntheticModules/numba_countInitialize.py +10 -7
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/syntheticModules/numba_countParallel.py +14 -9
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/syntheticModules/numba_countSequential.py +11 -7
- mapfolding-0.3.11/mapFolding/syntheticModules/numba_doTheNeedful.py +20 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/theDao.py +66 -50
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/theSSOT.py +21 -39
- mapfolding-0.3.11/mapFolding/theSSOTnumba.py +116 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding.egg-info/PKG-INFO +3 -7
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding.egg-info/SOURCES.txt +2 -3
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding.egg-info/requires.txt +2 -7
- {mapfolding-0.3.9 → mapfolding-0.3.11}/pyproject.toml +9 -19
- {mapfolding-0.3.9 → mapfolding-0.3.11}/tests/conftest.py +2 -43
- {mapfolding-0.3.9 → mapfolding-0.3.11}/tests/test_oeis.py +7 -66
- {mapfolding-0.3.9 → mapfolding-0.3.11}/tests/test_other.py +30 -29
- mapfolding-0.3.9/mapFolding/someAssemblyRequired/synthesizeModuleJobNumba.py +0 -212
- mapfolding-0.3.9/mapFolding/someAssemblyRequired/synthesizeModulesNumba.py +0 -506
- mapfolding-0.3.9/mapFolding/syntheticModules/__init__.py +0 -3
- mapfolding-0.3.9/mapFolding/syntheticModules/numba_doTheNeedful.py +0 -33
- {mapfolding-0.3.9 → mapfolding-0.3.11}/LICENSE +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/README.md +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/reference/flattened.py +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/reference/hunterNumba.py +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/reference/irvineJavaPort.py +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/reference/jax.py +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/reference/lunnan.py +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/reference/lunnanNumpy.py +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/reference/lunnanWhile.py +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/reference/rotatedEntryPoint.py +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/reference/total_countPlus1vsPlusN.py +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/someAssemblyRequired/__init__.py +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/someAssemblyRequired/getLLVMforNoReason.py +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding.egg-info/dependency_links.txt +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding.egg-info/entry_points.txt +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding.egg-info/top_level.txt +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/setup.cfg +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/tests/__init__.py +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/tests/conftest_tmpRegistry.py +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/tests/conftest_uniformTests.py +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/tests/test_tasks.py +0 -0
- {mapfolding-0.3.9 → mapfolding-0.3.11}/tests/test_types.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: mapFolding
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.11
|
|
4
4
|
Summary: Count distinct ways to fold a map (or a strip of stamps)
|
|
5
5
|
Author-email: Hunter Hogan <HunterHogan@pm.me>
|
|
6
6
|
License: CC-BY-NC-4.0
|
|
@@ -25,12 +25,8 @@ License-File: LICENSE
|
|
|
25
25
|
Requires-Dist: numba
|
|
26
26
|
Requires-Dist: numpy
|
|
27
27
|
Requires-Dist: Z0Z_tools
|
|
28
|
-
Provides-Extra: benchmark
|
|
29
|
-
Requires-Dist: ipywidgets; extra == "benchmark"
|
|
30
|
-
Requires-Dist: jupyter; extra == "benchmark"
|
|
31
|
-
Requires-Dist: pandas; extra == "benchmark"
|
|
32
|
-
Requires-Dist: tqdm; extra == "benchmark"
|
|
33
28
|
Provides-Extra: testing
|
|
29
|
+
Requires-Dist: autoflake; extra == "testing"
|
|
34
30
|
Requires-Dist: more_itertools; extra == "testing"
|
|
35
31
|
Requires-Dist: mypy; extra == "testing"
|
|
36
32
|
Requires-Dist: pytest-cov; extra == "testing"
|
|
@@ -39,8 +35,8 @@ Requires-Dist: pytest-mypy; extra == "testing"
|
|
|
39
35
|
Requires-Dist: pytest-xdist; extra == "testing"
|
|
40
36
|
Requires-Dist: pytest; extra == "testing"
|
|
41
37
|
Requires-Dist: python_minifier; extra == "testing"
|
|
42
|
-
Requires-Dist: tomli; extra == "testing"
|
|
43
38
|
Requires-Dist: types-setuptools; extra == "testing"
|
|
39
|
+
Requires-Dist: updateCitation; extra == "testing"
|
|
44
40
|
|
|
45
41
|
# Algorithm(s) for counting distinct ways to fold a map (or a strip of stamps)
|
|
46
42
|
|
|
@@ -1,25 +1,43 @@
|
|
|
1
|
+
# fundamentals
|
|
1
2
|
from mapFolding.theSSOT import (
|
|
2
3
|
computationState,
|
|
3
4
|
EnumIndices,
|
|
4
|
-
getAlgorithmCallable,
|
|
5
|
-
getAlgorithmSource,
|
|
6
5
|
getDispatcherCallable,
|
|
7
|
-
getPathJobDEFAULT,
|
|
8
6
|
getPathPackage,
|
|
9
|
-
getPathSyntheticModules,
|
|
10
|
-
hackSSOTdatatype,
|
|
11
|
-
hackSSOTdtype,
|
|
12
7
|
indexMy,
|
|
13
8
|
indexTrack,
|
|
14
|
-
moduleOfSyntheticModules,
|
|
15
9
|
myPackageNameIs,
|
|
16
|
-
|
|
17
|
-
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
# Datatype management
|
|
13
|
+
from mapFolding.theSSOT import (
|
|
14
|
+
hackSSOTdatatype,
|
|
15
|
+
hackSSOTdtype,
|
|
18
16
|
setDatatypeElephino,
|
|
19
17
|
setDatatypeFoldsTotal,
|
|
20
18
|
setDatatypeLeavesTotal,
|
|
21
19
|
setDatatypeModule,
|
|
22
20
|
)
|
|
21
|
+
|
|
22
|
+
# Synthesize modules
|
|
23
|
+
from mapFolding.theSSOT import (
|
|
24
|
+
getAlgorithmCallable,
|
|
25
|
+
getAlgorithmSource,
|
|
26
|
+
getPathJobRootDEFAULT,
|
|
27
|
+
getPathSyntheticModules,
|
|
28
|
+
moduleOfSyntheticModules,
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
# Parameters for the prima donna
|
|
32
|
+
from mapFolding.theSSOT import (
|
|
33
|
+
ParametersNumba,
|
|
34
|
+
parametersNumbaDEFAULT,
|
|
35
|
+
parametersNumbaFailEarly,
|
|
36
|
+
parametersNumbaParallelDEFAULT,
|
|
37
|
+
parametersNumbaSuperJit,
|
|
38
|
+
parametersNumbaSuperJitParallel,
|
|
39
|
+
)
|
|
40
|
+
|
|
23
41
|
from mapFolding.beDRY import (
|
|
24
42
|
getFilenameFoldsTotal,
|
|
25
43
|
getPathFilenameFoldsTotal,
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from mapFolding import getDispatcherCallable, getPathFilenameFoldsTotal, outfitCountFolds, saveFoldsTotal
|
|
1
|
+
from mapFolding import computationState, getDispatcherCallable, getPathFilenameFoldsTotal, outfitCountFolds, saveFoldsTotal
|
|
2
2
|
from typing import Optional, Sequence, Union
|
|
3
3
|
import os
|
|
4
4
|
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
"""A relatively stable API for oft-needed functionality."""
|
|
2
|
-
from operator import ge
|
|
3
2
|
from mapFolding import (
|
|
4
3
|
computationState,
|
|
5
|
-
|
|
4
|
+
getPathJobRootDEFAULT,
|
|
6
5
|
hackSSOTdtype,
|
|
7
6
|
indexMy,
|
|
8
7
|
indexTrack,
|
|
@@ -11,9 +10,9 @@ from mapFolding import (
|
|
|
11
10
|
setDatatypeLeavesTotal,
|
|
12
11
|
)
|
|
13
12
|
from numpy import integer
|
|
14
|
-
from numpy.typing import
|
|
13
|
+
from numpy.typing import DTypeLike, NDArray
|
|
15
14
|
from typing import Any, List, Optional, Sequence, Tuple, Type, Union
|
|
16
|
-
from Z0Z_tools import
|
|
15
|
+
from Z0Z_tools import defineConcurrencyLimit, intInnit, oopsieKwargsie
|
|
17
16
|
import numba
|
|
18
17
|
import numpy
|
|
19
18
|
import os
|
|
@@ -21,18 +20,26 @@ import pathlib
|
|
|
21
20
|
import sys
|
|
22
21
|
|
|
23
22
|
def getFilenameFoldsTotal(mapShape: Union[Sequence[int], numpy.ndarray[Tuple[int], numpy.dtype[integer[Any]]]]) -> str:
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
The
|
|
27
|
-
|
|
28
|
-
|
|
23
|
+
"""Make a standardized filename for the computed value `foldsTotal`.
|
|
24
|
+
|
|
25
|
+
The filename takes into account
|
|
26
|
+
- the dimensions of the map, aka `mapShape`, aka `listDimensions`
|
|
27
|
+
- no spaces in the filename
|
|
28
|
+
- safe filesystem characters across platforms
|
|
29
|
+
- unique extension
|
|
30
|
+
- avoiding potential problems when Python is manipulating the filename, including
|
|
31
|
+
- treating the file stem as a valid Python identifier, such as
|
|
32
|
+
- not starting with a number
|
|
33
|
+
- not using reserved words
|
|
34
|
+
- no dashes or other special characters
|
|
35
|
+
- uh, I can't remember, but I found some frustrating edge limitations
|
|
36
|
+
- if 'p' is still the first character, I picked that because it was the original identifier for the map shape in Lunnan's code
|
|
29
37
|
|
|
30
38
|
Parameters:
|
|
31
|
-
mapShape: A sequence of integers representing the dimensions
|
|
32
|
-
of the map (e.g., [3, 2] for a 3x2 map)
|
|
39
|
+
mapShape: A sequence of integers representing the dimensions of the map (e.g., [3, 2] for a 3x2 map)
|
|
33
40
|
|
|
34
41
|
Returns:
|
|
35
|
-
A filename string in format 'pNxM.foldsTotal' where N,M are sorted dimensions
|
|
42
|
+
filenameFoldsTotal: A filename string in format 'pNxM.foldsTotal' where N,M are sorted dimensions
|
|
36
43
|
"""
|
|
37
44
|
return 'p' + 'x'.join(str(dim) for dim in sorted(mapShape)) + '.foldsTotal'
|
|
38
45
|
|
|
@@ -76,10 +83,15 @@ def getPathFilenameFoldsTotal(mapShape: Union[Sequence[int], numpy.ndarray[Tuple
|
|
|
76
83
|
Returns:
|
|
77
84
|
pathlib.Path: Complete path to the folds total file.
|
|
78
85
|
"""
|
|
79
|
-
pathFilenameFoldsTotal = pathlib.Path(pathLikeWriteFoldsTotal) if pathLikeWriteFoldsTotal is not None else
|
|
86
|
+
pathFilenameFoldsTotal = pathlib.Path(pathLikeWriteFoldsTotal) if pathLikeWriteFoldsTotal is not None else getPathJobRootDEFAULT()
|
|
80
87
|
if pathFilenameFoldsTotal.is_dir():
|
|
81
88
|
filenameFoldsTotalDEFAULT = getFilenameFoldsTotal(mapShape)
|
|
82
89
|
pathFilenameFoldsTotal = pathFilenameFoldsTotal / filenameFoldsTotalDEFAULT
|
|
90
|
+
elif pathlib.Path(pathLikeWriteFoldsTotal).is_absolute(): # type: ignore
|
|
91
|
+
pathFilenameFoldsTotal = pathlib.Path(pathLikeWriteFoldsTotal) # type: ignore
|
|
92
|
+
else:
|
|
93
|
+
pathFilenameFoldsTotal = pathlib.Path(getPathJobRootDEFAULT(), pathLikeWriteFoldsTotal) # type: ignore
|
|
94
|
+
|
|
83
95
|
pathFilenameFoldsTotal.parent.mkdir(parents=True, exist_ok=True)
|
|
84
96
|
return pathFilenameFoldsTotal
|
|
85
97
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"""Everything implementing the The Online Encyclopedia of Integer Sequences (OEIS);
|
|
2
2
|
_only_ things that implement _only_ the OEIS."""
|
|
3
3
|
from datetime import datetime, timedelta
|
|
4
|
-
from mapFolding import countFolds
|
|
5
|
-
from typing import
|
|
4
|
+
from mapFolding import countFolds, getPathPackage
|
|
5
|
+
from typing import Any, Callable, Dict, Final, List, Tuple, TYPE_CHECKING, Union
|
|
6
6
|
import argparse
|
|
7
7
|
import pathlib
|
|
8
8
|
import random
|
|
@@ -10,6 +10,7 @@ import sys
|
|
|
10
10
|
import time
|
|
11
11
|
import urllib.request
|
|
12
12
|
import urllib.response
|
|
13
|
+
import warnings
|
|
13
14
|
|
|
14
15
|
if TYPE_CHECKING:
|
|
15
16
|
from typing import TypedDict
|
|
@@ -18,10 +19,12 @@ else:
|
|
|
18
19
|
|
|
19
20
|
"""
|
|
20
21
|
Section: make `settingsOEIS`"""
|
|
22
|
+
|
|
23
|
+
_pathCache = getPathPackage() / ".cache"
|
|
24
|
+
|
|
21
25
|
class SettingsOEIS(TypedDict):
|
|
22
|
-
# I would prefer to load description dynamically from OEIS, but it's a pita for me
|
|
23
|
-
# to learn how to efficiently implement right now.
|
|
24
26
|
description: str
|
|
27
|
+
offset: int
|
|
25
28
|
getMapShape: Callable[[int], List[int]]
|
|
26
29
|
valuesBenchmark: List[int]
|
|
27
30
|
valuesKnown: Dict[int, int]
|
|
@@ -31,40 +34,33 @@ class SettingsOEIS(TypedDict):
|
|
|
31
34
|
|
|
32
35
|
settingsOEIShardcodedValues: Dict[str, Dict[str, Any]] = {
|
|
33
36
|
'A001415': {
|
|
34
|
-
'description': 'Number of ways of folding a 2 X n strip of stamps.',
|
|
35
37
|
'getMapShape': lambda n: sorted([2, n]),
|
|
36
38
|
'valuesBenchmark': [14],
|
|
37
39
|
'valuesTestParallelization': [*range(3, 7)],
|
|
38
40
|
'valuesTestValidation': [0, 1, random.randint(2, 9)],
|
|
39
41
|
},
|
|
40
42
|
'A001416': {
|
|
41
|
-
'description': 'Number of ways of folding a 3 X n strip of stamps.',
|
|
42
43
|
'getMapShape': lambda n: sorted([3, n]),
|
|
43
44
|
'valuesBenchmark': [9],
|
|
44
45
|
'valuesTestParallelization': [*range(3, 5)],
|
|
45
46
|
'valuesTestValidation': [0, 1, random.randint(2, 6)],
|
|
46
47
|
},
|
|
47
48
|
'A001417': {
|
|
48
|
-
'description': 'Number of ways of folding a 2 X 2 X ... X 2 n-dimensional map.',
|
|
49
49
|
'getMapShape': lambda n: [2] * n,
|
|
50
50
|
'valuesBenchmark': [6],
|
|
51
51
|
'valuesTestParallelization': [*range(2, 4)],
|
|
52
52
|
'valuesTestValidation': [0, 1, random.randint(2, 4)],
|
|
53
53
|
},
|
|
54
54
|
'A195646': {
|
|
55
|
-
'description': 'Number of ways of folding a 3 X 3 X ... X 3 n-dimensional map.',
|
|
56
55
|
'getMapShape': lambda n: [3] * n,
|
|
57
56
|
'valuesBenchmark': [3],
|
|
58
57
|
'valuesTestParallelization': [*range(2, 3)],
|
|
59
58
|
'valuesTestValidation': [0, 1, 2],
|
|
60
59
|
},
|
|
61
60
|
'A001418': {
|
|
62
|
-
'description': 'Number of ways of folding an n X n sheet of stamps.',
|
|
63
61
|
'getMapShape': lambda n: [n, n],
|
|
64
62
|
'valuesBenchmark': [5],
|
|
65
63
|
'valuesTestParallelization': [*range(2, 4)],
|
|
66
|
-
# offset 1: hypothetically, if I were to load the offset from OEIS, I could use it to
|
|
67
|
-
# determine if a sequence is defined at n=0, which would affect, for example, the valuesTestValidation.
|
|
68
64
|
'valuesTestValidation': [1, random.randint(2, 4)],
|
|
69
65
|
},
|
|
70
66
|
}
|
|
@@ -125,9 +121,9 @@ def _parseBFileOEIS(OEISbFile: str, oeisID: str) -> Dict[int, int]:
|
|
|
125
121
|
sequence ID or if the content format is invalid.
|
|
126
122
|
"""
|
|
127
123
|
bFileLines = OEISbFile.strip().splitlines()
|
|
128
|
-
# The first line has the sequence ID
|
|
129
124
|
if not bFileLines.pop(0).startswith(f"# {oeisID}"):
|
|
130
|
-
|
|
125
|
+
warnings.warn(f"Content does not match sequence {oeisID}")
|
|
126
|
+
return {-1: -1}
|
|
131
127
|
|
|
132
128
|
OEISsequence = {}
|
|
133
129
|
for line in bFileLines:
|
|
@@ -137,10 +133,30 @@ def _parseBFileOEIS(OEISbFile: str, oeisID: str) -> Dict[int, int]:
|
|
|
137
133
|
OEISsequence[n] = aOFn
|
|
138
134
|
return OEISsequence
|
|
139
135
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
136
|
+
def _getOEISofficial(pathFilenameCache: pathlib.Path, url: str) -> None | str:
|
|
137
|
+
cacheDays = 7
|
|
138
|
+
tryCache = False
|
|
139
|
+
if pathFilenameCache.exists():
|
|
140
|
+
fileAge = datetime.now() - datetime.fromtimestamp(pathFilenameCache.stat().st_mtime)
|
|
141
|
+
tryCache = fileAge < timedelta(days=cacheDays)
|
|
142
|
+
|
|
143
|
+
oeisInformation = None
|
|
144
|
+
if tryCache:
|
|
145
|
+
try:
|
|
146
|
+
oeisInformation = pathFilenameCache.read_text()
|
|
147
|
+
except IOError:
|
|
148
|
+
tryCache = False
|
|
149
|
+
|
|
150
|
+
if not tryCache:
|
|
151
|
+
httpResponse: urllib.response.addinfourl = urllib.request.urlopen(url)
|
|
152
|
+
oeisInformation = httpResponse.read().decode('utf-8')
|
|
153
|
+
pathFilenameCache.parent.mkdir(parents=True, exist_ok=True)
|
|
154
|
+
pathFilenameCache.write_text(oeisInformation)
|
|
155
|
+
|
|
156
|
+
if not oeisInformation:
|
|
157
|
+
warnings.warn(f"Failed to retrieve OEIS sequence information for {pathFilenameCache.stem}.")
|
|
158
|
+
|
|
159
|
+
return oeisInformation
|
|
144
160
|
|
|
145
161
|
def _getOEISidValues(oeisID: str) -> Dict[int, int]:
|
|
146
162
|
"""
|
|
@@ -162,64 +178,60 @@ def _getOEISidValues(oeisID: str) -> Dict[int, int]:
|
|
|
162
178
|
"""
|
|
163
179
|
|
|
164
180
|
pathFilenameCache = _pathCache / _getFilenameOEISbFile(oeisID)
|
|
165
|
-
|
|
181
|
+
url = f"https://oeis.org/{oeisID}/{_getFilenameOEISbFile(oeisID)}"
|
|
166
182
|
|
|
167
|
-
|
|
168
|
-
if pathFilenameCache.exists():
|
|
169
|
-
fileAge = datetime.now() - datetime.fromtimestamp(pathFilenameCache.stat().st_mtime)
|
|
170
|
-
tryCache = fileAge < timedelta(days=cacheDays)
|
|
183
|
+
oeisInformation = _getOEISofficial(pathFilenameCache, url)
|
|
171
184
|
|
|
172
|
-
if
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
return _parseBFileOEIS(OEISbFile, oeisID)
|
|
176
|
-
except (ValueError, IOError):
|
|
177
|
-
tryCache = False
|
|
178
|
-
|
|
179
|
-
urlOEISbFile = f"https://oeis.org/{oeisID}/{_getFilenameOEISbFile(oeisID)}"
|
|
180
|
-
httpResponse: urllib.response.addinfourl = urllib.request.urlopen(urlOEISbFile)
|
|
181
|
-
OEISbFile = httpResponse.read().decode('utf-8')
|
|
182
|
-
|
|
183
|
-
if not tryCache:
|
|
184
|
-
pathFilenameCache.parent.mkdir(parents=True, exist_ok=True)
|
|
185
|
-
pathFilenameCache.write_text(OEISbFile)
|
|
185
|
+
if oeisInformation:
|
|
186
|
+
return _parseBFileOEIS(oeisInformation, oeisID)
|
|
187
|
+
return {-1: -1}
|
|
186
188
|
|
|
187
|
-
|
|
189
|
+
def _getOEISidInformation(oeisID: str) -> Tuple[str, int]:
|
|
190
|
+
oeisID = _validateOEISid(oeisID)
|
|
191
|
+
pathFilenameCache = _pathCache / f"{oeisID}.txt"
|
|
192
|
+
url = f"https://oeis.org/search?q=id:{oeisID}&fmt=text"
|
|
193
|
+
|
|
194
|
+
oeisInformation = _getOEISofficial(pathFilenameCache, url)
|
|
195
|
+
|
|
196
|
+
if not oeisInformation:
|
|
197
|
+
return "Not found", -1
|
|
198
|
+
|
|
199
|
+
description_parts = []
|
|
200
|
+
offset = None
|
|
201
|
+
for line in oeisInformation.splitlines():
|
|
202
|
+
if line.startswith('%N'):
|
|
203
|
+
parts = line.split()
|
|
204
|
+
if parts[1] == oeisID:
|
|
205
|
+
desc_part = ' '.join(parts[2:])
|
|
206
|
+
description_parts.append(desc_part)
|
|
207
|
+
elif line.startswith('%O'):
|
|
208
|
+
parts = line.split()
|
|
209
|
+
if parts[1] == oeisID:
|
|
210
|
+
offset_str = parts[2].split(',')[0]
|
|
211
|
+
offset = int(offset_str)
|
|
212
|
+
if not description_parts:
|
|
213
|
+
warnings.warn(f"No description found for {oeisID}")
|
|
214
|
+
description_parts.append("No description found")
|
|
215
|
+
if offset is None:
|
|
216
|
+
warnings.warn(f"No offset found for {oeisID}")
|
|
217
|
+
offset = -1
|
|
218
|
+
description = ' '.join(description_parts)
|
|
219
|
+
return description, offset
|
|
188
220
|
|
|
189
221
|
def makeSettingsOEIS() -> Dict[str, SettingsOEIS]:
|
|
190
|
-
"""
|
|
191
|
-
Creates a dictionary mapping OEIS IDs to their corresponding settings.
|
|
192
|
-
|
|
193
|
-
This function initializes settings for each implemented OEIS sequence by combining
|
|
194
|
-
hardcoded values with dynamically retrieved OEIS sequence values.
|
|
195
|
-
|
|
196
|
-
Returns:
|
|
197
|
-
Dict[str, SettingsOEIS]: A dictionary where:
|
|
198
|
-
- Keys are OEIS sequence IDs (str)
|
|
199
|
-
- Values are SettingsOEIS objects containing:
|
|
200
|
-
- description: Text description of the sequence
|
|
201
|
-
- getMapShape: Function to get dimensions
|
|
202
|
-
- valuesBenchmark: Benchmark values
|
|
203
|
-
- valuesKnown: Known values from OEIS
|
|
204
|
-
- valuesTestValidation: Values for test validation
|
|
205
|
-
- valueUnknown: First unknown value in sequence
|
|
206
|
-
|
|
207
|
-
Note:
|
|
208
|
-
Relies on global variables:
|
|
209
|
-
- oeisIDsImplemented: List of implemented OEIS sequence IDs
|
|
210
|
-
- settingsOEIShardcodedValues: Dictionary of hardcoded settings per sequence
|
|
211
|
-
"""
|
|
212
222
|
settingsTarget = {}
|
|
213
223
|
for oeisID in oeisIDsImplemented:
|
|
214
224
|
valuesKnownSherpa = _getOEISidValues(oeisID)
|
|
225
|
+
descriptionSherpa, offsetSherpa = _getOEISidInformation(oeisID)
|
|
215
226
|
settingsTarget[oeisID] = SettingsOEIS(
|
|
216
|
-
description=
|
|
227
|
+
description=descriptionSherpa,
|
|
228
|
+
offset=offsetSherpa,
|
|
217
229
|
getMapShape=settingsOEIShardcodedValues[oeisID]['getMapShape'],
|
|
218
230
|
valuesBenchmark=settingsOEIShardcodedValues[oeisID]['valuesBenchmark'],
|
|
219
231
|
valuesTestParallelization=settingsOEIShardcodedValues[oeisID]['valuesTestParallelization'],
|
|
220
232
|
valuesTestValidation=settingsOEIShardcodedValues[oeisID]['valuesTestValidation'],
|
|
221
|
-
valuesKnown
|
|
222
|
-
valueUnknown
|
|
233
|
+
valuesKnown=valuesKnownSherpa,
|
|
234
|
+
valueUnknown=max(valuesKnownSherpa.keys(), default=0) + 1
|
|
223
235
|
)
|
|
224
236
|
return settingsTarget
|
|
225
237
|
|
|
@@ -278,11 +290,11 @@ def oeisIDfor_n(oeisID: str, n: int) -> int:
|
|
|
278
290
|
listDimensions = settingsOEIS[oeisID]['getMapShape'](n)
|
|
279
291
|
|
|
280
292
|
if n <= 1 or len(listDimensions) < 2:
|
|
281
|
-
|
|
282
|
-
if
|
|
283
|
-
return foldsTotal
|
|
284
|
-
else:
|
|
293
|
+
offset = settingsOEIS[oeisID]['offset']
|
|
294
|
+
if n < offset:
|
|
285
295
|
raise ArithmeticError(f"OEIS sequence {oeisID} is not defined at n={n}.")
|
|
296
|
+
foldsTotal = settingsOEIS[oeisID]['valuesKnown'][n]
|
|
297
|
+
return foldsTotal
|
|
286
298
|
|
|
287
299
|
return countFolds(listDimensions)
|
|
288
300
|
|
|
@@ -314,11 +326,9 @@ def clearOEIScache() -> None:
|
|
|
314
326
|
if not _pathCache.exists():
|
|
315
327
|
print(f"Cache directory, {_pathCache}, not found - nothing to clear.")
|
|
316
328
|
return
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
pathFilenameCache.unlink(missing_ok=True)
|
|
321
|
-
|
|
329
|
+
for oeisID in settingsOEIS:
|
|
330
|
+
( _pathCache / f"{oeisID}.txt" ).unlink(missing_ok=True)
|
|
331
|
+
( _pathCache / _getFilenameOEISbFile(oeisID) ).unlink(missing_ok=True)
|
|
322
332
|
print(f"Cache cleared from {_pathCache}")
|
|
323
333
|
|
|
324
334
|
def getOEISids() -> None:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import importlib.util
|
|
2
1
|
from mapFolding import getPathFilenameFoldsTotal, computationState, outfitCountFolds, getAlgorithmSource
|
|
3
|
-
from
|
|
2
|
+
from types import ModuleType
|
|
3
|
+
from typing import Any, Literal, Optional, Sequence, overload
|
|
4
4
|
import pathlib
|
|
5
5
|
import pickle
|
|
6
6
|
|
|
@@ -14,7 +14,7 @@ def makeStateJob(listDimensions: Sequence[int], *, writeJob: Literal[False]
|
|
|
14
14
|
, **keywordArguments: Optional[str]) -> computationState:
|
|
15
15
|
...
|
|
16
16
|
|
|
17
|
-
def makeStateJob(listDimensions: Sequence[int], *, writeJob: bool = True, **keywordArguments: Optional[
|
|
17
|
+
def makeStateJob(listDimensions: Sequence[int], *, writeJob: bool = True, **keywordArguments: Optional[Any]) -> computationState | pathlib.Path:
|
|
18
18
|
"""
|
|
19
19
|
Creates a computation state job for map folding calculations and optionally saves it to disk.
|
|
20
20
|
|
|
@@ -43,10 +43,9 @@ def makeStateJob(listDimensions: Sequence[int], *, writeJob: bool = True, **keyw
|
|
|
43
43
|
when writeJob is True. The file is saved in a directory structure based on the map shape.
|
|
44
44
|
"""
|
|
45
45
|
|
|
46
|
-
stateUniversal: computationState = outfitCountFolds(listDimensions,
|
|
46
|
+
stateUniversal: computationState = outfitCountFolds(listDimensions, **keywordArguments)
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
moduleSource = getAlgorithmSource()
|
|
48
|
+
moduleSource: ModuleType = getAlgorithmSource()
|
|
50
49
|
moduleSource.countInitialize(stateUniversal['connectionGraph'], stateUniversal['gapsWhere'], stateUniversal['my'], stateUniversal['track'])
|
|
51
50
|
|
|
52
51
|
if not writeJob:
|
{mapfolding-0.3.9 → mapfolding-0.3.11}/mapFolding/someAssemblyRequired/synthesizeModuleJAX.py
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from mapFolding import getAlgorithmSource,
|
|
1
|
+
from mapFolding import getAlgorithmSource, getPathSyntheticModules
|
|
2
2
|
from mapFolding import setDatatypeModule, setDatatypeFoldsTotal, setDatatypeElephino, setDatatypeLeavesTotal
|
|
3
3
|
from typing import Optional
|
|
4
4
|
import ast
|
|
@@ -18,7 +18,7 @@ def writeJax(*, codeSource: Optional[str] = None, pathFilenameAlgorithm: Optiona
|
|
|
18
18
|
else:
|
|
19
19
|
raise NotImplementedError("You haven't written this part yet.")
|
|
20
20
|
if pathFilenameDestination is None:
|
|
21
|
-
pathFilenameDestination =
|
|
21
|
+
pathFilenameDestination = getPathSyntheticModules() / "countJax.py"
|
|
22
22
|
# pathFilenameDestination.write_text(transformedText)
|
|
23
23
|
|
|
24
24
|
if __name__ == '__main__':
|