mapFolding 0.14.0__py3-none-any.whl → 0.15.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. mapFolding/_A007822.py +181 -0
  2. mapFolding/__init__.py +1 -1
  3. mapFolding/_oeisFormulas/A000682.py +2 -2
  4. mapFolding/_oeisFormulas/Z0Z_aOFn.py +7 -5
  5. mapFolding/_oeisFormulas/Z0Z_oeisMeanders.py +2 -0
  6. mapFolding/_oeisFormulas/matrixMeanders.py +122 -61
  7. mapFolding/_oeisFormulas/matrixMeandersAnnex.py +66 -66
  8. mapFolding/_theSSOT.py +9 -3
  9. mapFolding/_theTypes.py +34 -130
  10. mapFolding/basecamp.py +1 -1
  11. mapFolding/beDRY.py +5 -21
  12. mapFolding/dataBaskets.py +8 -3
  13. mapFolding/oeis.py +13 -15
  14. mapFolding/reference/A005316optimized128bit.py +19 -19
  15. mapFolding/reference/A005316primitiveOptimized.py +25 -25
  16. mapFolding/reference/A005316redis.py +19 -19
  17. mapFolding/reference/A005316write2disk.py +19 -19
  18. mapFolding/reference/matrixMeandersBaseline.py +20 -20
  19. mapFolding/reference/matrixMeandersBaselineAnnex.py +4 -4
  20. mapFolding/reference/matrixMeandersSimpleQueue.py +90 -0
  21. mapFolding/reference/matrixMeandersSlicePop.py +104 -0
  22. mapFolding/someAssemblyRequired/_toolkitContainers.py +1 -1
  23. mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +1 -1
  24. mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +1 -1
  25. mapFolding/syntheticModules/countParallel.py +7 -4
  26. mapFolding/syntheticModules/daoOfMapFolding.py +6 -4
  27. mapFolding/syntheticModules/dataPacking.py +5 -3
  28. mapFolding/syntheticModules/theorem2Numba.py +4 -3
  29. {mapfolding-0.14.0.dist-info → mapfolding-0.15.0.dist-info}/METADATA +4 -5
  30. {mapfolding-0.14.0.dist-info → mapfolding-0.15.0.dist-info}/RECORD +34 -31
  31. {mapfolding-0.14.0.dist-info → mapfolding-0.15.0.dist-info}/WHEEL +0 -0
  32. {mapfolding-0.14.0.dist-info → mapfolding-0.15.0.dist-info}/entry_points.txt +0 -0
  33. {mapfolding-0.14.0.dist-info → mapfolding-0.15.0.dist-info}/licenses/LICENSE +0 -0
  34. {mapfolding-0.14.0.dist-info → mapfolding-0.15.0.dist-info}/top_level.txt +0 -0
mapFolding/_theTypes.py CHANGED
@@ -1,148 +1,52 @@
1
- """
2
- Type system architecture for map folding computational domains.
3
-
4
- (AI generated docstring)
5
-
6
- Building upon the configuration foundation, this module defines the complete type
7
- hierarchy that ensures type safety and semantic clarity throughout the map folding
8
- computational framework. The type system recognizes three distinct computational
9
- domains, each with specific data characteristics and performance requirements
10
- that emerge from Lunnon's algorithm implementation.
11
-
12
- The Leaves domain handles map sections, their indices, and dimensional parameters.
13
- The Elephino domain manages internal computational state, gap calculations, and
14
- temporary indices used during the recursive folding analysis. The Folds domain
15
- represents final pattern counts and computation results. Each domain employs both
16
- Python types for general computation and NumPy types for performance-critical
17
- array operations.
18
-
19
- This dual-type strategy enables the core utility functions to operate with type
20
- safety while maintaining the computational efficiency required for analyzing
21
- complex multi-dimensional folding patterns. The array types built from these
22
- base types provide the structured data containers that computational state
23
- management depends upon.
24
- """
25
- from numpy import dtype, integer, ndarray, uint8 as numpy_uint8, uint16 as numpy_uint16, uint64 as numpy_uint64
1
+ """Types for defensive coding and for computation optimization."""
2
+
3
+ from numpy import dtype, int_ as numpy_int, integer, ndarray, uint64 as numpy_uint64
26
4
  from typing import Any, TypeAlias, TypeVar
27
5
 
28
6
  NumPyIntegerType = TypeVar('NumPyIntegerType', bound=integer[Any], covariant=True)
