mapFolding 0.13.1__py3-none-any.whl → 0.14.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/_oeisFormulas/A000136.py +4 -0
- mapFolding/_oeisFormulas/A000560.py +4 -0
- mapFolding/_oeisFormulas/A000682.py +17 -0
- mapFolding/_oeisFormulas/A005315.py +4 -0
- mapFolding/_oeisFormulas/A005316.py +10 -0
- mapFolding/_oeisFormulas/A223094.py +7 -0
- mapFolding/_oeisFormulas/A259702.py +4 -0
- mapFolding/_oeisFormulas/A301620.py +6 -0
- mapFolding/_oeisFormulas/Z0Z_aOFn.py +18 -0
- mapFolding/_oeisFormulas/Z0Z_oeisMeanders.py +53 -0
- mapFolding/_oeisFormulas/__init__.py +1 -0
- mapFolding/_oeisFormulas/matrixMeanders.py +79 -0
- mapFolding/_oeisFormulas/matrixMeandersAnnex.py +84 -0
- mapFolding/_theSSOT.py +68 -26
- mapFolding/basecamp.py +2 -2
- mapFolding/beDRY.py +1 -1
- mapFolding/oeis.py +56 -167
- mapFolding/reference/A005316JavaPort.py +134 -0
- mapFolding/reference/A005316imperative.py +101 -0
- mapFolding/reference/A005316intOptimized.py +122 -0
- mapFolding/reference/A005316optimized128bit.py +79 -0
- mapFolding/reference/A005316primitiveOptimized.py +97 -0
- mapFolding/reference/A005316redis.py +118 -0
- mapFolding/reference/A005316write2disk.py +169 -0
- mapFolding/reference/irvineJavaPort.py +4 -8
- mapFolding/reference/matrixMeandersBaseline.py +65 -0
- mapFolding/reference/matrixMeandersBaselineAnnex.py +84 -0
- mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +45 -17
- mapFolding/tests/conftest.py +13 -13
- mapFolding/tests/test_computations.py +4 -4
- mapFolding/tests/test_oeis.py +7 -14
- mapfolding-0.14.1.dist-info/METADATA +77 -0
- {mapfolding-0.13.1.dist-info → mapfolding-0.14.1.dist-info}/RECORD +37 -15
- mapfolding-0.13.1.dist-info/METADATA +0 -154
- {mapfolding-0.13.1.dist-info → mapfolding-0.14.1.dist-info}/WHEEL +0 -0
- {mapfolding-0.13.1.dist-info → mapfolding-0.14.1.dist-info}/entry_points.txt +0 -0
- {mapfolding-0.13.1.dist-info → mapfolding-0.14.1.dist-info}/licenses/LICENSE +0 -0
- {mapfolding-0.13.1.dist-info → mapfolding-0.14.1.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
from mapFolding._oeisFormulas.matrixMeanders import count, curveMaximum
|
|
2
|
+
|
|
3
|
+
def initializeA000682(n: int) -> dict[int, int]:
|
|
4
|
+
curveLocationsMAXIMUM = curveMaximum[n].curveLocationsMAXIMUM
|
|
5
|
+
|
|
6
|
+
curveSeed: int = 5 - (n & 0b1) * 4
|
|
7
|
+
listCurveLocations = [(curveSeed << 1) | curveSeed]
|
|
8
|
+
|
|
9
|
+
while listCurveLocations[-1] < curveLocationsMAXIMUM:
|
|
10
|
+
curveSeed = (curveSeed << 4) | 0b101
|
|
11
|
+
listCurveLocations.append((curveSeed << 1) | curveSeed)
|
|
12
|
+
|
|
13
|
+
return dict.fromkeys(listCurveLocations, 1)
|
|
14
|
+
|
|
15
|
+
def A000682(n: int) -> int:
|
|
16
|
+
return count(n - 1, initializeA000682(n - 1))
|
|
17
|
+
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
from mapFolding._oeisFormulas.A000136 import A000136
|
|
2
|
+
from mapFolding._oeisFormulas.A000682 import A000682
|
|
3
|
+
|
|
4
|
+
def A223094(n: int) -> int:
|
|
5
|
+
return A000136(n) - A000682(n + 1)
|
|
6
|
+
|
|
7
|
+
# %F A223094 For n >= 3: a(n) = n! - Sum_{k=3..n-1} (a(k)*n!/k!) - A000682(n+1). - _Roger Ford_, Aug 24 2024
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from mapFolding._oeisFormulas.A000136 import A000136
|
|
2
|
+
from mapFolding.oeis import dictionaryOEIS
|
|
3
|
+
import sys
|
|
4
|
+
import time
|
|
5
|
+
|
|
6
|
+
# ruff: noqa: ERA001
|
|
7
|
+
|
|
8
|
+
if __name__ == '__main__':
|
|
9
|
+
oeisID = 'A000136'
|
|
10
|
+
for n in range(3,30):
|
|
11
|
+
|
|
12
|
+
# print(n)
|
|
13
|
+
|
|
14
|
+
timeStart = time.perf_counter()
|
|
15
|
+
foldsTotal = A000136(n)
|
|
16
|
+
# sys.stdout.write(f"{n} {foldsTotal} {time.perf_counter() - timeStart:.2f}\n")
|
|
17
|
+
sys.stdout.write(f"{foldsTotal == dictionaryOEIS[oeisID]['valuesKnown'][n]} {n} {foldsTotal} {time.perf_counter() - timeStart:.2f}\n")
|
|
18
|
+
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
from mapFolding._oeisFormulas.A000560 import A000560
|
|
2
|
+
from mapFolding._oeisFormulas.A000682 import A000682
|
|
3
|
+
from mapFolding._oeisFormulas.A005315 import A005315
|
|
4
|
+
from mapFolding._oeisFormulas.A005316 import A005316
|
|
5
|
+
from mapFolding._oeisFormulas.A223094 import A223094
|
|
6
|
+
from mapFolding._oeisFormulas.A259702 import A259702
|
|
7
|
+
from mapFolding._oeisFormulas.A301620 import A301620
|
|
8
|
+
from mapFolding.oeis import getOEISidInformation, getOEISidValues
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
oeisIDsMeanders: list[str] = [
|
|
12
|
+
'A000560',
|
|
13
|
+
'A000682',
|
|
14
|
+
'A005315',
|
|
15
|
+
'A005316',
|
|
16
|
+
'A223094',
|
|
17
|
+
'A259702',
|
|
18
|
+
'A301620',
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
dictionaryOEISMeanders: dict[str, dict[str, dict[int, int] | str | int]] = {
|
|
22
|
+
oeisID: {
|
|
23
|
+
'valuesKnown': getOEISidValues(oeisID),
|
|
24
|
+
'description': getOEISidInformation(oeisID)[0],
|
|
25
|
+
'offset': getOEISidInformation(oeisID)[1],
|
|
26
|
+
}
|
|
27
|
+
for oeisID in oeisIDsMeanders
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
# ruff: noqa: S101
|
|
31
|
+
# pyright: reportIndexIssue=false
|
|
32
|
+
|
|
33
|
+
rangeTest = range(5, 13)
|
|
34
|
+
|
|
35
|
+
if __name__ == '__main__':
|
|
36
|
+
for n in rangeTest:
|
|
37
|
+
|
|
38
|
+
A000560for_n = A000560(n)
|
|
39
|
+
assert A000560for_n == dictionaryOEISMeanders['A000560']['valuesKnown'][n]
|
|
40
|
+
A000682for_n = A000682(n)
|
|
41
|
+
assert A000682for_n == dictionaryOEISMeanders['A000682']['valuesKnown'][n]
|
|
42
|
+
A005315for_n = A005315(n)
|
|
43
|
+
assert A005315for_n == dictionaryOEISMeanders['A005315']['valuesKnown'][n]
|
|
44
|
+
A005316for_n = A005316(n)
|
|
45
|
+
assert A005316for_n == dictionaryOEISMeanders['A005316']['valuesKnown'][n]
|
|
46
|
+
A223094for_n = A223094(n)
|
|
47
|
+
assert A223094for_n == dictionaryOEISMeanders['A223094']['valuesKnown'][n]
|
|
48
|
+
A259702for_n = A259702(n)
|
|
49
|
+
assert A259702for_n == dictionaryOEISMeanders['A259702']['valuesKnown'][n]
|
|
50
|
+
A301620for_n = A301620(n)
|
|
51
|
+
assert A301620for_n == dictionaryOEISMeanders['A301620']['valuesKnown'][n]
|
|
52
|
+
|
|
53
|
+
sys.stdout.write(f"\nTrue for {str(rangeTest)}\n")
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""OEIS formula collection and analysis."""
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
from mapFolding._oeisFormulas.matrixMeandersAnnex import curveMaximum as curveMaximum
|
|
2
|
+
from typing import NamedTuple
|
|
3
|
+
|
|
4
|
+
class BifurcatedCurves(NamedTuple):
|
|
5
|
+
bifurcationEven: int
|
|
6
|
+
bifurcationOdd: int
|
|
7
|
+
distinctCrossings: int
|
|
8
|
+
curveLocationsMAXIMUM: int
|
|
9
|
+
|
|
10
|
+
dictionaryCurveLocations: dict[int, list[int]] = {}
|
|
11
|
+
|
|
12
|
+
def getCurveLocations(bridges: int) -> list[BifurcatedCurves]:
|
|
13
|
+
global dictionaryCurveLocations # noqa: PLW0603
|
|
14
|
+
curveLocationsMAXIMUM, bifurcationEvenLocator, bifurcationOddLocator = curveMaximum[bridges]
|
|
15
|
+
listBifurcatedCurves: list[BifurcatedCurves] = []
|
|
16
|
+
# TODO This is ready for concurrency and/or vectorization.
|
|
17
|
+
for curveLocations, listDistinctCrossings in dictionaryCurveLocations.items():
|
|
18
|
+
bifurcationEven = (curveLocations & bifurcationEvenLocator) >> 1
|
|
19
|
+
bifurcationOdd = (curveLocations & bifurcationOddLocator)
|
|
20
|
+
distinctCrossings = sum(listDistinctCrossings)
|
|
21
|
+
listBifurcatedCurves.append(BifurcatedCurves(bifurcationEven, bifurcationOdd, distinctCrossings, curveLocationsMAXIMUM))
|
|
22
|
+
dictionaryCurveLocations = {}
|
|
23
|
+
return listBifurcatedCurves
|
|
24
|
+
|
|
25
|
+
def recordAnalysis(curveLocationAnalysis: int, curveLocationsMAXIMUM: int, distinctCrossings: int) -> None:
|
|
26
|
+
if curveLocationAnalysis < curveLocationsMAXIMUM:
|
|
27
|
+
dictionaryCurveLocations.setdefault(curveLocationAnalysis, []).append(distinctCrossings)
|
|
28
|
+
|
|
29
|
+
def analyzeCurve(bifurcationEven: int, bifurcationOdd: int, distinctCrossings: int, curveLocationsMAXIMUM: int) -> None:
|
|
30
|
+
bifurcationEvenFinalZero = (bifurcationEven & 0b1) == 0
|
|
31
|
+
bifurcationEvenHasCurves = bifurcationEven != 1
|
|
32
|
+
bifurcationOddFinalZero = (bifurcationOdd & 0b1) == 0
|
|
33
|
+
bifurcationOddHasCurves = bifurcationOdd != 1
|
|
34
|
+
|
|
35
|
+
if bifurcationEvenHasCurves:
|
|
36
|
+
curveLocationAnalysis = (bifurcationEven >> 1) | (bifurcationOdd << 2) | bifurcationEvenFinalZero
|
|
37
|
+
recordAnalysis(curveLocationAnalysis, curveLocationsMAXIMUM, distinctCrossings)
|
|
38
|
+
|
|
39
|
+
if bifurcationOddHasCurves:
|
|
40
|
+
curveLocationAnalysis = (bifurcationOdd >> 2) | (bifurcationEven << 3) | (bifurcationOddFinalZero << 1)
|
|
41
|
+
recordAnalysis(curveLocationAnalysis, curveLocationsMAXIMUM, distinctCrossings)
|
|
42
|
+
|
|
43
|
+
curveLocationAnalysis = ((bifurcationOdd | (bifurcationEven << 1)) << 2) | 3
|
|
44
|
+
recordAnalysis(curveLocationAnalysis, curveLocationsMAXIMUM, distinctCrossings)
|
|
45
|
+
|
|
46
|
+
if bifurcationEvenHasCurves and bifurcationOddHasCurves and (bifurcationEvenFinalZero or bifurcationOddFinalZero):
|
|
47
|
+
XOrHere2makePair = 0b1
|
|
48
|
+
findUnpairedBinary1 = 0
|
|
49
|
+
|
|
50
|
+
if bifurcationEvenFinalZero and not bifurcationOddFinalZero:
|
|
51
|
+
while findUnpairedBinary1 >= 0:
|
|
52
|
+
XOrHere2makePair <<= 2
|
|
53
|
+
findUnpairedBinary1 += 1 if (bifurcationEven & XOrHere2makePair) == 0 else -1
|
|
54
|
+
bifurcationEven ^= XOrHere2makePair
|
|
55
|
+
|
|
56
|
+
elif bifurcationOddFinalZero and not bifurcationEvenFinalZero:
|
|
57
|
+
while findUnpairedBinary1 >= 0:
|
|
58
|
+
XOrHere2makePair <<= 2
|
|
59
|
+
findUnpairedBinary1 += 1 if (bifurcationOdd & XOrHere2makePair) == 0 else -1
|
|
60
|
+
bifurcationOdd ^= XOrHere2makePair
|
|
61
|
+
|
|
62
|
+
curveLocationAnalysis = ((bifurcationEven >> 2) << 1) | (bifurcationOdd >> 2)
|
|
63
|
+
recordAnalysis(curveLocationAnalysis, curveLocationsMAXIMUM, distinctCrossings)
|
|
64
|
+
|
|
65
|
+
def initializeCurveLocations(startingCurveLocations: dict[int, int]) -> None:
|
|
66
|
+
global dictionaryCurveLocations # noqa: PLW0603
|
|
67
|
+
dictionaryCurveLocations = {curve: [distinctCrossings] for curve, distinctCrossings in startingCurveLocations.items()}
|
|
68
|
+
|
|
69
|
+
def count(bridges: int, startingCurveLocations: dict[int, int]) -> int:
|
|
70
|
+
initializeCurveLocations(startingCurveLocations)
|
|
71
|
+
|
|
72
|
+
while bridges > 0:
|
|
73
|
+
bridges -= 1
|
|
74
|
+
|
|
75
|
+
# TODO This could be parallelized when `recordAnalysis` is thread-safe
|
|
76
|
+
for bifurcatedCurve in getCurveLocations(bridges):
|
|
77
|
+
analyzeCurve(*bifurcatedCurve)
|
|
78
|
+
|
|
79
|
+
return getCurveLocations(bridges)[0].distinctCrossings
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
from typing import NamedTuple
|
|
2
|
+
import sys
|
|
3
|
+
|
|
4
|
+
class limitLocators(NamedTuple):
|
|
5
|
+
curveLocationsMAXIMUM: int
|
|
6
|
+
bifurcationEvenLocator: int
|
|
7
|
+
bifurcationOddLocator: int
|
|
8
|
+
|
|
9
|
+
curveMaximum: dict[int, limitLocators] = {
|
|
10
|
+
0: limitLocators(16, 0x2a, 0x15),
|
|
11
|
+
1: limitLocators(64, 0xaa, 0x55),
|
|
12
|
+
2: limitLocators(256, 0x2aa, 0x155),
|
|
13
|
+
3: limitLocators(1024, 0xaaa, 0x555),
|
|
14
|
+
4: limitLocators(4096, 0x2aaa, 0x1555),
|
|
15
|
+
5: limitLocators(16384, 0xaaaa, 0x5555),
|
|
16
|
+
6: limitLocators(65536, 0x2aaaa, 0x15555),
|
|
17
|
+
7: limitLocators(262144, 0xaaaaa, 0x55555),
|
|
18
|
+
8: limitLocators(1048576, 0x2aaaaa, 0x155555),
|
|
19
|
+
9: limitLocators(4194304, 0xaaaaaa, 0x555555),
|
|
20
|
+
10: limitLocators(16777216, 0x2aaaaaa, 0x1555555),
|
|
21
|
+
11: limitLocators(67108864, 0xaaaaaaa, 0x5555555),
|
|
22
|
+
12: limitLocators(268435456, 0x2aaaaaaa, 0x15555555),
|
|
23
|
+
13: limitLocators(1073741824, 0xaaaaaaaa, 0x55555555),
|
|
24
|
+
14: limitLocators(4294967296, 0x2aaaaaaaa, 0x155555555),
|
|
25
|
+
15: limitLocators(17179869184, 0xaaaaaaaaa, 0x555555555),
|
|
26
|
+
16: limitLocators(68719476736, 0x2aaaaaaaaa, 0x1555555555),
|
|
27
|
+
17: limitLocators(274877906944, 0xaaaaaaaaaa, 0x5555555555),
|
|
28
|
+
18: limitLocators(1099511627776, 0x2aaaaaaaaaa, 0x15555555555),
|
|
29
|
+
19: limitLocators(4398046511104, 0xaaaaaaaaaaa, 0x55555555555),
|
|
30
|
+
20: limitLocators(17592186044416, 0x2aaaaaaaaaaa, 0x155555555555),
|
|
31
|
+
21: limitLocators(70368744177664, 0xaaaaaaaaaaaa, 0x555555555555),
|
|
32
|
+
22: limitLocators(281474976710656, 0x2aaaaaaaaaaaa, 0x1555555555555),
|
|
33
|
+
23: limitLocators(1125899906842624, 0xaaaaaaaaaaaaa, 0x5555555555555),
|
|
34
|
+
24: limitLocators(4503599627370496, 0x2aaaaaaaaaaaaa, 0x15555555555555),
|
|
35
|
+
25: limitLocators(18014398509481984, 0xaaaaaaaaaaaaaa, 0x55555555555555),
|
|
36
|
+
26: limitLocators(72057594037927936, 0x2aaaaaaaaaaaaaa, 0x155555555555555),
|
|
37
|
+
27: limitLocators(288230376151711744, 0xaaaaaaaaaaaaaaa, 0x555555555555555),
|
|
38
|
+
28: limitLocators(1152921504606846976, 0x2aaaaaaaaaaaaaaa, 0x1555555555555555), # 0x2aaaaaaaaaaaaaaa.bit_length() = 62
|
|
39
|
+
29: limitLocators(4611686018427387904, 0xaaaaaaaaaaaaaaaa, 0x5555555555555555),
|
|
40
|
+
30: limitLocators(18446744073709551616, 0x2aaaaaaaaaaaaaaaa, 0x15555555555555555),
|
|
41
|
+
31: limitLocators(73786976294838206464, 0xaaaaaaaaaaaaaaaaa, 0x55555555555555555),
|
|
42
|
+
32: limitLocators(295147905179352825856, 0x2aaaaaaaaaaaaaaaaa, 0x155555555555555555),
|
|
43
|
+
33: limitLocators(1180591620717411303424, 0xaaaaaaaaaaaaaaaaaa, 0x555555555555555555),
|
|
44
|
+
34: limitLocators(4722366482869645213696, 0x2aaaaaaaaaaaaaaaaaa, 0x1555555555555555555),
|
|
45
|
+
35: limitLocators(18889465931478580854784, 0xaaaaaaaaaaaaaaaaaaa, 0x5555555555555555555),
|
|
46
|
+
36: limitLocators(75557863725914323419136, 0x2aaaaaaaaaaaaaaaaaaa, 0x15555555555555555555),
|
|
47
|
+
37: limitLocators(302231454903657293676544, 0xaaaaaaaaaaaaaaaaaaaa, 0x55555555555555555555),
|
|
48
|
+
38: limitLocators(1208925819614629174706176, 0x2aaaaaaaaaaaaaaaaaaaa, 0x155555555555555555555),
|
|
49
|
+
39: limitLocators(4835703278458516698824704, 0xaaaaaaaaaaaaaaaaaaaaa, 0x555555555555555555555),
|
|
50
|
+
40: limitLocators(19342813113834066795298816, 0x2aaaaaaaaaaaaaaaaaaaaa, 0x1555555555555555555555),
|
|
51
|
+
41: limitLocators(77371252455336267181195264, 0xaaaaaaaaaaaaaaaaaaaaaa, 0x5555555555555555555555),
|
|
52
|
+
42: limitLocators(309485009821345068724781056, 0x2aaaaaaaaaaaaaaaaaaaaaa, 0x15555555555555555555555),
|
|
53
|
+
43: limitLocators(1237940039285380274899124224, 0xaaaaaaaaaaaaaaaaaaaaaaa, 0x55555555555555555555555),
|
|
54
|
+
44: limitLocators(4951760157141521099596496896, 0x2aaaaaaaaaaaaaaaaaaaaaaa, 0x155555555555555555555555),
|
|
55
|
+
45: limitLocators(19807040628566084398385987584, 0xaaaaaaaaaaaaaaaaaaaaaaaa, 0x555555555555555555555555),
|
|
56
|
+
46: limitLocators(79228162514264337593543950336, 0x2aaaaaaaaaaaaaaaaaaaaaaaa, 0x1555555555555555555555555),
|
|
57
|
+
47: limitLocators(316912650057057350374175801344, 0xaaaaaaaaaaaaaaaaaaaaaaaaa, 0x5555555555555555555555555),
|
|
58
|
+
48: limitLocators(1267650600228229401496703205376, 0x2aaaaaaaaaaaaaaaaaaaaaaaaa, 0x15555555555555555555555555),
|
|
59
|
+
49: limitLocators(5070602400912917605986812821504, 0xaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x55555555555555555555555555),
|
|
60
|
+
50: limitLocators(20282409603651670423947251286016, 0x2aaaaaaaaaaaaaaaaaaaaaaaaaa, 0x155555555555555555555555555),
|
|
61
|
+
51: limitLocators(81129638414606681695789005144064, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x555555555555555555555555555),
|
|
62
|
+
52: limitLocators(324518553658426726783156020576256, 0x2aaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x1555555555555555555555555555),
|
|
63
|
+
53: limitLocators(1298074214633706907132624082305024, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x5555555555555555555555555555),
|
|
64
|
+
54: limitLocators(5192296858534827628530496329220096, 0x2aaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x15555555555555555555555555555),
|
|
65
|
+
55: limitLocators(20769187434139310514121985316880384, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x55555555555555555555555555555),
|
|
66
|
+
56: limitLocators(83076749736557242056487941267521536, 0x2aaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x155555555555555555555555555555),
|
|
67
|
+
57: limitLocators(332306998946228968225951765070086144, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x555555555555555555555555555555),
|
|
68
|
+
58: limitLocators(1329227995784915872903807060280344576, 0x2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x1555555555555555555555555555555),
|
|
69
|
+
59: limitLocators(5316911983139663491615228241121378304, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x5555555555555555555555555555555),
|
|
70
|
+
60: limitLocators(21267647932558653966460912964485513216, 0x2aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x15555555555555555555555555555555),
|
|
71
|
+
61: limitLocators(85070591730234615865843651857942052864, 0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa, 0x55555555555555555555555555555555),
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
def makeCurveMaximum() -> None:
|
|
75
|
+
sys.stdout.write("curveMaximum: dict[int, limitLocators] = {\n")
|
|
76
|
+
for n in range(62):
|
|
77
|
+
curveLocationsMAXIMUM = 1 << (2 * n + 4)
|
|
78
|
+
bifurcationOddLocator = int('01' * ((curveLocationsMAXIMUM.bit_length() + 1) // 2), 2)
|
|
79
|
+
sys.stdout.write(f"{n}: limitLocators({curveLocationsMAXIMUM}, {hex(bifurcationOddLocator << 1)}, {hex(bifurcationOddLocator)}),\n")
|
|
80
|
+
sys.stdout.write("}\n")
|
|
81
|
+
|
|
82
|
+
if __name__ == '__main__':
|
|
83
|
+
makeCurveMaximum()
|
|
84
|
+
|
mapFolding/_theSSOT.py
CHANGED
|
@@ -1,36 +1,31 @@
|
|
|
1
|
-
"""
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
(AI generated docstring)
|
|
5
|
-
|
|
6
|
-
This module establishes the fundamental configuration infrastructure that underpins
|
|
7
|
-
all map folding operations. Map folding, as defined by Lunnon's 1971 algorithm,
|
|
8
|
-
requires precise coordination of computational resources, type systems, and data
|
|
9
|
-
flow management to solve the complex combinatorial problem of counting distinct
|
|
10
|
-
folding patterns across multi-dimensional maps.
|
|
11
|
-
|
|
12
|
-
The Single Source Of Truth (SSOT) principle governs this foundation, ensuring that
|
|
13
|
-
package identity, filesystem locations, and concurrency configuration remain
|
|
14
|
-
consistent across all computational phases. During packaging, static metadata is
|
|
15
|
-
resolved from pyproject.toml. During installation, filesystem-dependent paths are
|
|
16
|
-
dynamically discovered. During runtime, the `packageSettings` instance provides
|
|
17
|
-
unified access to all configuration values, enabling the sophisticated computational
|
|
18
|
-
framework that follows.
|
|
19
|
-
|
|
20
|
-
This configuration foundation supports the type system definition, core utility
|
|
21
|
-
functions, computational state management, result persistence, and ultimately the
|
|
22
|
-
main computational interface that users interact with to solve map folding problems.
|
|
1
|
+
"""Primary goal: access and configure package settings and metadata.
|
|
2
|
+
|
|
3
|
+
Secondary goal: store hardcoded values until I implement a dynamic solution.
|
|
23
4
|
"""
|
|
24
5
|
|
|
6
|
+
from collections.abc import Callable
|
|
25
7
|
from hunterMakesPy import PackageSettings
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import TypedDict
|
|
26
10
|
import dataclasses
|
|
11
|
+
import random
|
|
27
12
|
|
|
28
|
-
|
|
29
|
-
"""Hardcoded package name used as fallback when dynamic resolution fails."""
|
|
30
|
-
|
|
13
|
+
# TODO eliminate hardcoding
|
|
31
14
|
concurrencyPackageHARDCODED = 'multiprocessing'
|
|
32
15
|
"""Default package identifier for concurrent execution operations."""
|
|
33
16
|
|
|
17
|
+
class MetadataOEISidManuallySet(TypedDict):
|
|
18
|
+
"""Settings that are best selected by a human instead of algorithmically."""
|
|
19
|
+
|
|
20
|
+
getMapShape: Callable[[int], tuple[int, ...]]
|
|
21
|
+
"""Function to convert the OEIS sequence index, 'n', to its `mapShape` tuple."""
|
|
22
|
+
valuesBenchmark: list[int]
|
|
23
|
+
"""List of index values, 'n', to use when benchmarking the algorithm performance."""
|
|
24
|
+
valuesTestParallelization: list[int]
|
|
25
|
+
"""List of index values, 'n', to use when testing parallelization performance."""
|
|
26
|
+
valuesTestValidation: list[int]
|
|
27
|
+
"""List of index values, 'n', to use when testing validation performance."""
|
|
28
|
+
|
|
34
29
|
@dataclasses.dataclass
|
|
35
30
|
class mapFoldingPackageSettings(PackageSettings):
|
|
36
31
|
"""Centralized configuration container for all package-wide settings.
|
|
@@ -72,10 +67,57 @@ class mapFoldingPackageSettings(PackageSettings):
|
|
|
72
67
|
specialized numerical computations.
|
|
73
68
|
"""
|
|
74
69
|
|
|
70
|
+
identifierPackageFALLBACK = "mapFolding"
|
|
71
|
+
"""Hardcoded package name used as fallback when dynamic resolution fails."""
|
|
72
|
+
|
|
75
73
|
concurrencyPackage = concurrencyPackageHARDCODED
|
|
76
74
|
"""Active concurrency package configuration for the current session."""
|
|
77
75
|
|
|
76
|
+
# TODO I made a `TypedDict` before I knew how to make dataclasses and classes. Think about other data structures.
|
|
77
|
+
settingsOEISManuallySelected: dict[str, MetadataOEISidManuallySet] = {
|
|
78
|
+
'A000136': {
|
|
79
|
+
'getMapShape': lambda n: tuple(sorted([1, n])),
|
|
80
|
+
'valuesBenchmark': [14],
|
|
81
|
+
'valuesTestParallelization': [*range(3, 7)],
|
|
82
|
+
'valuesTestValidation': [random.randint(2, 9)], # noqa: S311
|
|
83
|
+
},
|
|
84
|
+
'A001415': {
|
|
85
|
+
'getMapShape': lambda n: tuple(sorted([2, n])),
|
|
86
|
+
'valuesBenchmark': [14],
|
|
87
|
+
'valuesTestParallelization': [*range(3, 7)],
|
|
88
|
+
'valuesTestValidation': [random.randint(2, 9)], # noqa: S311
|
|
89
|
+
},
|
|
90
|
+
'A001416': {
|
|
91
|
+
'getMapShape': lambda n: tuple(sorted([3, n])),
|
|
92
|
+
'valuesBenchmark': [9],
|
|
93
|
+
'valuesTestParallelization': [*range(3, 5)],
|
|
94
|
+
'valuesTestValidation': [random.randint(2, 6)], # noqa: S311
|
|
95
|
+
},
|
|
96
|
+
'A001417': {
|
|
97
|
+
'getMapShape': lambda n: tuple(2 for _dimension in range(n)),
|
|
98
|
+
'valuesBenchmark': [6],
|
|
99
|
+
'valuesTestParallelization': [*range(2, 4)],
|
|
100
|
+
'valuesTestValidation': [random.randint(2, 4)], # noqa: S311
|
|
101
|
+
},
|
|
102
|
+
'A195646': {
|
|
103
|
+
'getMapShape': lambda n: tuple(3 for _dimension in range(n)),
|
|
104
|
+
'valuesBenchmark': [3],
|
|
105
|
+
'valuesTestParallelization': [*range(2, 3)],
|
|
106
|
+
'valuesTestValidation': [2],
|
|
107
|
+
},
|
|
108
|
+
'A001418': {
|
|
109
|
+
'getMapShape': lambda n: (n, n),
|
|
110
|
+
'valuesBenchmark': [5],
|
|
111
|
+
'valuesTestParallelization': [*range(2, 4)],
|
|
112
|
+
'valuesTestValidation': [random.randint(2, 4)], # noqa: S311
|
|
113
|
+
},
|
|
114
|
+
}
|
|
115
|
+
|
|
78
116
|
packageSettings = mapFoldingPackageSettings(
|
|
79
|
-
identifierPackageFALLBACK=
|
|
117
|
+
identifierPackageFALLBACK=identifierPackageFALLBACK
|
|
80
118
|
, concurrencyPackage=concurrencyPackage)
|
|
81
119
|
"""Global package settings."""
|
|
120
|
+
cacheDays = 30
|
|
121
|
+
"""Number of days to retain cached OEIS data before refreshing from the online source."""
|
|
122
|
+
pathCache: Path = packageSettings.pathPackage / ".cache"
|
|
123
|
+
"""Local directory path for storing cached OEIS sequence data and metadata."""
|
mapFolding/basecamp.py
CHANGED
|
@@ -96,9 +96,9 @@ def countFolds(listDimensions: Sequence[int] | None = None # noqa: C901, PLR091
|
|
|
96
96
|
pass
|
|
97
97
|
else:
|
|
98
98
|
if oeisID and oeis_n:
|
|
99
|
-
from mapFolding.oeis import
|
|
99
|
+
from mapFolding.oeis import dictionaryOEIS # noqa: PLC0415
|
|
100
100
|
with contextlib.suppress(KeyError):
|
|
101
|
-
mapShape =
|
|
101
|
+
mapShape = dictionaryOEIS[oeisID]['getMapShape'](oeis_n)
|
|
102
102
|
if not mapShape and listDimensions:
|
|
103
103
|
mapShape = validateListDimensions(listDimensions)
|
|
104
104
|
|
mapFolding/beDRY.py
CHANGED
|
@@ -319,7 +319,7 @@ def validateListDimensions(listDimensions: Sequence[int]) -> tuple[int, ...]:
|
|
|
319
319
|
message = f"I received `{dimension = }` in `{listDimensions = }`, but all dimensions must be a non-negative integer."
|
|
320
320
|
raise ValueError(message)
|
|
321
321
|
mapDimensions.append(dimension)
|
|
322
|
-
if len(mapDimensions) < 2:
|
|
322
|
+
if len(mapDimensions) < 2:
|
|
323
323
|
message = f"This function requires `{listDimensions = }` to have at least two dimensions greater than 0. You may want to look at https://oeis.org/."
|
|
324
324
|
raise NotImplementedError(message)
|
|
325
325
|
|