mapFolding 0.16.1__py3-none-any.whl → 0.16.4__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 (78) hide show
  1. easyRun/A000682.py +1 -1
  2. easyRun/A005316.py +2 -3
  3. easyRun/NOTcountingFolds.py +6 -5
  4. easyRun/countFolds.py +1 -1
  5. easyRun/generateAllModules.py +14 -0
  6. easyRun/meanders.py +16 -18
  7. mapFolding/__init__.py +1 -0
  8. mapFolding/_theSSOT.py +3 -2
  9. mapFolding/_theTypes.py +3 -0
  10. mapFolding/algorithms/A086345.py +75 -0
  11. mapFolding/algorithms/matrixMeanders.py +15 -28
  12. mapFolding/algorithms/matrixMeandersBeDry.py +34 -116
  13. mapFolding/algorithms/matrixMeandersNumPy.py +117 -70
  14. mapFolding/algorithms/matrixMeandersPandas.py +113 -130
  15. mapFolding/algorithms/oeisIDbyFormula.py +25 -14
  16. mapFolding/algorithms/symmetricFolds.py +36 -0
  17. mapFolding/algorithms/zCuzDocStoopidoeisIDbyFormula.py +26 -12
  18. mapFolding/basecamp.py +152 -323
  19. mapFolding/dataBaskets.py +136 -34
  20. mapFolding/filesystemToolkit.py +4 -32
  21. mapFolding/oeis.py +5 -12
  22. mapFolding/reference/A000682facts.py +785 -1264
  23. mapFolding/reference/A005316facts.py +958 -923
  24. mapFolding/reference/A086345Wu.py +25 -0
  25. mapFolding/reference/matrixMeandersAnalysis/signatures.py +2033 -0
  26. mapFolding/someAssemblyRequired/A007822/A007822rawMaterials.py +9 -44
  27. mapFolding/someAssemblyRequired/A007822/_asynchronousAnnex.py +51 -0
  28. mapFolding/someAssemblyRequired/A007822/makeA007822AsynchronousModules.py +39 -136
  29. mapFolding/someAssemblyRequired/A007822/makeA007822Modules.py +44 -45
  30. mapFolding/someAssemblyRequired/RecipeJob.py +78 -18
  31. mapFolding/someAssemblyRequired/__init__.py +3 -8
  32. mapFolding/someAssemblyRequired/_toolkitContainers.py +32 -3
  33. mapFolding/someAssemblyRequired/infoBooth.py +40 -23
  34. mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +75 -154
  35. mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +56 -88
  36. mapFolding/someAssemblyRequired/makingModules_count.py +91 -85
  37. mapFolding/someAssemblyRequired/makingModules_doTheNeedful.py +7 -65
  38. mapFolding/someAssemblyRequired/{mapFolding → mapFoldingModules}/makeMapFoldingModules.py +25 -31
  39. mapFolding/someAssemblyRequired/meanders/makeMeandersModules.py +14 -13
  40. mapFolding/someAssemblyRequired/toolkitMakeModules.py +10 -10
  41. mapFolding/someAssemblyRequired/toolkitNumba.py +1 -1
  42. mapFolding/someAssemblyRequired/transformationTools.py +17 -19
  43. mapFolding/syntheticModules/A007822/algorithm.py +46 -50
  44. mapFolding/syntheticModules/A007822/asynchronous.py +93 -34
  45. mapFolding/syntheticModules/A007822/initializeState.py +15 -21
  46. mapFolding/syntheticModules/A007822/theorem2.py +21 -21
  47. mapFolding/syntheticModules/A007822/theorem2Numba.py +42 -23
  48. mapFolding/syntheticModules/A007822/theorem2Trimmed.py +21 -21
  49. mapFolding/syntheticModules/countParallelNumba.py +3 -7
  50. mapFolding/syntheticModules/daoOfMapFoldingNumba.py +3 -6
  51. mapFolding/syntheticModules/meanders/bigInt.py +15 -25
  52. mapFolding/syntheticModules/theorem2.py +6 -0
  53. mapFolding/syntheticModules/theorem2Numba.py +26 -2
  54. mapFolding/syntheticModules/theorem2Trimmed.py +6 -0
  55. mapFolding/tests/test_computations.py +1 -1
  56. mapFolding/zCuzDocStoopid/makeDocstrings.py +2 -0
  57. {mapfolding-0.16.1.dist-info → mapfolding-0.16.4.dist-info}/METADATA +4 -1
  58. mapfolding-0.16.4.dist-info/RECORD +106 -0
  59. mapFolding/_dataPacking.py +0 -68
  60. mapFolding/reference/meandersDumpingGround/A005316intOptimized.py +0 -122
  61. mapFolding/reference/meandersDumpingGround/A005316optimized128bit.py +0 -79
  62. mapFolding/reference/meandersDumpingGround/matrixMeandersBaseline.py +0 -65
  63. mapFolding/reference/meandersDumpingGround/matrixMeandersBaselineAnnex.py +0 -84
  64. mapFolding/reference/meandersDumpingGround/matrixMeandersSimpleQueue.py +0 -90
  65. mapFolding/syntheticModules/A007822/algorithmNumba.py +0 -94
  66. mapFolding/syntheticModules/A007822/asynchronousAnnex.py +0 -66
  67. mapFolding/syntheticModules/A007822/asynchronousAnnexNumba.py +0 -85
  68. mapFolding/syntheticModules/A007822/asynchronousNumba.py +0 -52
  69. mapFolding/syntheticModules/A007822/asynchronousTheorem2.py +0 -53
  70. mapFolding/syntheticModules/A007822/asynchronousTrimmed.py +0 -47
  71. mapFolding/syntheticModules/dataPacking.py +0 -28
  72. mapFolding/syntheticModules/dataPackingA007822.py +0 -92
  73. mapfolding-0.16.1.dist-info/RECORD +0 -114
  74. /mapFolding/someAssemblyRequired/{mapFolding → mapFoldingModules}/__init__.py +0 -0
  75. {mapfolding-0.16.1.dist-info → mapfolding-0.16.4.dist-info}/WHEEL +0 -0
  76. {mapfolding-0.16.1.dist-info → mapfolding-0.16.4.dist-info}/entry_points.txt +0 -0
  77. {mapfolding-0.16.1.dist-info → mapfolding-0.16.4.dist-info}/licenses/LICENSE +0 -0
  78. {mapfolding-0.16.1.dist-info → mapfolding-0.16.4.dist-info}/top_level.txt +0 -0