29
- """
30
- Generic type variable for NumPy integer types used in computational operations.
31
-
32
- (AI generated docstring)
33
-
34
- This type variable enables generic programming with NumPy integer types while
35
- maintaining type safety. It supports covariant relationships between different
36
- NumPy integer types and their array containers.
37
- """
38
-
39
- DatatypeLeavesTotal: TypeAlias = int
40
- """
41
- Python type for leaf-related counts and indices in map folding computations.
42
-
43
- (AI generated docstring)
44
-
45
- Represents quantities related to individual map sections (leaves), including
46
- total leaf counts, leaf indices, and dimensional parameters. Uses standard
47
- Python integers for compatibility with general computations while enabling
48
- conversion to NumPy types when performance optimization is needed.
49
- """
50
-
51
- NumPyLeavesTotal: TypeAlias = numpy_uint8
52
- """
53
- NumPy type for efficient leaf-related computations and array operations.
54
-
55
- (AI generated docstring)
56
-
57
- Corresponds to `DatatypeLeavesTotal` but optimized for NumPy operations.
58
- Uses 8-bit unsigned integers since leaf counts in practical map folding
59
- scenarios typically remain small (under 256).
60
- """
61
-
62
- DatatypeElephino: TypeAlias = int
63
- """
64
- Python type for internal computational indices and intermediate values.
65
-
66
- (AI generated docstring)
67
-
68
- Used for temporary variables, gap indices, and other internal computational
69
- state that doesn't directly correspond to leaves or final fold counts. The
70
- name follows the package convention for internal computational domains.
71
- """
7
+ """Any NumPy integer type, which is usually between 8-bit signed and 64-bit unsigned."""
72
8
 
73
- NumPyElephino: TypeAlias = numpy_uint16
74
- """
75
- NumPy type for internal computational operations requiring moderate value ranges.
9
+ DatatypeLeavesTotal: TypeAlias = int # noqa: UP040 The TypeAlias may be used to construct ("cast") a value to the type. And the identifier may be changed to a different type.
10
+ """Use on unsigned integers that will never exceed the magnitude of `leavesTotal`."""
76
11
 
77
- (AI generated docstring)
12
+ NumPyLeavesTotal: TypeAlias = numpy_int # noqa: UP040 The TypeAlias may be used to construct ("cast") a value to the type. And the identifier may be changed to a different type.
13
+ """Use in NumPy data structures whose elements are unsigned integers that will never exceed the magnitude of `leavesTotal`."""
78
14
 
79
- Corresponds to `DatatypeElephino` with 16-bit unsigned integer storage,
80
- providing sufficient range for internal computations while maintaining
81
- memory efficiency in array operations.
82
- """
15
+ DatatypeElephino: TypeAlias = int # noqa: UP040 The TypeAlias may be used to construct ("cast") a value to the type. And the identifier may be changed to a different type.
16
+ """Use on unsigned integers that will exceed the magnitude of `leavesTotal` but that are not "colossal."
83
17
 
84
- DatatypeFoldsTotal: TypeAlias = int
85
- """
86
- Python type for final fold counts and pattern totals.
18
+ Note well
19
+ ---------
20
+ Colossal values are found with the cross humpy inequality:
87
21
 
88
- (AI generated docstring)
22
+ el ⎤ ⎡ ⎤
23
+ ⎢ eph ⎥ X ⎢ rhi ⎥ <= elephino
24
+ ⎣ ant ⎦ ⎣ no ⎦
89
25
 
90
- Represents the ultimate results of map folding computations - the total number
91
- of distinct folding patterns possible for a given map configuration. These
92
- values can grow exponentially with map size, requiring flexible integer types.
93
26
  """
94
27
 
95
- NumPyFoldsTotal: TypeAlias = numpy_uint64
96
- """
97
- NumPy type for large fold count computations and high-precision results.
28
+ NumPyElephino: TypeAlias = numpy_int # noqa: UP040 The TypeAlias may be used to construct ("cast") a value to the type. And the identifier may be changed to a different type.
29
+ """Use in NumPy data structures whose elements are unsigned integers that might exceed the magnitude of `leavesTotal` but that are not 'colossal.'"""
98
30
 
99
- (AI generated docstring)
31
+ DatatypeFoldsTotal: TypeAlias = int # noqa: UP040 The TypeAlias may be used to construct ("cast") a value to the type. And the identifier may be changed to a different type.
32
+ """Use on unsigned integers that might have colossal magnitudes similar to `foldsTotal`."""
100
33
 
101
- Corresponds to `DatatypeFoldsTotal` using 64-bit unsigned integers to
102
- accommodate the exponentially large values that can result from map folding
103
- computations on even moderately-sized maps.
104
- """
34
+ NumPyFoldsTotal: TypeAlias = numpy_uint64 # noqa: UP040 The TypeAlias may be used to construct ("cast") a value to the type. And the identifier may be changed to a different type.
35
+ """Use in NumPy data structures whose elements are unsigned integers that might have colossal magnitudes similar to `foldsTotal`.
105
36
 
106
- Array3D: TypeAlias = ndarray[tuple[int, int, int], dtype[NumPyLeavesTotal]]
107
- """
108
- Three-dimensional NumPy array type for connection graph representations.
37
+ Note well
38
+ ---------
39
+ If your elements might exceed 1.8 × 10^19, then you should take extra steps to ensure the integrity of the data in NumPy or use a
40
+ different data structure."""
109
41
 
110
- (AI generated docstring)
42
+ Array3DLeavesTotal: TypeAlias = ndarray[tuple[int, int, int], dtype[NumPyLeavesTotal]] # noqa: UP040 The TypeAlias may be used to construct ("cast") a value to the type. And the identifier may be changed to a different type.
43
+ """A `numpy.ndarray` with three axes and elements of type `NumPyLeavesTotal`."""
111
44
 
