mapFolding 0.2.1__py3-none-any.whl → 0.2.2__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.
@@ -21,11 +21,11 @@ gapter = gapRangeStart = 3
21
21
 
22
22
  # Indices of array `my`, which holds dynamic, small, unsigned, integer values.
23
23
  tricky = [
24
- (activeLeaf1ndex := 0),
25
- (activeGap1ndex := 1),
24
+ (leaf1ndex := 0),
25
+ (gap1ndex := 1),
26
26
  (unconstrainedLeaf := 2),
27
27
  (gap1ndexCeiling := 3),
28
- (leaf1ndexConnectee := 4),
28
+ (leafConnectee := 4),
29
29
  (taskIndex := 5),
30
30
  (dimension1ndex := 6),
31
31
  (foldingsSubtotal := 7),
@@ -76,7 +76,7 @@ def countFoldings(TEMPLATEtrack: NDArray,
76
76
  ):
77
77
 
78
78
  TEMPLATEmy = numpy.zeros(COUNTindicesDynamic, dtype=numpy.int64)
79
- TEMPLATEmy[activeLeaf1ndex] = 1
79
+ TEMPLATEmy[leaf1ndex] = 1
80
80
 
81
81
  taskDivisions = 0
82
82
  # taskDivisions = the[leavesTotal]
@@ -87,61 +87,61 @@ def countFoldings(TEMPLATEtrack: NDArray,
87
87
  my: NDArray) -> tuple[NDArray, NDArray, NDArray]:
88
88
  foldingsTotal = 0
89
89
  while True:
90
- if my[activeLeaf1ndex] <= 1 or track[leafBelow][0] == 1:
91
- if my[activeLeaf1ndex] > the[leavesTotal]:
90
+ if my[leaf1ndex] <= 1 or track[leafBelow][0] == 1:
91
+ if my[leaf1ndex] > the[leavesTotal]:
92
92
  foldingsTotal += the[leavesTotal]
93
93
  else:
94
94
  my[unconstrainedLeaf] = 0
95
- my[gap1ndexCeiling] = track[gapRangeStart][my[activeLeaf1ndex] - 1]
96
- my[activeGap1ndex] = my[gap1ndexCeiling]
95
+ my[gap1ndexCeiling] = track[gapRangeStart][my[leaf1ndex] - 1]
96
+ my[gap1ndex] = my[gap1ndexCeiling]
97
97
 
98
98
  for PREPAREdimension1ndex in range(1, the[dimensionsPlus1]):
99
- if connectionGraph[PREPAREdimension1ndex][my[activeLeaf1ndex]][my[activeLeaf1ndex]] == my[activeLeaf1ndex]:
99
+ if connectionGraph[PREPAREdimension1ndex][my[leaf1ndex]][my[leaf1ndex]] == my[leaf1ndex]:
100
100
  my[unconstrainedLeaf] += 1
101
101
  else:
102
- my[leaf1ndexConnectee] = connectionGraph[PREPAREdimension1ndex][my[activeLeaf1ndex]][my[activeLeaf1ndex]]
103
- while my[leaf1ndexConnectee] != my[activeLeaf1ndex]:
102
+ my[leafConnectee] = connectionGraph[PREPAREdimension1ndex][my[leaf1ndex]][my[leaf1ndex]]
103
+ while my[leafConnectee] != my[leaf1ndex]:
104
104
 
105
- if my[leaf1ndexConnectee] != my[activeLeaf1ndex]:
105
+ if my[leafConnectee] != my[leaf1ndex]:
106
106
  my[dimension1ndex] = PREPAREdimension1ndex
107
107
  return track, gapsWhere, my
108
108
 
109
- if my[activeLeaf1ndex] != the[leavesTotal]:
110
- gapsWhere[my[gap1ndexCeiling]] = my[leaf1ndexConnectee]
111
- if track[countDimensionsGapped][my[leaf1ndexConnectee]] == 0:
109
+ if my[leaf1ndex] != the[leavesTotal]:
110
+ gapsWhere[my[gap1ndexCeiling]] = my[leafConnectee]
111
+ if track[countDimensionsGapped][my[leafConnectee]] == 0:
112
112
  my[gap1ndexCeiling] += 1
113
- track[countDimensionsGapped][my[leaf1ndexConnectee]] += 1
113
+ track[countDimensionsGapped][my[leafConnectee]] += 1
114
114
  else:
115
115
  print("else")
116
116
  my[dimension1ndex] = PREPAREdimension1ndex
117
117
  return track, gapsWhere, my
118
- # PREPAREmy[leaf1ndexConnectee] % the[leavesTotal] == PREPAREmy[taskIndex]
119
- my[leaf1ndexConnectee] = connectionGraph[dimension1ndex][my[activeLeaf1ndex]][track[leafBelow][my[leaf1ndexConnectee]]]
118
+ # PREPAREmy[leafConnectee] % the[leavesTotal] == PREPAREmy[taskIndex]
119
+ my[leafConnectee] = connectionGraph[dimension1ndex][my[leaf1ndex]][track[leafBelow][my[leafConnectee]]]
120
120
 
121
121
  if my[unconstrainedLeaf] == the[dimensionsTotal]:
122
- for leaf1ndex in range(my[activeLeaf1ndex]):
123
- gapsWhere[my[gap1ndexCeiling]] = leaf1ndex
122
+ for indexLeaf in range(my[leaf1ndex]):
123
+ gapsWhere[my[gap1ndexCeiling]] = indexLeaf
124
124
  my[gap1ndexCeiling] += 1
125
125
 
126
- for indexMiniGap in range(my[activeGap1ndex], my[gap1ndexCeiling]):
127
- gapsWhere[my[activeGap1ndex]] = gapsWhere[indexMiniGap]
126
+ for indexMiniGap in range(my[gap1ndex], my[gap1ndexCeiling]):
127
+ gapsWhere[my[gap1ndex]] = gapsWhere[indexMiniGap]
128
128
  if track[countDimensionsGapped][gapsWhere[indexMiniGap]] == the[dimensionsTotal] - my[unconstrainedLeaf]:
129
- my[activeGap1ndex] += 1
129
+ my[gap1ndex] += 1
130
130
  track[countDimensionsGapped][gapsWhere[indexMiniGap]] = 0
131
131
 
132
- while my[activeLeaf1ndex] > 0 and my[activeGap1ndex] == track[gapRangeStart][my[activeLeaf1ndex] - 1]:
133
- my[activeLeaf1ndex] -= 1
134
- track[leafBelow][track[leafAbove][my[activeLeaf1ndex]]] = track[leafBelow][my[activeLeaf1ndex]]
135
- track[leafAbove][track[leafBelow][my[activeLeaf1ndex]]] = track[leafAbove][my[activeLeaf1ndex]]
132
+ while my[leaf1ndex] > 0 and my[gap1ndex] == track[gapRangeStart][my[leaf1ndex] - 1]:
133
+ my[leaf1ndex] -= 1
134
+ track[leafBelow][track[leafAbove][my[leaf1ndex]]] = track[leafBelow][my[leaf1ndex]]
135
+ track[leafAbove][track[leafBelow][my[leaf1ndex]]] = track[leafAbove][my[leaf1ndex]]
136
136
 
137
- if my[activeLeaf1ndex] > 0:
138
- my[activeGap1ndex] -= 1
139
- track[leafAbove][my[activeLeaf1ndex]] = gapsWhere[my[activeGap1ndex]]
140
- track[leafBelow][my[activeLeaf1ndex]] = track[leafBelow][track[leafAbove][my[activeLeaf1ndex]]]
141
- track[leafBelow][track[leafAbove][my[activeLeaf1ndex]]] = my[activeLeaf1ndex]
142
- track[leafAbove][track[leafBelow][my[activeLeaf1ndex]]] = my[activeLeaf1ndex]
143
- track[gapRangeStart][my[activeLeaf1ndex]] = my[activeGap1ndex]
144
- my[activeLeaf1ndex] += 1
137
+ if my[leaf1ndex] > 0:
138
+ my[gap1ndex] -= 1
139
+ track[leafAbove][my[leaf1ndex]] = gapsWhere[my[gap1ndex]]
140
+ track[leafBelow][my[leaf1ndex]] = track[leafBelow][track[leafAbove][my[leaf1ndex]]]
141
+ track[leafBelow][track[leafAbove][my[leaf1ndex]]] = my[leaf1ndex]
142
+ track[leafAbove][track[leafBelow][my[leaf1ndex]]] = my[leaf1ndex]
143
+ track[gapRangeStart][my[leaf1ndex]] = my[gap1ndex]
144
+ my[leaf1ndex] += 1
145
145
 
146
146
  RETURNtrack, RETURNgapsWhere, RETURNmy = prepareWork(TEMPLATEtrack.copy(), TEMPLATEgapsWhere.copy(), TEMPLATEmy.copy())
147
147
 
@@ -166,44 +166,44 @@ def doWork(track: NDArray,
166
166
  thisIsNotTheFirstPass = False
167
167
 
168
168
  while papasGotABrandNewBag:
169
- if my[activeLeaf1ndex] <= 1 or track[leafBelow][0] == 1 or if_activeLeaf1ndex_LTE_1_or_leafBelow_index_0_equals_1 == True:
169
+ if my[leaf1ndex] <= 1 or track[leafBelow][0] == 1 or if_activeLeaf1ndex_LTE_1_or_leafBelow_index_0_equals_1 == True:
170
170
  if_activeLeaf1ndex_LTE_1_or_leafBelow_index_0_equals_1 = False
171
- if my[activeLeaf1ndex] > the[leavesTotal] and thisIsNotTheFirstPass:
171
+ if my[leaf1ndex] > the[leavesTotal] and thisIsNotTheFirstPass:
172
172
  my[foldingsSubtotal] += the[leavesTotal]
173
173
  else:
174
174
  if thisIsNotTheFirstPass:
175
175
  my[unconstrainedLeaf] = 0
176
- my[gap1ndexCeiling] = track[gapRangeStart][my[activeLeaf1ndex] - 1]
177
- my[activeGap1ndex] = my[gap1ndexCeiling]
176
+ my[gap1ndexCeiling] = track[gapRangeStart][my[leaf1ndex] - 1]
177
+ my[gap1ndex] = my[gap1ndexCeiling]
178
178
 
179
179
  for_dimension1ndex_in_range_1_to_dimensionsPlus1 = True
180
180
  while for_dimension1ndex_in_range_1_to_dimensionsPlus1 == True:
181
181
  for_dimension1ndex_in_range_1_to_dimensionsPlus1 = False
182
- if connectionGraph[my[dimension1ndex]][my[activeLeaf1ndex]][my[activeLeaf1ndex]] == my[activeLeaf1ndex] and thisIsNotTheFirstPass:
182
+ if connectionGraph[my[dimension1ndex]][my[leaf1ndex]][my[leaf1ndex]] == my[leaf1ndex] and thisIsNotTheFirstPass:
183
183
  my[unconstrainedLeaf] += 1
184
184
  else:
185
185
  if thisIsNotTheFirstPass:
186
- my[leaf1ndexConnectee] = connectionGraph[my[dimension1ndex]][my[activeLeaf1ndex]][my[activeLeaf1ndex]]
187
- if my[leaf1ndexConnectee] != my[activeLeaf1ndex]:
186
+ my[leafConnectee] = connectionGraph[my[dimension1ndex]][my[leaf1ndex]][my[leaf1ndex]]
187
+ if my[leafConnectee] != my[leaf1ndex]:
188
188
  while_leaf1ndexConnectee_notEquals_activeLeaf1ndex = True
189
189
 
190
190
  while while_leaf1ndexConnectee_notEquals_activeLeaf1ndex == True:
191
191
  while_leaf1ndexConnectee_notEquals_activeLeaf1ndex = False
192
192
  thisIsNotTheFirstPass = True
193
- if taskDivisions==0 or my[activeLeaf1ndex] != taskDivisions:
193
+ if taskDivisions==0 or my[leaf1ndex] != taskDivisions:
194
194
  myTask = True
195
195
  else:
196
- modulo = my[leaf1ndexConnectee] % the[leavesTotal]
196
+ modulo = my[leafConnectee] % the[leavesTotal]
197
197
  if modulo == my[taskIndex]: myTask = True
198
198
  else:
199
199
  myTask = False
200
200
  if myTask:
201
- gapsWhere[my[gap1ndexCeiling]] = my[leaf1ndexConnectee]
202
- if track[countDimensionsGapped][my[leaf1ndexConnectee]] == 0:
201
+ gapsWhere[my[gap1ndexCeiling]] = my[leafConnectee]
202
+ if track[countDimensionsGapped][my[leafConnectee]] == 0:
203
203
  my[gap1ndexCeiling] += 1
204
- track[countDimensionsGapped][my[leaf1ndexConnectee]] += 1
205
- my[leaf1ndexConnectee] = connectionGraph[my[dimension1ndex]][my[activeLeaf1ndex]][track[leafBelow][my[leaf1ndexConnectee]]]
206
- if my[leaf1ndexConnectee] != my[activeLeaf1ndex]:
204
+ track[countDimensionsGapped][my[leafConnectee]] += 1
205
+ my[leafConnectee] = connectionGraph[my[dimension1ndex]][my[leaf1ndex]][track[leafBelow][my[leafConnectee]]]
206
+ if my[leafConnectee] != my[leaf1ndex]:
207
207
  while_leaf1ndexConnectee_notEquals_activeLeaf1ndex = True
208
208
  my[dimension1ndex] += 1
209
209
  if my[dimension1ndex] < the[dimensionsPlus1]:
@@ -212,29 +212,29 @@ def doWork(track: NDArray,
212
212
  my[dimension1ndex] = 1
213
213
 
214
214
  if my[unconstrainedLeaf] == the[dimensionsTotal]:
215
- for leaf1ndex in range(my[activeLeaf1ndex]):
215
+ for leaf1ndex in range(my[leaf1ndex]):
216
216
  gapsWhere[my[gap1ndexCeiling]] = leaf1ndex
217
217
  my[gap1ndexCeiling] += 1
218
218
 
219
- for indexMiniGap in range(my[activeGap1ndex], my[gap1ndexCeiling]):
220
- gapsWhere[my[activeGap1ndex]] = gapsWhere[indexMiniGap]
219
+ for indexMiniGap in range(my[gap1ndex], my[gap1ndexCeiling]):
220
+ gapsWhere[my[gap1ndex]] = gapsWhere[indexMiniGap]
221
221
  if track[countDimensionsGapped][gapsWhere[indexMiniGap]] == the[dimensionsTotal] - my[unconstrainedLeaf]:
222
- my[activeGap1ndex] += 1
222
+ my[gap1ndex] += 1
223
223
  track[countDimensionsGapped][gapsWhere[indexMiniGap]] = 0
224
224
 
225
- while my[activeLeaf1ndex] > 0 and my[activeGap1ndex] == track[gapRangeStart][my[activeLeaf1ndex] - 1]:
226
- my[activeLeaf1ndex] -= 1
227
- track[leafBelow][track[leafAbove][my[activeLeaf1ndex]]] = track[leafBelow][my[activeLeaf1ndex]]
228
- track[leafAbove][track[leafBelow][my[activeLeaf1ndex]]] = track[leafAbove][my[activeLeaf1ndex]]
229
-
230
- if my[activeLeaf1ndex] > 0:
231
- my[activeGap1ndex] -= 1
232
- track[leafAbove][my[activeLeaf1ndex]] = gapsWhere[my[activeGap1ndex]]
233
- track[leafBelow][my[activeLeaf1ndex]] = track[leafBelow][track[leafAbove][my[activeLeaf1ndex]]]
234
- track[leafBelow][track[leafAbove][my[activeLeaf1ndex]]] = my[activeLeaf1ndex]
235
- track[leafAbove][track[leafBelow][my[activeLeaf1ndex]]] = my[activeLeaf1ndex]
236
- track[gapRangeStart][my[activeLeaf1ndex]] = my[activeGap1ndex]
237
- my[activeLeaf1ndex] += 1
238
-
239
- if my[activeLeaf1ndex] <= 0:
225
+ while my[leaf1ndex] > 0 and my[gap1ndex] == track[gapRangeStart][my[leaf1ndex] - 1]:
226
+ my[leaf1ndex] -= 1
227
+ track[leafBelow][track[leafAbove][my[leaf1ndex]]] = track[leafBelow][my[leaf1ndex]]
228
+ track[leafAbove][track[leafBelow][my[leaf1ndex]]] = track[leafAbove][my[leaf1ndex]]
229
+
230
+ if my[leaf1ndex] > 0:
231
+ my[gap1ndex] -= 1
232
+ track[leafAbove][my[leaf1ndex]] = gapsWhere[my[gap1ndex]]
233
+ track[leafBelow][my[leaf1ndex]] = track[leafBelow][track[leafAbove][my[leaf1ndex]]]
234
+ track[leafBelow][track[leafAbove][my[leaf1ndex]]] = my[leaf1ndex]
235
+ track[leafAbove][track[leafBelow][my[leaf1ndex]]] = my[leaf1ndex]
236
+ track[gapRangeStart][my[leaf1ndex]] = my[gap1ndex]
237
+ my[leaf1ndex] += 1
238
+
239
+ if my[leaf1ndex] <= 0:
240
240
  return my[foldingsSubtotal]
@@ -0,0 +1,211 @@
1
+ from numba import njit
2
+ import numpy
3
+
4
+ @njit(cache=True)
5
+ def foldings_plus_1(p: list[int], computationDivisions: int = 0, computationIndex: int = 0) -> int:
6
+ n: int = 1 # Total number of leaves
7
+ for dimension in p:
8
+ n *= dimension
9
+
10
+ d = len(p) # Number of dimensions
11
+ # Compute arrays P, C, D as per the algorithm
12
+ P = numpy.ones(d + 1, dtype=numpy.int64)
13
+ for i in range(1, d + 1):
14
+ P[i] = P[i - 1] * p[i - 1]
15
+
16
+ # C[i][m] holds the i-th coordinate of leaf m
17
+ C = numpy.zeros((d + 1, n + 1), dtype=numpy.int64)
18
+ for i in range(1, d + 1):
19
+ for m in range(1, n + 1):
20
+ C[i][m] = ((m - 1) // P[i - 1]) - ((m - 1) // P[i]) * p[i - 1] + 1
21
+
22
+ # D[i][l][m] computes the leaf connected to m in section i when inserting l
23
+ D = numpy.zeros((d + 1, n + 1, n + 1), dtype=numpy.int64)
24
+ for i in range(1, d + 1):
25
+ for l in range(1, n + 1):
26
+ for m in range(1, l + 1):
27
+ delta = C[i][l] - C[i][m]
28
+ if delta % 2 == 0:
29
+ # If delta is even
30
+ if C[i][m] == 1:
31
+ D[i][l][m] = m
32
+ else:
33
+ D[i][l][m] = m - P[i - 1]
34
+ else:
35
+ # If delta is odd
36
+ if C[i][m] == p[i - 1] or m + P[i - 1] > l:
37
+ D[i][l][m] = m
38
+ else:
39
+ D[i][l][m] = m + P[i - 1]
40
+ # Initialize arrays/lists
41
+ A = numpy.zeros(n + 1, dtype=numpy.int64) # Leaf above leaf m
42
+ B = numpy.zeros(n + 1, dtype=numpy.int64) # Leaf below leaf m
43
+ count = numpy.zeros(n + 1, dtype=numpy.int64) # Counts for potential gaps
44
+ gapter = numpy.zeros(n + 1, dtype=numpy.int64) # Indices for gap stack per leaf
45
+ gap = numpy.zeros(n * n + 1, dtype=numpy.int64) # Stack of potential gaps
46
+
47
+
48
+ # Initialize variables for backtracking
49
+ total_count = 0 # Total number of foldings
50
+ g = 0 # Gap index
51
+ l = 1 # Current leaf
52
+
53
+ # Start backtracking loop
54
+ while l > 0:
55
+ # If we have processed all leaves, increment total count
56
+ if l > n:
57
+ total_count += 1
58
+ else:
59
+ dd = 0 # Number of sections where leaf l is unconstrained
60
+ gg = g # Temporary gap index
61
+ g = gapter[l - 1] # Reset gap index for current leaf
62
+
63
+ # Count possible gaps for leaf l in each section
64
+ for i in range(1, d + 1):
65
+ if D[i][l][l] == l:
66
+ dd += 1
67
+ else:
68
+ m = D[i][l][l]
69
+ while m != l:
70
+ if computationDivisions == 0 or l != computationDivisions or m % computationDivisions == computationIndex:
71
+ gap[gg] = m
72
+ if count[m] == 0:
73
+ gg += 1
74
+ count[m] += 1
75
+ m = D[i][l][B[m]]
76
+
77
+ # If leaf l is unconstrained in all sections, it can be inserted anywhere
78
+ if dd == d:
79
+ for m in range(l):
80
+ gap[gg] = m
81
+ gg += 1
82
+
83
+ # Filter gaps that are common to all sections
84
+ for j in range(g, gg):
85
+ gap[g] = gap[j]
86
+ if count[gap[j]] == d - dd:
87
+ g += 1
88
+ count[gap[j]] = 0 # Reset count for next iteration
89
+
90
+ # Recursive backtracking steps
91
+ while l > 0 and g == gapter[l - 1]:
92
+ l -= 1
93
+ B[A[l]] = B[l]
94
+ A[B[l]] = A[l]
95
+
96
+ if l > 0:
97
+ g -= 1
98
+ A[l] = gap[g]
99
+ B[l] = B[A[l]]
100
+ B[A[l]] = l
101
+ A[B[l]] = l
102
+ gapter[l] = g # Save current gap index
103
+ l += 1 # Move to next leaf
104
+
105
+ return total_count
106
+
107
+ @njit(cache=True)
108
+ def foldings(p: list[int], computationDivisions: int = 0, computationIndex: int = 0) -> int:
109
+ n: int = 1 # Total number of leaves
110
+ for dimension in p:
111
+ n *= dimension
112
+
113
+ d = len(p) # Number of dimensions
114
+ # Compute arrays P, C, D as per the algorithm
115
+ P = numpy.ones(d + 1, dtype=numpy.int64)
116
+ for i in range(1, d + 1):
117
+ P[i] = P[i - 1] * p[i - 1]
118
+
119
+ # C[i][m] holds the i-th coordinate of leaf m
120
+ C = numpy.zeros((d + 1, n + 1), dtype=numpy.int64)
121
+ for i in range(1, d + 1):
122
+ for m in range(1, n + 1):
123
+ C[i][m] = ((m - 1) // P[i - 1]) - ((m - 1) // P[i]) * p[i - 1] + 1
124
+ # C[i][m] = ((m - 1) // P[i - 1]) % p[i - 1] + 1 # NOTE different, but either one works
125
+
126
+ # D[i][l][m] computes the leaf connected to m in section i when inserting l
127
+ D = numpy.zeros((d + 1, n + 1, n + 1), dtype=numpy.int64)
128
+ for i in range(1, d + 1):
129
+ for l in range(1, n + 1):
130
+ for m in range(1, l + 1):
131
+ delta = C[i][l] - C[i][m]
132
+ if delta % 2 == 0:
133
+ # If delta is even
134
+ if C[i][m] == 1:
135
+ D[i][l][m] = m
136
+ else:
137
+ D[i][l][m] = m - P[i - 1]
138
+ else:
139
+ # If delta is odd
140
+ if C[i][m] == p[i - 1] or m + P[i - 1] > l:
141
+ D[i][l][m] = m
142
+ else:
143
+ D[i][l][m] = m + P[i - 1]
144
+ # Initialize arrays/lists
145
+ A = numpy.zeros(n + 1, dtype=numpy.int64) # Leaf above leaf m
146
+ B = numpy.zeros(n + 1, dtype=numpy.int64) # Leaf below leaf m
147
+ count = numpy.zeros(n + 1, dtype=numpy.int64) # Counts for potential gaps
148
+ gapter = numpy.zeros(n + 1, dtype=numpy.int64) # Indices for gap stack per leaf
149
+ gap = numpy.zeros(n * n + 1, dtype=numpy.int64) # Stack of potential gaps
150
+
151
+
152
+ # Initialize variables for backtracking
153
+ total_count = 0 # Total number of foldings
154
+ g = 0 # Gap index
155
+ l = 1 # Current leaf
156
+
157
+ # Start backtracking loop
158
+ while l > 0:
159
+ if l <= 1 or B[0] == 1: # NOTE different
160
+ # NOTE the above `if` statement encloses the the if/else block below
161
+ # NOTE these changes increase the throughput by more than an order of magnitude
162
+ if l > n:
163
+ total_count += n
164
+ else:
165
+ dd = 0 # Number of sections where leaf l is unconstrained
166
+ gg = gapter[l - 1] # Track possible gaps # NOTE different, but not important
167
+ g = gg # NOTE different, but not important
168
+
169
+ # Count possible gaps for leaf l in each section
170
+ for i in range(1, d + 1):
171
+ if D[i][l][l] == l:
172
+ dd += 1
173
+ else:
174
+ m = D[i][l][l]
175
+ while m != l:
176
+ if computationDivisions == 0 or l != computationDivisions or m % computationDivisions == computationIndex:
177
+ gap[gg] = m
178
+ if count[m] == 0:
179
+ gg += 1
180
+ count[m] += 1
181
+ m = D[i][l][B[m]]
182
+
183
+ # If leaf l is unconstrained in all sections, it can be inserted anywhere
184
+ if dd == d:
185
+ for m in range(l):
186
+ gap[gg] = m
187
+ gg += 1
188
+
189
+ # Filter gaps that are common to all sections
190
+ for j in range(g, gg):
191
+ gap[g] = gap[j]
192
+ if count[gap[j]] == d - dd:
193
+ g += 1
194
+ count[gap[j]] = 0 # Reset count for next iteration
195
+
196
+ # Recursive backtracking steps
197
+ while l > 0 and g == gapter[l - 1]:
198
+ l -= 1
199
+ B[A[l]] = B[l]
200
+ A[B[l]] = A[l]
201
+
202
+ if l > 0:
203
+ g -= 1
204
+ A[l] = gap[g]
205
+ B[l] = B[A[l]]
206
+ B[A[l]] = l
207
+ A[B[l]] = l
208
+ gapter[l] = g # Save current gap index
209
+ l += 1 # Move to next leaf
210
+
211
+ return total_count
mapFolding/startHere.py CHANGED
@@ -13,7 +13,7 @@ def countFolds(listDimensions: Sequence[int], writeFoldsTotal: Optional[Union[st
13
13
  computationDivisions (None):
14
14
  Whether and how to divide the computational work. See notes for details.
15
15
  CPUlimit (None): This is only relevant if there are `computationDivisions`: whether and how to limit the CPU usage. See notes for details.
16
- **keywordArguments: Additional arguments including dtypeDefault and dtypeLarge for data type specifications.
16
+ **keywordArguments: Additional arguments including `dtypeDefault` and `dtypeLarge` for data type specifications.
17
17
  Returns:
18
18
  foldsTotal: Total number of distinct ways to fold a map of the given dimensions.
19
19
 
@@ -54,9 +54,7 @@ def countFolds(listDimensions: Sequence[int], writeFoldsTotal: Optional[Union[st
54
54
  pathFilenameFoldsTotal.write_text(str(foldsTotal))
55
55
  except Exception as ERRORmessage:
56
56
  print(ERRORmessage)
57
- print("\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal")
58
- print(f"{foldsTotal=}")
59
- print("\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal")
57
+ print(f"\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal\n\n{foldsTotal=}\n\nfoldsTotal foldsTotal foldsTotal foldsTotal foldsTotal")
60
58
 
61
59
  return foldsTotal
62
60
 
mapFolding/theSSOT.py CHANGED
@@ -5,6 +5,10 @@ import numpy.typing
5
5
  import pathlib
6
6
  import sys
7
7
 
8
+ dtypeLarge = numpy.int64
9
+ dtypeDefault = dtypeLarge
10
+ dtypeSmall = dtypeDefault
11
+
8
12
  try:
9
13
  _pathModule = pathlib.Path(__file__).parent
10
14
  except NameError:
@@ -24,7 +28,8 @@ class EnumIndices(enum.IntEnum):
24
28
  return count
25
29
 
26
30
  def __index__(self) -> int:
27
- """Make the enum work with array indexing."""
31
+ """Adapt enum to the ultra-rare event of indexing a NumPy 'ndarray', which is not the
32
+ same as `array.array`. See NumPy.org; I think it will be very popular someday."""
28
33
  return self.value
29
34
 
30
35
  class indexMy(EnumIndices):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: mapFolding
3
- Version: 0.2.1
3
+ Version: 0.2.2
4
4
  Summary: Algorithm(s) for counting distinct ways to fold a map (or a strip of stamps)
5
5
  Author-email: Hunter Hogan <HunterHogan@pm.me>
6
6
  Project-URL: homepage, https://github.com/hunterhogan/mapFolding
@@ -0,0 +1,28 @@
1
+ mapFolding/__init__.py,sha256=POxXTSE6Qu1G8k-YlSXHzbe-_JGuHk-L9p5SLRng4vA,439
2
+ mapFolding/babbage.py,sha256=3D1qcntoiJm2tqgbiCAMc7GpGA0SZTdGORNEnensyxk,1882
3
+ mapFolding/beDRY.py,sha256=ZrUXCNqnumTQ1XX8RT5gGdRr-a-o8QxEiGrerUxKtYg,12784
4
+ mapFolding/lovelace.py,sha256=qcyGpVEPP3n0r-RNrSUgPRP3yZJfBEfmok7jYMm1OI0,11473
5
+ mapFolding/oeis.py,sha256=_-fLGc1ybZ2eFxoiBrSmojMexeg6ROxtrLaBF2BzMn4,12144
6
+ mapFolding/startHere.py,sha256=RGdFoJJdrJ_0tmLIKZn1WnHP0NCZwvQG7C2p4EUHOe4,5034
7
+ mapFolding/theSSOT.py,sha256=yRW6aHyJxheL-Znk537LQA6xUPHz6FfoXY-0Ayh3Lsg,2178
8
+ mapFolding/JAX/lunnanJAX.py,sha256=xMZloN47q-MVfjdYOM1hi9qR4OnLq7qALmGLMraevQs,14819
9
+ mapFolding/JAX/taskJAX.py,sha256=yJNeH0rL6EhJ6ppnATHF0Zf81CDMC10bnPnimVxE1hc,20037
10
+ mapFolding/benchmarks/benchmarking.py,sha256=kv85F6V9pGhZvTOImArOuxyg5rywA_T6JLH_qFXM8BM,3018
11
+ mapFolding/benchmarks/test_benchmarks.py,sha256=c4ANeR3jgqpKXFoxDeZkmAHxSuenMwsjmrhKJ1_XPqY,3659
12
+ mapFolding/reference/hunterNumba.py,sha256=0giUyqAFzP-XKcq3Kz8wIWCK0BVFhjABVJ1s-w4Jhu0,7109
13
+ mapFolding/reference/irvineJavaPort.py,sha256=Sj-63Z-OsGuDoEBXuxyjRrNmmyl0d7Yz_XuY7I47Oyg,4250
14
+ mapFolding/reference/lunnan.py,sha256=XEcql_gxvCCghb6Or3qwmPbn4IZUbZTaSmw_fUjRxZE,5037
15
+ mapFolding/reference/lunnanNumpy.py,sha256=HqDgSwTOZA-G0oophOEfc4zs25Mv4yw2aoF1v8miOLk,4653
16
+ mapFolding/reference/lunnanWhile.py,sha256=7NY2IKO5XBgol0aWWF_Fi-7oTL9pvu_z6lB0TF1uVHk,4063
17
+ mapFolding/reference/rotatedEntryPoint.py,sha256=z0QyDQtnMvXNj5ntWzzJUQUMFm1-xHGLVhtYzwmczUI,11530
18
+ mapFolding/reference/total_countPlus1vsPlusN.py,sha256=usenM8Yn_G1dqlPl7NKKkcnbohBZVZBXTQRm2S3_EDA,8106
19
+ tests/__init__.py,sha256=PGYVr7r23gATgcvZ3Sfph9D_g1MVvhgzMNWXBs_9tmY,52
20
+ tests/conftest.py,sha256=VFYSd7-tHWd-LUKnTY24PIJhq9quP9S3sK2SYusNNog,12875
21
+ tests/test_oeis.py,sha256=vxnwO-cSR68htkyMh9QMVv-lvxBo6qlwPg1Rbx4JylY,7963
22
+ tests/test_other.py,sha256=cf8DbkZxm_DHNq9lkMe7auXye_XspruU9qiNZATkxr4,6930
23
+ tests/test_tasks.py,sha256=Nwe4iuSjwGZvsw5CXCcic7tkBxgM5JX9mrGZMDYhAwE,1785
24
+ mapFolding-0.2.2.dist-info/METADATA,sha256=BSCXcKZDhAtOWr8A5pZMG8bZnm5YBLf-6uMN9qs8JDk,5914
25
+ mapFolding-0.2.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
26
+ mapFolding-0.2.2.dist-info/entry_points.txt,sha256=F3OUeZR1XDTpoH7k3wXuRb3KF_kXTTeYhu5AGK1SiOQ,146
27
+ mapFolding-0.2.2.dist-info/top_level.txt,sha256=1gP2vFaqPwHujGwb3UjtMlLEGN-943VSYFR7V4gDqW8,17
28
+ mapFolding-0.2.2.dist-info/RECORD,,