mapFolding/dataBaskets.py CHANGED
@@ -21,10 +21,10 @@ 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, Array3DLeavesTotal, DatatypeElephino, DatatypeFoldsTotal, DatatypeLeavesTotal,
25
- getConnectionGraph, getLeavesTotal, makeDataContainer, ShapeArray, ShapeSlicer)
24
+ Array1DElephino, Array1DLeavesTotal, Array2DLeavesTotal, Array3DLeavesTotal, DatatypeElephino, DatatypeFoldsTotal,
25
+ DatatypeLeavesTotal, getConnectionGraph, getLeavesTotal, makeDataContainer)
26
26
  from numpy.typing import NDArray
27
- from typing import Final, TypeAlias
27
+ from typing import TypeAlias
28
28
  import dataclasses
29
29
  import numpy
30
30
 
@@ -111,8 +111,6 @@ class MapFoldingState:
111
111
  """Array tracking the leaves above to the current leaf, `leaf1ndex`, during computation."""
112
112
  leafBelow: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
113
113
  """Array tracking the leaves below to the current leaf, `leaf1ndex`, during computation."""
114
- leafComparison: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
115
- """Array for finding symmetric folds."""
116
114
 
117
115
  connectionGraph: Array3DLeavesTotal = dataclasses.field(init=False, metadata={'dtype': Array3DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportUnknownMemberType, reportAttributeAccessIssue]
118
116
  """Unchanging array representing connections between all leaves."""
@@ -126,7 +124,7 @@ class MapFoldingState:
126
124
 
127
125
  Returns
128
126
  -------
129
- totalFoldings : DatatypeFoldsTotal
127
+ foldsTotal : DatatypeFoldsTotal
130
128
  The complete count of distinct folding patterns achievable with the current map configuration.
131
129
 
132
130
  """
@@ -154,6 +152,126 @@ class MapFoldingState:
154
152
  if self.gapRangeStart is None: self.gapRangeStart = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['gapRangeStart'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
155
153
  if self.leafAbove is None: self.leafAbove = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafAbove'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
156
154
  if self.leafBelow is None: self.leafBelow = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafBelow'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
155
+
156
+ @dataclasses.dataclass(slots=True)
157
+ class SymmetricFoldsState:
158
+ """Core computational state for symmetric map folding algorithms.
159
+
160
+ Attributes
161
+ ----------
162
+ mapShape : tuple[DatatypeLeavesTotal, ...]
163
+ Dimensions of the map being analyzed for folding patterns.
164
+ groupsOfFolds : DatatypeFoldsTotal = DatatypeFoldsTotal(0)
165
+ Current count of distinct folding pattern groups: each group has `leavesTotal`-many foldings.
166
+ gap1ndex : DatatypeElephino = DatatypeElephino(0)
167
+ The current 1-indexed position of the 'gap' during computation: 1-indexed as opposed to 0-indexed.
168
+ gap1ndexCeiling : DatatypeElephino = DatatypeElephino(0)
169
+ The upper bound of `gap1ndex`.
170
+ indexDimension : DatatypeLeavesTotal = DatatypeLeavesTotal(0)
171
+ The current 0-indexed position of the dimension during computation.
172
+ indexLeaf : DatatypeLeavesTotal = DatatypeLeavesTotal(0)
173
+ The current 0-indexed position of a leaf in a loop during computation: not to be confused with `leaf1ndex`.
174
+ indexMiniGap : DatatypeElephino = DatatypeElephino(0)
175
+ The current 0-indexed position of a 'gap' in a loop during computation.
176
+ leaf1ndex : DatatypeLeavesTotal = DatatypeLeavesTotal(1)
177
+ The current 1-indexed position of the leaf during computation: 1-indexed as opposed to 0-indexed.
178
+ leafConnectee : DatatypeLeavesTotal = DatatypeLeavesTotal(0)
179
+ Target leaf for connection operations.
180
+ dimensionsUnconstrained : DatatypeLeavesTotal = None
181
+ Count of dimensions not subject to folding constraints.
182
+ countDimensionsGapped : Array1DLeavesTotal = None
183
+ Array tracking computed number of dimensions with gaps.
184
+ gapRangeStart : Array1DElephino = None
185
+ Array tracking computed starting positions of gap ranges.
186
+ gapsWhere : Array1DLeavesTotal = None
187
+ Array indicating locations of gaps in the folding pattern.
188
+ leafAbove : Array1DLeavesTotal = None
189
+ Array tracking the leaves above to the current leaf, `leaf1ndex`, during computation.
190
+ leafBelow : Array1DLeavesTotal = None
191
+ Array tracking the leaves below to the current leaf, `leaf1ndex`, during computation.
192
+ leafComparison : Array1DLeavesTotal = None
193
+ Array for finding symmetric folds.
194
+ connectionGraph : Array3DLeavesTotal
195
+ Unchanging array representing connections between all leaves.
196
+ dimensionsTotal : DatatypeLeavesTotal
197
+ Unchanging total number of dimensions in the map.
198
+ leavesTotal : DatatypeLeavesTotal
199
+ Unchanging total number of leaves in the map.
200
+
201
+ """
202
+
203
+ mapShape: tuple[DatatypeLeavesTotal, ...] = dataclasses.field(init=True, metadata={'elementConstructor': 'DatatypeLeavesTotal'})
204
+ """Dimensions of the map being analyzed for folding patterns."""
205
+
206
+ groupsOfFolds: DatatypeFoldsTotal = dataclasses.field(default=DatatypeFoldsTotal(0), metadata={'theCountingIdentifier': True})
207
+ """Current count of symmetric folds."""
208
+
209
+ gap1ndex: DatatypeElephino = DatatypeElephino(0) # noqa: RUF009
210
+ """The current 1-indexed position of the 'gap' during computation: 1-indexed as opposed to 0-indexed."""
211
+ gap1ndexCeiling: DatatypeElephino = DatatypeElephino(0) # noqa: RUF009
212
+ """The upper bound of `gap1ndex`."""
213
+ indexDimension: DatatypeLeavesTotal = DatatypeLeavesTotal(0) # noqa: RUF009
214
+ """The current 0-indexed position of the dimension during computation."""
215
+ indexLeaf: DatatypeLeavesTotal = DatatypeLeavesTotal(0) # noqa: RUF009
216
+ """The current 0-indexed position of a leaf in a loop during computation: not to be confused with `leaf1ndex`."""
217
+ indexMiniGap: DatatypeElephino = DatatypeElephino(0) # noqa: RUF009
218
+ """The current 0-indexed position of a 'gap' in a loop during computation."""
219
+ leaf1ndex: DatatypeLeavesTotal = DatatypeLeavesTotal(1) # noqa: RUF009
220
+ """The current 1-indexed position of the leaf during computation: 1-indexed as opposed to 0-indexed."""
221
+ leafConnectee: DatatypeLeavesTotal = DatatypeLeavesTotal(0) # noqa: RUF009
222
+ """Target leaf for connection operations."""
223
+
224
+ dimensionsUnconstrained: DatatypeLeavesTotal = dataclasses.field(default=None, init=True) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
225
+ """Count of dimensions not subject to folding constraints."""
226
+
227
+ countDimensionsGapped: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
228
+ """Array tracking computed number of dimensions with gaps."""
229
+ gapRangeStart: Array1DElephino = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DElephino.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
230
+ """Array tracking computed starting positions of gap ranges."""
231
+ gapsWhere: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
232
+ """Array indicating locations of gaps in the folding pattern."""
233
+ leafAbove: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
234
+ """Array tracking the leaves above to the current leaf, `leaf1ndex`, during computation."""
235
+ leafBelow: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
236
+ """Array tracking the leaves below to the current leaf, `leaf1ndex`, during computation."""
237
+ leafComparison: Array1DLeavesTotal = dataclasses.field(default=None, init=True, metadata={'dtype': Array1DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportAssignmentType, reportAttributeAccessIssue, reportUnknownMemberType]
238
+ """Array for finding symmetric folds."""
239
+
240
+ arrayGroupOfFolds: Array2DLeavesTotal = dataclasses.field(init=False, metadata={'dtype': Array2DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportUnknownMemberType, reportAttributeAccessIssue]
241
+ connectionGraph: Array3DLeavesTotal = dataclasses.field(init=False, metadata={'dtype': Array3DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportUnknownMemberType, reportAttributeAccessIssue]
242
+ """Unchanging array representing connections between all leaves."""
243
+ dimensionsTotal: DatatypeLeavesTotal = dataclasses.field(init=False)
244
+ """Unchanging total number of dimensions in the map."""
245
+ indicesArrayGroupOfFolds: Array2DLeavesTotal = dataclasses.field(init=False, metadata={'dtype': Array2DLeavesTotal.__args__[1].__args__[0]}) # pyright: ignore[reportUnknownMemberType, reportAttributeAccessIssue]
246
+ leavesTotal: DatatypeLeavesTotal = dataclasses.field(init=False)
247
+ """Unchanging total number of leaves in the map."""
248
+
249
+ def __post_init__(self) -> None:
250
+ """Ensure all fields have a value.
251
+
252
+ Notes
253
+ -----
254
+ Arrays that are not explicitly provided (None) are automatically allocated with appropriate sizes based on the map
255
+ dimensions. `dimensionsTotal`, `leavesTotal`, and `connectionGraph` cannot be set: they are calculated.
256
+
257
+ """
258
+ self.dimensionsTotal = DatatypeLeavesTotal(len(self.mapShape))
259
+ self.leavesTotal = DatatypeLeavesTotal(getLeavesTotal(self.mapShape))
260
+
261
+ leavesTotalAsInt = int(self.leavesTotal)
262
+
263
+ self.connectionGraph = getConnectionGraph(self.mapShape, leavesTotalAsInt, self.__dataclass_fields__['connectionGraph'].metadata['dtype'])
264
+
265
+ self.indicesArrayGroupOfFolds = (numpy.arange(leavesTotalAsInt + 1)[:, None] + numpy.arange(leavesTotalAsInt)[None, :]) % (leavesTotalAsInt + 1)
266
+ self.indicesArrayGroupOfFolds[..., leavesTotalAsInt // 2:None] = self.indicesArrayGroupOfFolds[..., leavesTotalAsInt - 1: leavesTotalAsInt - leavesTotalAsInt // 2 - 1: -1]
267
+ self.arrayGroupOfFolds = numpy.zeros_like(self.indicesArrayGroupOfFolds)
268
+
269
+ if self.dimensionsUnconstrained is None: self.dimensionsUnconstrained = DatatypeLeavesTotal(int(self.dimensionsTotal)) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
270
+ if self.gapsWhere is None: self.gapsWhere = makeDataContainer(leavesTotalAsInt * leavesTotalAsInt + 1, self.__dataclass_fields__['gapsWhere'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
271
+ if self.countDimensionsGapped is None: self.countDimensionsGapped = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['countDimensionsGapped'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
272
+ if self.gapRangeStart is None: self.gapRangeStart = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['gapRangeStart'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
273
+ if self.leafAbove is None: self.leafAbove = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafAbove'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
274
+ if self.leafBelow is None: self.leafBelow = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafBelow'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
157
275
  if self.leafComparison is None: self.leafComparison = makeDataContainer(leavesTotalAsInt + 1, self.__dataclass_fields__['leafComparison'].metadata['dtype']) # pyright: ignore[reportUnnecessaryComparison] # noqa: E701
158
276
 
159
277
  @dataclasses.dataclass
@@ -280,21 +398,21 @@ class MatrixMeandersState:
280
398
  """The index of the meanders problem being solved."""
281
399
  oeisID: str
282
400
  """'A000682', semi-meanders, or 'A005316', meanders."""
283
- kOfMatrix: int
284
- """The number of iterations remaining in the transfer matrix algorithm."""
401
+ boundary: int
402
+ """The algorithm analyzes `n` boundaries starting at `boundary = n - 1`."""
285
403
  dictionaryMeanders: dict[int, int]
286
404
  """A Python `dict` (*dict*ionary) of `arcCode` to `crossings`. The values are stored as Python `int`
287
405
  (*int*eger), which may be arbitrarily large. Because of that property, `int` may also be called a 'bignum' (big *num*ber) or
288
406
  'bigint' (big *int*eger)."""
289
407
 
290
408
  bitWidth: int = 0
291
- """At the start of an iteration enumerated by `kOfMatrix`, the number of bits of the largest value `arcCode`. The
409
+ """At the start of an iteration enumerated by `boundary`, the number of bits of the largest value `arcCode`. The
292
410
  `dataclass` computes a `property` from `bitWidth`."""
293
411
 
294
412
  @property
295
413
  def MAXIMUMarcCode(self) -> int:
296
414
  """Compute the maximum value of `arcCode` for the current iteration of the transfer matrix."""
297
- return 1 << (2 * self.kOfMatrix + 4)
415
+ return 1 << (2 * self.boundary + 4)
298
416
 
299
417
  @property
300
418
  def locatorBits(self) -> int:
@@ -317,7 +435,8 @@ class MatrixMeandersState:
317
435
  class MatrixMeandersNumPyState(MatrixMeandersState):
318
436
  """Hold the state of a meanders transfer matrix algorithm computation."""
319
437
 
320
- arrayMeanders: NDArray[numpy.uint64] = dataclasses.field(default_factory=lambda: numpy.empty((0,), dtype=numpy.uint64))
438
+ arrayArcCodes: NDArray[numpy.uint64] = dataclasses.field(default_factory=lambda: numpy.empty((0,), dtype=numpy.uint64))
439
+ arrayCrossings: NDArray[numpy.uint64] = dataclasses.field(default_factory=lambda: numpy.empty((0,), dtype=numpy.uint64))
321
440
 
322
441
  bitWidthLimitArcCode: int | None = None
323
442
  bitWidthLimitCrossings: int | None = None
@@ -330,20 +449,6 @@ class MatrixMeandersNumPyState(MatrixMeandersState):
330
449
  indexTarget: int = 0
331
450
  """What is being indexed depends on the algorithm flavor."""
332
451
 
333
- # TODO Integrate this better into the dataclasses paradigm.
334
- indicesMeanders: Final[int] = 2
335
- indexArcCode, indexCrossings = range(indicesMeanders)
336
-
337
- @property
338
- def slicerArcCode(self) -> ShapeSlicer:
339
- """Get a `ShapeSlicer` to extract the `arcCode` column from `arrayMeanders`."""
340
- return ShapeSlicer(length=..., indices=self.indexArcCode)
341
-
342
- @property
343
- def slicerCrossings(self) -> ShapeSlicer:
344
- """Get a `ShapeSlicer` to extract the `crossings` column from `arrayMeanders`."""
345
- return ShapeSlicer(length=..., indices=self.indexCrossings)
346
-
347
452
  def __post_init__(self) -> None:
348
453
  """Post init."""
349
454
  if self.bitWidthLimitArcCode is None:
@@ -371,16 +476,13 @@ class MatrixMeandersNumPyState(MatrixMeandersState):
371
476
 
372
477
  def makeDictionary(self) -> None:
373
478
  """Convert from NumPy `ndarray` (*Num*erical *Py*thon *n-d*imensional array) to Python `dict` (*dict*ionary)."""
374
- self.dictionaryMeanders = {int(key): int(value) for key, value in zip(
375
- self.arrayMeanders[self.slicerArcCode], self.arrayMeanders[self.slicerCrossings]
376
- , strict=True)}
377
- self.arrayMeanders = numpy.empty((0,), dtype=self.datatypeArcCode)
479
+ self.dictionaryMeanders = {int(key): int(value) for key, value in zip(self.arrayArcCodes, self.arrayCrossings, strict=True)}
480
+ self.arrayArcCodes = numpy.empty((0,), dtype=self.datatypeArcCode)
481
+ self.arrayCrossings = numpy.empty((0,), dtype=self.datatypeCrossings)
378
482
 
379
483
  def makeArray(self) -> None:
380
484
  """Convert from Python `dict` (*dict*ionary) to NumPy `ndarray` (*Num*erical *Py*thon *n-d*imensional array)."""
381
- shape = ShapeArray(length=len(self.dictionaryMeanders), indices=self.indicesMeanders)
382
- self.arrayMeanders = numpy.zeros(shape, dtype=self.datatypeArcCode)
383
- self.arrayMeanders[self.slicerArcCode] = list(self.dictionaryMeanders.keys())
384
- self.arrayMeanders[self.slicerCrossings] = list(self.dictionaryMeanders.values())
385
- self.bitWidth = int(self.arrayMeanders[self.slicerArcCode].max()).bit_length()
485
+ self.arrayArcCodes = numpy.array(list(self.dictionaryMeanders.keys()), dtype=self.datatypeArcCode)
486
+ self.arrayCrossings = numpy.array(list(self.dictionaryMeanders.values()), dtype=self.datatypeCrossings)
487
+ self.bitWidth = int(self.arrayArcCodes.max()).bit_length()
386
488
  self.dictionaryMeanders = {}
@@ -56,12 +56,10 @@ def getFilenameFoldsTotal(mapShape: tuple[int, ...]) -> str:
56
56
  return 'p' + 'x'.join(str(dimension) for dimension in sorted(mapShape)) + '.foldsTotal'
57
57
 
58
58
  def getPathFilenameFoldsTotal(mapShape: tuple[int, ...], pathLikeWriteFoldsTotal: PathLike[str] | PurePath | None = None) -> Path:
59
- """Get a standardized path and filename for the computed `foldsTotal` value.
59
+ """Get a standardized filename and create a configurable path to store the computed `foldsTotal` value.
60
60
 
61
- (AI generated docstring)
62
-
63
- This function resolves paths for storing computation results, handling different input types including directories,
64
- absolute paths, or relative paths. It ensures that all parent directories exist in the resulting path.
61
+ To help reduce duplicate code and to increase predictability, this function creates a standardized filename, has a default but
62
+ configurable path, and creates the path.
65
63
 
66
64
  Parameters
67
65
  ----------
@@ -78,10 +76,9 @@ def getPathFilenameFoldsTotal(mapShape: tuple[int, ...], pathLikeWriteFoldsTotal
78
76
  Notes
79
77
  -----
80
78
  The function creates any necessary directories in the path if they don't exist.
81
-
82
79
  """
83
80
  if pathLikeWriteFoldsTotal is None:
84
- pathFilenameFoldsTotal = getPathRootJobDEFAULT() / getFilenameFoldsTotal(mapShape)
81
+ pathFilenameFoldsTotal: Path = getPathRootJobDEFAULT() / getFilenameFoldsTotal(mapShape)
85
82
  else:
86
83
  pathLikeSherpa = Path(pathLikeWriteFoldsTotal)
87
84
  if pathLikeSherpa.is_dir():
@@ -237,28 +234,3 @@ def saveFoldsTotalFAILearly(pathFilename: PathLike[str] | PurePath) -> None:
237
234
  if foldsTotalRead != foldsTotal:
238
235
  message = f"I wrote a test file to `{pathFilename = }` with contents of `{str(foldsTotal) = }`, but I read `{foldsTotalRead = }` from the file. Python says the values are not equal. Fix that now, so your computation doesn't get corrupted later. And be pro-social."
239
236
  raise FileNotFoundError(message)
240
-
241
- def writeStringToHere(this: str, pathFilename: PathLike[str] | PurePath) -> None:
242
- """Write a string to a file, creating parent directories if needed.
243
-
244
- (AI generated docstring)
245
-
246
- This utility function provides a consistent interface for writing string content to files across the package. It
247
- handles path creation and ensures proper string conversion.
248
-
249
- Parameters
250
- ----------
251
- this : str
252
- The string content to write to the file.
253
- pathFilename : PathLike[str] | PurePath
254
- The target file path where the string should be written.
255
-
256
- Notes
257
- -----
258
- This function creates all parent directories in the path if they don't exist, making it safe to use with newly
259
- created directory structures.
260
-
261
- """
262
- pathFilename = Path(pathFilename)
263
- pathFilename.parent.mkdir(parents=True, exist_ok=True)
264
- pathFilename.write_text(str(this))
mapFolding/oeis.py CHANGED
@@ -306,12 +306,6 @@ def makeDictionaryFoldsTotalKnown() -> dict[tuple[int, ...], int]:
306
306
  def getFoldsTotalKnown(mapShape: tuple[int, ...]) -> int:
307
307
  """Retrieve the known total number of distinct folding patterns for a given map shape.
308
308
 
309
- (AI generated docstring)
310
-
311
- This function provides rapid access to precalculated folding totals from OEIS sequences without
312
- requiring computation. It serves as a validation reference for algorithm results and enables
313
- quick lookup of known values across all implemented sequences.
314
-
315
309
  Parameters
316
310
  ----------
317
311
  mapShape : tuple[int, ...]
@@ -320,17 +314,16 @@ def getFoldsTotalKnown(mapShape: tuple[int, ...]) -> int:
320
314
  Returns
321
315
  -------
322
316
  foldingsTotal : int
323
- The known total number of distinct folding patterns for the given map shape,
324
- or -1 if the map shape does not match any known values in the OEIS sequences.
317
+ The known total number of distinct folding patterns for the given map shape, or 0 if the map shape does not match any
318
+ known values in the OEIS sequences.
325
319
 
326
320
  Notes
327
321
  -----
328
- The function uses a cached dictionary for efficient retrieval without repeatedly processing
329
- OEIS data. Map shapes are matched exactly as provided without internal sorting or normalization.
322
+ Map shapes are matched exactly as provided without internal sorting or normalization.
330
323
 
331
324
  """
332
- lookupFoldsTotal = makeDictionaryFoldsTotalKnown()
333
- return lookupFoldsTotal.get(tuple(mapShape), -1)
325
+ lookupFoldsTotal: dict[tuple[int, ...], int] = makeDictionaryFoldsTotalKnown()
326
+ return lookupFoldsTotal.get(tuple(mapShape), 0)
334
327
 
335
328
  def _formatHelpText() -> str:
336
329
  """Format comprehensive help text for both command-line and interactive use.