112
- Used to store the connectivity relationships between map leaves in a
113
- 3D array structure. The array uses `NumPyLeavesTotal` element type since
114
- the stored values represent leaf indices and connection states.
115
- """
45
+ Array1DLeavesTotal: TypeAlias = ndarray[tuple[int], dtype[NumPyLeavesTotal]] # noqa: UP040 The TypeAlias may be used to construct ("cast") a value to the type. And the identifier may be changed to a different type.
46
+ """A `numpy.ndarray` with one axis and elements of type `NumPyLeavesTotal`."""
116
47
 
117
- Array1DLeavesTotal: TypeAlias = ndarray[tuple[int], dtype[NumPyLeavesTotal]]
118
- """
119
- One-dimensional NumPy array type for leaf-related data sequences.
48
+ Array1DElephino: TypeAlias = ndarray[tuple[int], dtype[NumPyElephino]] # noqa: UP040 The TypeAlias may be used to construct ("cast") a value to the type. And the identifier may be changed to a different type.
49
+ """A `numpy.ndarray` with one axis and elements of type `NumPyElephino`."""
120
50
 
121
- (AI generated docstring)
122
-
123
- Stores sequences of leaf counts, indices, or related values in efficient
124
- array format. Common uses include leaf sequences, gap locations, and
125
- dimensional data where each element relates to the leaves domain.
126
- """
127
-
128
- Array1DElephino: TypeAlias = ndarray[tuple[int], dtype[NumPyElephino]]
129
- """
130
- One-dimensional NumPy array type for internal computational sequences.
131
-
132
- (AI generated docstring)
133
-
134
- Used for storing sequences of internal computational values such as
135
- gap range starts, temporary indices, and other intermediate results
136
- that require the elephino computational domain's value range.
137
- """
138
-
139
- Array1DFoldsTotal: TypeAlias = ndarray[tuple[int], dtype[NumPyFoldsTotal]]
140
- """
141
- One-dimensional NumPy array type for sequences of fold count results.
142
-
143
- (AI generated docstring)
144
-
145
- Stores sequences of fold totals and pattern counts, using the large
146
- integer type to accommodate the potentially enormous values that
147
- result from complex map folding computations.
148
- """
51
+ Array1DFoldsTotal: TypeAlias = ndarray[tuple[int], dtype[NumPyFoldsTotal]] # noqa: UP040 The TypeAlias may be used to construct ("cast") a value to the type. And the identifier may be changed to a different type.
52
+ """A `numpy.ndarray` with one axis and elements of type `NumPyFoldsTotal`."""
mapFolding/basecamp.py CHANGED
@@ -31,7 +31,7 @@ from os import PathLike
31
31
  from pathlib import PurePath
32
32
  import contextlib
33
33
 
34
- def countFolds(listDimensions: Sequence[int] | None = None # noqa: C901, PLR0912, PLR0915
34
+ def countFolds(listDimensions: Sequence[int] | None = None
35
35
  , pathLikeWriteFoldsTotal: PathLike[str] | PurePath | None = None
36
36
  , computationDivisions: int | str | None = None
37
37
  # , * # TODO improve `standardizedEqualToCallableReturn` so it will work with keyword arguments
mapFolding/beDRY.py CHANGED
@@ -121,12 +121,6 @@ def getTaskDivisions(computationDivisions: int | str | None, concurrencyLimit: i
121
121
  def _makeConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int) -> ndarray[tuple[int, int, int], numpy_dtype[numpy_int64]]:
122
122
  """Implement connection graph generation for map folding.
123
123
 
124
- (AI generated docstring)
125
-
126
- This is the internal implementation that calculates all possible connections between leaves in a map folding problem
127
- based on Lunnon's algorithm. The function constructs a three-dimensional array representing which leaves can be
128
- connected to each other for each dimension of the map.
129
-
130
124
  Parameters
131
125
  ----------
132
126
  mapShape : tuple[int, ...]
@@ -177,12 +171,6 @@ def _makeConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int) -> ndarray
177
171
  def getConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int, datatype: type[NumPyIntegerType]) -> ndarray[tuple[int, int, int], numpy_dtype[NumPyIntegerType]]:
178
172
  """Create a properly typed connection graph for the map folding algorithm.
179
173
 
180
- (AI generated docstring)
181
-
182
- This function serves as a typed wrapper around the internal implementation that generates connection graphs. It
183
- provides the correct type information for the returned array, ensuring consistency throughout the computation
184
- assembly-line.
185
-
186
174
  Parameters
187
175
  ----------
188
176
  mapShape : tuple[int, ...]
@@ -204,25 +192,21 @@ def getConnectionGraph(mapShape: tuple[int, ...], leavesTotal: int, datatype: ty
204
192
  return connectionGraph.astype(datatype)
205
193
 
206
194
  def makeDataContainer(shape: int | tuple[int, ...], datatype: type[NumPyIntegerType]) -> ndarray[Any, numpy_dtype[NumPyIntegerType]]:
207
- """Create a typed NumPy array container with initialized values.
208
-
209
- (AI generated docstring)
195
+ """Create any data container as long as it is a `numpy.ndarray` full of zeroes of type `numpy.integer`.
210
196
 
211
- This function centralizes the creation of data containers used throughout the computation assembly-line, enabling
212
- easy switching between different container types or implementation strategies if needed in the future.
197
+ By centralizing data container creation, you can more easily make global changes.
213
198
 
214
199
  Parameters
215
200
  ----------
216
201
  shape : int | tuple[int, ...]
217
- Either an integer (for 1D arrays) or a tuple of integers (for multi-dimensional arrays) specifying the
218
- dimensions of the array.
202
+ The array shape, either as a single axis length or a tuple of axes lengths.
219
203
  datatype : type[NumPyIntegerType]
220
- The NumPy integer type to use for the array elements, ensuring proper type consistency and memory efficiency.
204
+ The `numpy.integer` type for the array elements.
221
205
 
222
206
  Returns
223
207
  -------
224
208
  container : ndarray[Any, numpy_dtype[NumPyIntegerType]]
225
- A NumPy array of zeros with the specified shape and `datatype`.
209
+ A zero-filled `ndarray` with the specified `shape` and `datatype`.
226
210
 
227
211
  """
228
212
  return numpy.zeros(shape, dtype=datatype)
mapFolding/dataBaskets.py CHANGED
@@ -21,7 +21,7 @@ integrity throughout the recursive analysis while providing the structured data
21
21
  access patterns that enable efficient result persistence and retrieval.
22
22
  """
23
23
  from mapFolding import (
24
- Array1DElephino, Array1DLeavesTotal, Array3D, DatatypeElephino, DatatypeFoldsTotal, DatatypeLeavesTotal,
24
+ Array1DElephino, Array1DLeavesTotal, Array3DLeavesTotal, DatatypeElephino, DatatypeFoldsTotal, DatatypeLeavesTotal,
25
25
  getConnectionGraph, getLeavesTotal, makeDataContainer)
26
26
  import dataclasses
27
27
 
@@ -63,7 +63,9 @@ class MapFoldingState:
63
63
  Array tracking the leaves above to the current leaf, `leaf1ndex`, during computation.
64
64
  leafBelow : Array1DLeavesTotal = None
65
65
  Array tracking the leaves below to the current leaf, `leaf1ndex`, during computation.
66
- connectionGraph : Array3D
66
+ leafComparison : Array1DLeavesTotal = None
67
+ Array for finding symmetric folds.
68
+ connectionGraph : Array3DLeavesTotal
67
69
  Unchanging array representing connections between all leaves.
68
70
  dimensionsTotal : DatatypeLeavesTotal
69
71
  Unchanging total number of dimensions in the map.
@@ -106,8 +108,10 @@ class MapFoldingState:
106
108
  """Array tracking the leaves above to the current leaf, `leaf1ndex`, during computation."""
107
109
  leafBelow: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
108
110
  """Array tracking the leaves below to the current leaf, `leaf1ndex`, during computation."""
111
+ leafComparison: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
112
+ """Array for finding symmetric folds."""
109
113
 
110
- connectionGraph: Array3D = dataclasses.field(init=False, metadata={'dtype': Array3D.__args__[1].__args__[0]}) # pyright: ignore[reportUnknownMemberType, reportAttributeAccessIssue]
114
+ connectionGraph: Array3DLeavesTotal = dataclasses.field(init=False, metadata={'dtype': Array3DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportUnknownMemberType, reportAttributeAccessIssue]
111
115
  """Unchanging array representing connections between all leaves."""
112
116
  dimensionsTotal: DatatypeLeavesTotal = dataclasses.field(init=False)
113
117
  """Unchanging total number of dimensions in the map."""
@@ -147,6 +151,7 @@ class MapFoldingState:
147
151
  if self.gapRangeStart is None: self.gapRangeStart = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['gapRangeStart'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
148
152
  if self.leafAbove is None: self.leafAbove = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafAbove'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
149
153
  if self.leafBelow is None: self.leafBelow = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafBelow'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
154
+ if self.leafComparison is None: self.leafComparison = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafComparison'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
150
155
 
151
156
  @dataclasses.dataclass
152
157
  class ParallelMapFoldingState(MapFoldingState):
mapFolding/oeis.py CHANGED
@@ -31,7 +31,7 @@ from itertools import chain
31
31
  from mapFolding import countFolds
32
32
  from mapFolding._theSSOT import cacheDays, pathCache, settingsOEISManuallySelected
33
33
  from pathlib import Path
34
- from typing import Any, Final, TypedDict
34
+ from typing import Final, TypedDict
35
35
  from urllib.request import urlopen
36
36
  import argparse
37
37
  import sys
@@ -331,8 +331,8 @@ def makeDictionaryFoldsTotalKnown() -> dict[tuple[int, ...], int]:
331
331
  of distinct folding patterns for those shapes.
332
332
 
333
333
  """
334
- return dict(chain.from_iterable(zip(map(oeisID['getMapShape'], oeisID['valuesKnown'].keys())
335
- , oeisID['valuesKnown'].values(), strict=True) for oeisID in dictionaryOEIS.values()))
334
+ return dict(chain.from_iterable(zip(map(oeisIDmetadata['getMapShape'], oeisIDmetadata['valuesKnown'].keys())
335
+ , oeisIDmetadata['valuesKnown'].values(), strict=True) for oeisID, oeisIDmetadata in dictionaryOEIS.items() if oeisID != 'A007822'))
336
336
 
337
337
  def getFoldsTotalKnown(mapShape: tuple[int, ...]) -> int:
338
338
  """Retrieve the known total number of distinct folding patterns for a given map shape.
@@ -410,26 +410,19 @@ def _formatOEISsequenceInfo() -> str:
410
410
  for oeisID in oeisIDsImplemented
411
411
  )
412
412
 
413
- def oeisIDfor_n(oeisID: str, n: int | Any) -> int:
414
- """Calculate the value a(n) for a specified OEIS sequence and index.
415
-
416
- (AI generated docstring)
417
-
418
- This function serves as the primary interface for computing OEIS sequence values within the map folding
419
- context. For small values or values within the known range, it returns cached OEIS data. For larger
420
- values, it computes the result using the map folding algorithm with the appropriate map shape derived
421
- from the sequence definition.
413
+ def oeisIDfor_n(oeisID: str, n: int) -> int:
414
+ """Calculate the value a(n) for a specified OEIS ID and index.
422
415
 
423
416
  Parameters
424
417
  ----------
425
418
  oeisID : str
426
419
  The identifier of the OEIS sequence to evaluate.
427
- n : int | Any
420
+ n : int
428
421
  A non-negative integer index for which to calculate the sequence value.
429
422
 
430
423
  Returns
431
424
  -------
432
- int
425
+ a(n) : int
433
426
  The value a(n) of the specified OEIS sequence.
434
427
 
435
428
  Raises
@@ -448,7 +441,7 @@ def oeisIDfor_n(oeisID: str, n: int | Any) -> int:
448
441
  message = f"I received `{n = }` in the form of `{type(n) = }`, but it must be non-negative integer in the form of `{int}`."
449
442
  raise ValueError(message)
450
443
 
451
- mapShape: tuple[int, ...] = dictionaryOEIS[oeisID]['getMapShape'](n)
444
+ mapShape = dictionaryOEIS[oeisID]['getMapShape'](n)
452
445
 
453
446
  if n <= 1 or len(mapShape) < 2:
454
447
  offset: int = dictionaryOEIS[oeisID]['offset']
@@ -457,6 +450,11 @@ def oeisIDfor_n(oeisID: str, n: int | Any) -> int:
457
450
  raise ArithmeticError(message)
458
451
  foldsTotal: int = dictionaryOEIS[oeisID]['valuesKnown'][n]
459
452
  return foldsTotal
453
+
454
+ if oeisID == 'A007822':
455
+ from mapFolding._A007822 import Z0Z_flowNeedsFixing # noqa: PLC0415
456
+ return Z0Z_flowNeedsFixing(mapShape)
457
+
460
458
  return countFolds(mapShape)
461
459
 
462
460
  def OEIS_for_n() -> None:
@@ -5,44 +5,44 @@ def count(bridges: int, dictionaryCurveLocationsKnown: dict[int, int]) -> int:
5
5
  dictionaryCurveLocationsDiscovered: dict[int, int] = {}
6
6
 
7
7
  for curveLocations, distinctCrossings in dictionaryCurveLocationsKnown.items():
8
- bifurcationOdd = curveLocations & 0x5555555555555555555555555555555555555555555555555555555555555555
9
- bifurcationEven = (curveLocations ^ bifurcationOdd) >> 1
8
+ bifurcationAlpha = curveLocations & 0x5555555555555555555555555555555555555555555555555555555555555555
9
+ bifurcationZulu = (curveLocations ^ bifurcationAlpha) >> 1
10
10
 
11
- bifurcationOddHasCurves = bifurcationOdd != 1
12
- bifurcationEvenHasCurves = bifurcationEven != 1
13
- bifurcationOddFinalZero = not bifurcationOdd & 1
14
- bifurcationEvenFinalZero = not bifurcationEven & 1
11
+ bifurcationAlphaHasCurves = bifurcationAlpha != 1
12
+ bifurcationZuluHasCurves = bifurcationZulu != 1
13
+ bifurcationAlphaFinalZero = not bifurcationAlpha & 1
14
+ bifurcationZuluFinalZero = not bifurcationZulu & 1
15
15
 
16
- if bifurcationOddHasCurves:
17
- curveLocationAnalysis = (bifurcationOdd >> 2) | (bifurcationEven << 3) | (bifurcationOddFinalZero << 1)
16
+ if bifurcationAlphaHasCurves:
17
+ curveLocationAnalysis = (bifurcationAlpha >> 2) | (bifurcationZulu << 3) | (bifurcationAlphaFinalZero << 1)
18
18
  if curveLocationAnalysis < curveLocationsMAXIMUM:
19
19
  dictionaryCurveLocationsDiscovered[curveLocationAnalysis] = dictionaryCurveLocationsDiscovered.get(curveLocationAnalysis, 0) + distinctCrossings
20
20
 
21
- if bifurcationEvenHasCurves:
22
- curveLocationAnalysis = (bifurcationEven >> 1) | (bifurcationOdd << 2) | bifurcationEvenFinalZero
21
+ if bifurcationZuluHasCurves:
22
+ curveLocationAnalysis = (bifurcationZulu >> 1) | (bifurcationAlpha << 2) | bifurcationZuluFinalZero
23
23
  if curveLocationAnalysis < curveLocationsMAXIMUM:
24
24
  dictionaryCurveLocationsDiscovered[curveLocationAnalysis] = dictionaryCurveLocationsDiscovered.get(curveLocationAnalysis, 0) + distinctCrossings
25
25
 
26
- curveLocationAnalysis = ((bifurcationOdd | (bifurcationEven << 1)) << 2) | 3
26
+ curveLocationAnalysis = ((bifurcationAlpha | (bifurcationZulu << 1)) << 2) | 3
27
27
  if curveLocationAnalysis < curveLocationsMAXIMUM:
28
28
  dictionaryCurveLocationsDiscovered[curveLocationAnalysis] = dictionaryCurveLocationsDiscovered.get(curveLocationAnalysis, 0) + distinctCrossings
29
29
 
30
- if bifurcationOddHasCurves and bifurcationEvenHasCurves and (bifurcationOddFinalZero or bifurcationEvenFinalZero):
30
+ if bifurcationAlphaHasCurves and bifurcationZuluHasCurves and (bifurcationAlphaFinalZero or bifurcationZuluFinalZero):
31
31
  XOrHere2makePair = 0b1
32
32
  findUnpairedBinary1 = 0
33
- if bifurcationOddFinalZero and not bifurcationEvenFinalZero:
33
+ if bifurcationAlphaFinalZero and not bifurcationZuluFinalZero:
34
34
  while findUnpairedBinary1 >= 0:
35
35
  XOrHere2makePair <<= 2
36
- findUnpairedBinary1 += 1 if (bifurcationOdd & XOrHere2makePair) == 0 else -1
37
- bifurcationOdd ^= XOrHere2makePair
36
+ findUnpairedBinary1 += 1 if (bifurcationAlpha & XOrHere2makePair) == 0 else -1
37
+ bifurcationAlpha ^= XOrHere2makePair
38
38
 
39
- elif bifurcationEvenFinalZero and not bifurcationOddFinalZero:
39
+ elif bifurcationZuluFinalZero and not bifurcationAlphaFinalZero:
40
40
  while findUnpairedBinary1 >= 0:
41
41
  XOrHere2makePair <<= 2
42
- findUnpairedBinary1 += 1 if (bifurcationEven & XOrHere2makePair) == 0 else -1
43
- bifurcationEven ^= XOrHere2makePair
42
+ findUnpairedBinary1 += 1 if (bifurcationZulu & XOrHere2makePair) == 0 else -1
43
+ bifurcationZulu ^= XOrHere2makePair
44
44
 
45
- curveLocationAnalysis = (bifurcationOdd >> 2) | ((bifurcationEven >> 2) << 1)
45
+ curveLocationAnalysis = (bifurcationAlpha >> 2) | ((bifurcationZulu >> 2) << 1)
46
46
  if curveLocationAnalysis < curveLocationsMAXIMUM:
47
47
  dictionaryCurveLocationsDiscovered[curveLocationAnalysis] = dictionaryCurveLocationsDiscovered.get(curveLocationAnalysis, 0) + distinctCrossings
48
48
 
@@ -1,5 +1,5 @@
1
- bifurcationOddLocator = 0x55555555555555555555555555555555
2
- bitWidth = 1 << (bifurcationOddLocator.bit_length() - 1).bit_length()
1
+ bifurcationAlphaLocator = 0x55555555555555555555555555555555
2
+ bitWidth = 1 << (bifurcationAlphaLocator.bit_length() - 1).bit_length()
3
3
 
4
4
  def count(bridges: int, dictionaryCurveLocationsKnown: dict[int, int]) -> int:
5
5
  while bridges > 0:
@@ -9,53 +9,53 @@ def count(bridges: int, dictionaryCurveLocationsKnown: dict[int, int]) -> int:
9
9
  dictionaryCurveLocationsDiscovered: dict[int, int] = {}
10
10
 
11
11
  for curveLocations, distinctCrossings in dictionaryCurveLocationsKnown.items():
12
- global bifurcationOddLocator, bitWidth # noqa: PLW0603
12
+ global bifurcationAlphaLocator, bitWidth # noqa: PLW0603
13
13
 
14
- if curveLocations > bifurcationOddLocator:
15
- while curveLocations > bifurcationOddLocator:
16
- bifurcationOddLocator |= bifurcationOddLocator << bitWidth
14
+ if curveLocations > bifurcationAlphaLocator:
15
+ while curveLocations > bifurcationAlphaLocator:
16
+ bifurcationAlphaLocator |= bifurcationAlphaLocator << bitWidth
17
17
  bitWidth <<= 1
18
18
 
19
- bifurcationOdd = curveLocations & bifurcationOddLocator
20
- bifurcationEven = (curveLocations ^ bifurcationOdd) >> 1
19
+ bifurcationAlpha = curveLocations & bifurcationAlphaLocator
20
+ bifurcationZulu = (curveLocations ^ bifurcationAlpha) >> 1
21
21
 
22
- bifurcationOddHasCurves = bifurcationOdd != 1
23
- bifurcationEvenHasCurves = bifurcationEven != 1
24
- bifurcationOddFinalZero = (bifurcationOdd & 1) == 0
25
- bifurcationEvenFinalZero = (bifurcationEven & 1) == 0
22
+ bifurcationAlphaHasCurves = bifurcationAlpha != 1
23
+ bifurcationZuluHasCurves = bifurcationZulu != 1
24
+ bifurcationAlphaFinalZero = (bifurcationAlpha & 1) == 0
25
+ bifurcationZuluFinalZero = (bifurcationZulu & 1) == 0
26
26
 
27
- if bifurcationOddHasCurves:
28
- curveLocationAnalysis = (bifurcationOdd >> 2) | (bifurcationEven << 3) | (bifurcationOddFinalZero << 1)
27
+ if bifurcationAlphaHasCurves:
28
+ curveLocationAnalysis = (bifurcationAlpha >> 2) | (bifurcationZulu << 3) | (bifurcationAlphaFinalZero << 1)
29
29
  if curveLocationAnalysis < curveLocationsMAXIMUM:
30
30
  dictionaryCurveLocationsDiscovered[curveLocationAnalysis] = dictionaryCurveLocationsDiscovered.get(curveLocationAnalysis, 0) + distinctCrossings
31
31
 
32
- if bifurcationEvenHasCurves:
33
- curveLocationAnalysis = (bifurcationEven >> 1) | ((bifurcationOdd << 2) | bifurcationEvenFinalZero)
32
+ if bifurcationZuluHasCurves:
33
+ curveLocationAnalysis = (bifurcationZulu >> 1) | ((bifurcationAlpha << 2) | bifurcationZuluFinalZero)
34
34
  if curveLocationAnalysis < curveLocationsMAXIMUM:
35
35
  dictionaryCurveLocationsDiscovered[curveLocationAnalysis] = dictionaryCurveLocationsDiscovered.get(curveLocationAnalysis, 0) + distinctCrossings
36
36
 
37
- curveLocationAnalysis = ((bifurcationOdd | (bifurcationEven << 1)) << 2) | 3
37
+ curveLocationAnalysis = ((bifurcationAlpha | (bifurcationZulu << 1)) << 2) | 3
38
38
  if curveLocationAnalysis < curveLocationsMAXIMUM:
39
39
  dictionaryCurveLocationsDiscovered[curveLocationAnalysis] = dictionaryCurveLocationsDiscovered.get(curveLocationAnalysis, 0) + distinctCrossings
40
40
 
41
- if bifurcationOddHasCurves and bifurcationEvenHasCurves and (bifurcationOddFinalZero or bifurcationEvenFinalZero):
42
- if bifurcationOddFinalZero and not bifurcationEvenFinalZero:
41
+ if bifurcationAlphaHasCurves and bifurcationZuluHasCurves and (bifurcationAlphaFinalZero or bifurcationZuluFinalZero):
42
+ if bifurcationAlphaFinalZero and not bifurcationZuluFinalZero:
43
43
  Z0Z_idk = 0
44
44
  Z0Z_indexIDK = 1
45
45
  while Z0Z_idk >= 0:
46
46
  Z0Z_indexIDK <<= 2
47
- Z0Z_idk += 1 if (bifurcationOdd & Z0Z_indexIDK) == 0 else -1
48
- bifurcationOdd ^= Z0Z_indexIDK
47
+ Z0Z_idk += 1 if (bifurcationAlpha & Z0Z_indexIDK) == 0 else -1
48
+ bifurcationAlpha ^= Z0Z_indexIDK
49
49
 
50
- if bifurcationEvenFinalZero and not bifurcationOddFinalZero:
50
+ if bifurcationZuluFinalZero and not bifurcationAlphaFinalZero:
51
51
  Z0Z_idk = 0
52
52
  Z0Z_indexIDK = 1
53
53
  while Z0Z_idk >= 0:
54
54
  Z0Z_indexIDK <<= 2
55
- Z0Z_idk += 1 if (bifurcationEven & Z0Z_indexIDK) == 0 else -1
56
- bifurcationEven ^= Z0Z_indexIDK
55
+ Z0Z_idk += 1 if (bifurcationZulu & Z0Z_indexIDK) == 0 else -1
56
+ bifurcationZulu ^= Z0Z_indexIDK
57
57
 
58
- curveLocationAnalysis = (bifurcationOdd >> 2) | ((bifurcationEven >> 2) << 1)
58
+ curveLocationAnalysis = (bifurcationAlpha >> 2) | ((bifurcationZulu >> 2) << 1)
59
59
  if curveLocationAnalysis < curveLocationsMAXIMUM:
60
60
  dictionaryCurveLocationsDiscovered[curveLocationAnalysis] = dictionaryCurveLocationsDiscovered.get(curveLocationAnalysis, 0) + distinctCrossings
61
61
 
@@ -34,41 +34,41 @@ def count(bridges: int, curveLocationsKnown: dict[int, int]) -> int:
34
34
  curveLocations = int(str(keyName).split(":")[1])
35
35
  distinctCrossings = int(str(redisClient.get(keyName)))
36
36
 
37
- bifurcationOdd = curveLocations & 0x5555555555555555555555555555555555555555555555555555555555555555
38
- bifurcationEven = (curveLocations ^ bifurcationOdd) >> 1
37
+ bifurcationAlpha = curveLocations & 0x5555555555555555555555555555555555555555555555555555555555555555
38
+ bifurcationZulu = (curveLocations ^ bifurcationAlpha) >> 1
39
39
 
40
- bifurcationOddHasCurves = bifurcationOdd != 1
41
- bifurcationEvenHasCurves = bifurcationEven != 1
42
- bifurcationOddFinalZero = not bifurcationOdd & 1
43
- bifurcationEvenFinalZero = not bifurcationEven & 1
40
+ bifurcationAlphaHasCurves = bifurcationAlpha != 1
41
+ bifurcationZuluHasCurves = bifurcationZulu != 1
42
+ bifurcationAlphaFinalZero = not bifurcationAlpha & 1
43
+ bifurcationZuluFinalZero = not bifurcationZulu & 1
44
44
 
45
- if bifurcationOddHasCurves:
46
- curveLocationAnalysis = (bifurcationOdd >> 2) | (bifurcationEven << 3) | (bifurcationOddFinalZero << 1)
45
+ if bifurcationAlphaHasCurves:
46
+ curveLocationAnalysis = (bifurcationAlpha >> 2) | (bifurcationZulu << 3) | (bifurcationAlphaFinalZero << 1)
47
47
  storeCurveLocations(curveLocationAnalysis, distinctCrossings)
48
48
 
49
- if bifurcationEvenHasCurves:
50
- curveLocationAnalysis = (bifurcationEven >> 1) | (bifurcationOdd << 2) | bifurcationEvenFinalZero
49
+ if bifurcationZuluHasCurves:
50
+ curveLocationAnalysis = (bifurcationZulu >> 1) | (bifurcationAlpha << 2) | bifurcationZuluFinalZero
51
51
  storeCurveLocations(curveLocationAnalysis, distinctCrossings)
52
52
 
53
- curveLocationAnalysis = ((bifurcationOdd | (bifurcationEven << 1)) << 2) | 3
53
+ curveLocationAnalysis = ((bifurcationAlpha | (bifurcationZulu << 1)) << 2) | 3
54
54
  storeCurveLocations(curveLocationAnalysis, distinctCrossings)
55
55
 
56
- if bifurcationOddHasCurves and bifurcationEvenHasCurves and (bifurcationOddFinalZero or bifurcationEvenFinalZero):
56
+ if bifurcationAlphaHasCurves and bifurcationZuluHasCurves and (bifurcationAlphaFinalZero or bifurcationZuluFinalZero):
57
57
  XOrHere2makePair = 0b1
58
58
  findUnpairedBinary1 = 0
59
- if bifurcationOddFinalZero and not bifurcationEvenFinalZero:
59
+ if bifurcationAlphaFinalZero and not bifurcationZuluFinalZero:
60
60
  while findUnpairedBinary1 >= 0:
61
61
  XOrHere2makePair <<= 2
62
- findUnpairedBinary1 += 1 if (bifurcationOdd & XOrHere2makePair) == 0 else -1
63
- bifurcationOdd ^= XOrHere2makePair
62
+ findUnpairedBinary1 += 1 if (bifurcationAlpha & XOrHere2makePair) == 0 else -1
63
+ bifurcationAlpha ^= XOrHere2makePair
64
64
 
65
- elif bifurcationEvenFinalZero and not bifurcationOddFinalZero:
65
+ elif bifurcationZuluFinalZero and not bifurcationAlphaFinalZero:
66
66
  while findUnpairedBinary1 >= 0:
67
67
  XOrHere2makePair <<= 2
68
- findUnpairedBinary1 += 1 if (bifurcationEven & XOrHere2makePair) == 0 else -1
69
- bifurcationEven ^= XOrHere2makePair
68
+ findUnpairedBinary1 += 1 if (bifurcationZulu & XOrHere2makePair) == 0 else -1
69
+ bifurcationZulu ^= XOrHere2makePair
70
70
 
71
- curveLocationAnalysis = (bifurcationOdd >> 2) | ((bifurcationEven >> 2) << 1)
71
+ curveLocationAnalysis = (bifurcationAlpha >> 2) | ((bifurcationZulu >> 2) << 1)
72
72
  storeCurveLocations(curveLocationAnalysis, distinctCrossings)
73
73
 
74
74
  # Move discovered data to known for next iteration