mapFolding 0.17.1__py3-none-any.whl → 0.18.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 (248) hide show
  1. easyRun/NOTcountingFolds.py +7 -11
  2. easyRun/countFolds.py +11 -10
  3. easyRun/meanders.py +6 -8
  4. mapFolding/__init__.py +24 -36
  5. mapFolding/_e/Z0Z_analysisPython/SORTZ0Z_hypothesis.py +189 -0
  6. mapFolding/_e/Z0Z_analysisPython/SORTZ0Z_p2d6.py +143 -0
  7. mapFolding/_e/Z0Z_analysisPython/__init__.py +4 -0
  8. mapFolding/_e/Z0Z_analysisPython/exclusionData/__init__.py +0 -0
  9. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200.py +369 -0
  10. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/2001.py +694 -0
  11. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/270/211.py +514 -0
  12. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/270/2111.py +480 -0
  13. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/214.py +511 -0
  14. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/2141.py +515 -0
  15. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/214/344/270/211.py +485 -0
  16. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/200/344/272/214/344/270/2111.py +442 -0
  17. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/211.py +313 -0
  18. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/270/2111.py +343 -0
  19. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/214.py +400 -0
  20. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/2141.py +497 -0
  21. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/214/344/270/211.py +463 -0
  22. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/344/272/214/344/270/2111.py +441 -0
  23. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266.py +35 -0
  24. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/2661.py +35 -0
  25. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200.py +382 -0
  26. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/2001.py +630 -0
  27. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/270/211.py +488 -0
  28. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/270/2111.py +475 -0
  29. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/214.py +473 -0
  30. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/2141.py +500 -0
  31. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211.py +465 -0
  32. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111.py +439 -0
  33. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/211.py +599 -0
  34. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/270/2111.py +536 -0
  35. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/214.py +506 -0
  36. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/2141.py +533 -0
  37. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/214/344/270/211.py +489 -0
  38. mapFolding/_e/Z0Z_analysisPython/exclusionData/aggregated/351/246/226/351/233/266/344/272/214/344/270/2111.py +474 -0
  39. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200.py +1186 -0
  40. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2001.py +2158 -0
  41. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2001Negative.py +2158 -0
  42. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200Negative.py +1186 -0
  43. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/211.py +1397 -0
  44. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/2111.py +1291 -0
  45. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/2111Negative.py +1291 -0
  46. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/270/211Negative.py +1397 -0
  47. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214.py +1240 -0
  48. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/2141.py +1420 -0
  49. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/2141Negative.py +1420 -0
  50. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214Negative.py +1240 -0
  51. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/211.py +1366 -0
  52. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/2111.py +1274 -0
  53. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/2111Negative.py +1274 -0
  54. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/200/344/272/214/344/270/211Negative.py +1366 -0
  55. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/211.py +1186 -0
  56. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2111.py +1186 -0
  57. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/2111Negative.py +1186 -0
  58. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/270/211Negative.py +1186 -0
  59. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214.py +1102 -0
  60. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/2141.py +1422 -0
  61. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/2141Negative.py +1422 -0
  62. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214Negative.py +1102 -0
  63. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/211.py +1240 -0
  64. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/2111.py +1228 -0
  65. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/2111Negative.py +1228 -0
  66. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/344/272/214/344/270/211Negative.py +1240 -0
  67. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266.py +32 -0
  68. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/2661.py +1162 -0
  69. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/2661Negative.py +1162 -0
  70. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266Negative.py +32 -0
  71. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200.py +1186 -0
  72. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2001.py +1926 -0
  73. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2001Negative.py +1926 -0
  74. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200Negative.py +1186 -0
  75. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/211.py +1291 -0
  76. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/2111.py +1176 -0
  77. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/2111Negative.py +1176 -0
  78. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/270/211Negative.py +1291 -0
  79. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214.py +1228 -0
  80. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/2141.py +1324 -0
  81. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/2141Negative.py +1324 -0
  82. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214Negative.py +1228 -0
  83. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211.py +1274 -0
  84. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111.py +1038 -0
  85. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111Negative.py +1038 -0
  86. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211Negative.py +1274 -0
  87. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/211.py +2158 -0
  88. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2111.py +1926 -0
  89. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/2111Negative.py +1926 -0
  90. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/270/211Negative.py +2158 -0
  91. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214.py +1422 -0
  92. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/2141.py +1364 -0
  93. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/2141Negative.py +1364 -0
  94. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214Negative.py +1422 -0
  95. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/211.py +1420 -0
  96. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/2111.py +1324 -0
  97. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/2111Negative.py +1324 -0
  98. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d5/351/246/226/351/233/266/344/272/214/344/270/211Negative.py +1420 -0
  99. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200.py +3133 -0
  100. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2001.py +6039 -0
  101. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2001Negative.py +6039 -0
  102. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200Negative.py +3133 -0
  103. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/211.py +3527 -0
  104. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/2111.py +2300 -0
  105. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/2111Negative.py +2300 -0
  106. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/270/211Negative.py +3527 -0
  107. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214.py +3597 -0
  108. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/2141.py +3317 -0
  109. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/2141Negative.py +3317 -0
  110. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214Negative.py +3597 -0
  111. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/211.py +3161 -0
  112. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/2111.py +2877 -0
  113. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/2111Negative.py +2877 -0
  114. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/200/344/272/214/344/270/211Negative.py +3161 -0
  115. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/211.py +2981 -0
  116. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2111.py +3055 -0
  117. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/2111Negative.py +3055 -0
  118. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/270/211Negative.py +2981 -0
  119. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214.py +3221 -0
  120. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/2141.py +3988 -0
  121. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/2141Negative.py +3988 -0
  122. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214Negative.py +3221 -0
  123. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/211.py +3652 -0
  124. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/2111.py +2863 -0
  125. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/2111Negative.py +2863 -0
  126. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/344/272/214/344/270/211Negative.py +3652 -0
  127. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200.py +2485 -0
  128. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2001.py +4566 -0
  129. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2001Negative.py +4566 -0
  130. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200Negative.py +2485 -0
  131. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/211.py +3006 -0
  132. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/2111.py +2485 -0
  133. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/2111Negative.py +2485 -0
  134. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/270/211Negative.py +3006 -0
  135. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214.py +3304 -0
  136. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/2141.py +3015 -0
  137. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/2141Negative.py +3015 -0
  138. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214Negative.py +3304 -0
  139. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211.py +2939 -0
  140. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111.py +2589 -0
  141. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/2111Negative.py +2589 -0
  142. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/200/344/272/214/344/270/211Negative.py +2939 -0
  143. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/211.py +3899 -0
  144. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2111.py +2996 -0
  145. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/2111Negative.py +2996 -0
  146. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/270/211Negative.py +3899 -0
  147. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214.py +3223 -0
  148. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/2141.py +3020 -0
  149. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/2141Negative.py +3020 -0
  150. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214Negative.py +3223 -0
  151. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/211.py +3250 -0
  152. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/2111.py +2667 -0
  153. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/2111Negative.py +2667 -0
  154. mapFolding/_e/Z0Z_analysisPython/exclusionData/collatedp2d6/351/246/226/351/233/266/344/272/214/344/270/211Negative.py +3250 -0
  155. mapFolding/_e/Z0Z_analysisPython/measure.py +162 -0
  156. mapFolding/_e/Z0Z_analysisPython/positionAnalysis.py +403 -0
  157. mapFolding/_e/Z0Z_analysisPython/positionAnalysisPileRanges2d6.py +110 -0
  158. mapFolding/_e/Z0Z_analysisPython/theExcluderBeast.py +640 -0
  159. mapFolding/_e/Z0Z_analysisPython/toolkit.py +166 -0
  160. mapFolding/_e/Z0Z_analysisPython/toolkitCSVsequences.py +188 -0
  161. mapFolding/_e/Z0Z_analysisPython/workBenchPatternFinder.py +284 -0
  162. mapFolding/_e/Z0Z_notes/__init__.py +0 -0
  163. mapFolding/_e/Z0Z_notes/knowledgeDump.py +214 -0
  164. mapFolding/_e/__init__.py +45 -0
  165. mapFolding/_e/_beDRY.py +547 -0
  166. mapFolding/_e/_dataDynamic.py +1164 -0
  167. mapFolding/_e/_measure.py +579 -0
  168. mapFolding/_e/_semiotics.py +363 -0
  169. mapFolding/_e/_theTypes.py +31 -0
  170. mapFolding/_e/algorithms/__init__.py +1 -0
  171. mapFolding/_e/algorithms/constraintPropagation.py +158 -0
  172. mapFolding/_e/algorithms/elimination.py +118 -0
  173. mapFolding/_e/algorithms/eliminationCrease.py +66 -0
  174. mapFolding/_e/algorithms/iff.py +584 -0
  175. mapFolding/_e/basecamp.py +89 -0
  176. mapFolding/_e/dataBaskets.py +123 -0
  177. mapFolding/_e/dataRaw/__init__.py +0 -0
  178. mapFolding/_e/easyRun/__init__.py +0 -0
  179. mapFolding/_e/easyRun/eliminateFolds.py +72 -0
  180. mapFolding/_e/easyRun/pinning.py +62 -0
  181. mapFolding/_e/filters.py +384 -0
  182. mapFolding/_e/pin2/344/270/212nDimensions.py +882 -0
  183. mapFolding/_e/pin2/344/270/212nDimensionsAnnex.py +551 -0
  184. mapFolding/_e/pin2/344/270/212nDimensionsByCrease.py +190 -0
  185. mapFolding/_e/pin2/344/270/212nDimensionsByDomain.py +459 -0
  186. mapFolding/_e/pinIt.py +436 -0
  187. mapFolding/_semiotics.py +42 -0
  188. mapFolding/_theSSOT.py +11 -56
  189. mapFolding/_theTypes.py +52 -67
  190. mapFolding/algorithms/matrixMeandersNumPyndas.py +18 -18
  191. mapFolding/algorithms/oeisIDbyFormula.py +4 -4
  192. mapFolding/algorithms/zCuzDocStoopidoeisIDbyFormula.py +3 -3
  193. mapFolding/basecamp.py +11 -80
  194. mapFolding/beDRY.py +107 -111
  195. mapFolding/dataBaskets.py +0 -56
  196. mapFolding/filesystemToolkit.py +15 -11
  197. mapFolding/oeis.py +17 -16
  198. mapFolding/reference/matrixMeandersAnalysis/prefixNotationNotes.py +2 -2
  199. mapFolding/reference/meandersDumpingGround/matrixMeandersBaselineV2.py +0 -1
  200. mapFolding/reference/meandersDumpingGround/matrixMeandersNumPyV1finalForm.py +8 -10
  201. mapFolding/someAssemblyRequired/RecipeJob.py +5 -5
  202. mapFolding/someAssemblyRequired/makeJobTheorem2Numba.py +5 -2
  203. mapFolding/someAssemblyRequired/makeJobTheorem2codon.py +9 -11
  204. mapFolding/someAssemblyRequired/mapFoldingModules/makeMapFoldingModules.py +2 -1
  205. mapFolding/someAssemblyRequired/transformationTools.py +1 -1
  206. mapFolding/tests/Z0Z_test_e_excluder.py +155 -0
  207. mapFolding/tests/conftest.py +193 -314
  208. mapFolding/tests/dataSamples/A001417.py +455 -0
  209. mapFolding/tests/dataSamples/__init__.py +1 -0
  210. mapFolding/tests/dataSamples/measurementData.py +1818 -0
  211. mapFolding/tests/dataSamples/p2DnDomain3_2_/351/246/226/344/270/200_/351/246/226/351/233/266/344/270/200.py +17 -0
  212. mapFolding/tests/dataSamples/p2DnDomain3_/351/246/226/344/270/200.py +17 -0
  213. mapFolding/tests/dataSamples/p2DnDomain5_4.py +17 -0
  214. mapFolding/tests/dataSamples/p2DnDomain6_5.py +17 -0
  215. mapFolding/tests/dataSamples/p2DnDomain6_7_5_4.py +17 -0
  216. mapFolding/tests/dataSamples/p2DnDomain7_6.py +17 -0
  217. mapFolding/tests/dataSamples/p2DnDomain/351/246/226/344/272/214_/351/246/226/351/233/266/344/270/200/344/272/214.py +17 -0
  218. mapFolding/tests/dataSamples/p2DnDomain/351/246/226/344/272/214_/351/246/226/351/233/266/344/272/214_/351/246/226/351/233/266/344/270/200/344/272/214_/351/246/226/344/270/200/344/272/214.py +17 -0
  219. mapFolding/tests/dataSamples/p2DnDomain/351/246/226/351/233/266/344/270/200/344/272/214_/351/246/226/344/270/200/344/272/214.py +15 -0
  220. mapFolding/tests/dataSamples/p2DnDomain/351/246/226/351/233/266/344/272/214_/351/246/226/344/272/214.py +15 -0
  221. mapFolding/tests/dataSamples/semioticsData.py +135 -0
  222. mapFolding/tests/test_computations.py +134 -80
  223. mapFolding/tests/test_e_computations.py +42 -0
  224. mapFolding/tests/test_e_dataDynamic.py +189 -0
  225. mapFolding/tests/test_e_measurements.py +257 -0
  226. mapFolding/tests/test_e_pinning.py +61 -0
  227. mapFolding/tests/test_e_semiotics.py +128 -0
  228. mapFolding/tests/test_filesystem.py +39 -17
  229. mapFolding/tests/{test_other.py → test_parameterValidation.py} +3 -3
  230. mapFolding/tests/{test_tasks.py → test_taskDivisions.py} +42 -23
  231. mapFolding/zCuzDocStoopid/makeDocstrings.py +3 -2
  232. {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/METADATA +11 -8
  233. mapfolding-0.18.0.dist-info/RECORD +305 -0
  234. {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/WHEEL +1 -1
  235. easyRun/eliminateFolds.py +0 -60
  236. mapFolding/algorithms/constraintPropagation.py +0 -184
  237. mapFolding/algorithms/elimination.py +0 -131
  238. mapFolding/algorithms/eliminationCount.py +0 -26
  239. mapFolding/algorithms/eliminationPinned.py +0 -35
  240. mapFolding/algorithms/iff.py +0 -206
  241. mapFolding/algorithms/patternFinder.py +0 -280
  242. mapFolding/algorithms/pinning2Dn.py +0 -345
  243. mapFolding/algorithms/pinning2DnAnnex.py +0 -43
  244. mapFolding/tests/verify.py +0 -323
  245. mapfolding-0.17.1.dist-info/RECORD +0 -112
  246. {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/entry_points.txt +0 -0
  247. {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/licenses/LICENSE +0 -0
  248. {mapfolding-0.17.1.dist-info → mapfolding-0.18.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,547 @@
1
+ """You can use this module to share elimination-algorithm utilities that avoid `EliminationState` imports.
2
+
3
+ This module is a workbench utility layer for `mapFolding._e` algorithms. The module primarily contains utilities that are intended
4
+ to work beyond the $2^n$-dimensional special case.
5
+
6
+ You should avoid putting functions in this module that only work on $2^n$-dimensional maps. You cannot import `EliminationState`
7
+ into this module without causing circular import problems. This constraint exists as of 2026-01-26.
8
+
9
+ Contents
10
+ --------
11
+ Group-by functions
12
+ bifurcatePermutationSpace
13
+ You can split a `PermutationSpace` into pinned leaves and pile-range domains.
14
+
15
+ Disaggregation and deconstruction functions
16
+ DOTitems
17
+ You can iterate over `(key, value)` pairs in a `Mapping`.
18
+ DOTkeys
19
+ You can iterate over keys in a `Mapping`.
20
+ DOTvalues
21
+ You can iterate over values in a `Mapping`.
22
+ getIteratorOfLeaves
23
+ You can iterate over each `Leaf` bit that is set in a `PileRangeOfLeaves`.
24
+
25
+ `PileRangeOfLeaves` functions
26
+ DOTgetPileIfLeaf
27
+ You can read `permutationSpace[pile]` only when `permutationSpace[pile]` is a `Leaf`.
28
+ DOTgetPileIfPileRangeOfLeaves
29
+ You can read `permutationSpace[pile]` only when `permutationSpace[pile]` is a `PileRangeOfLeaves`.
30
+ getAntiPileRangeOfLeaves
31
+ You can build a complement `PileRangeOfLeaves` by clearing each `leaf` bit.
32
+ getPileRangeOfLeaves
33
+ You can build a `PileRangeOfLeaves` by setting each `leaf` bit.
34
+ JeanValjean
35
+ You can normalize a `PileRangeOfLeaves` into a `Leaf` or `None` when the range is degenerate.
36
+ pileRangeOfLeavesAND
37
+ You can AND a `PileRangeOfLeaves` with a disposable mask in a curry-friendly parameter order.
38
+
39
+ Be DRY functions
40
+ getProductsOfDimensions
41
+ You can compute prefix products of `mapShape` dimension lengths.
42
+ getSumsOfProductsOfDimensions
43
+ You can compute prefix sums of `getProductsOfDimensions(mapShape)`.
44
+ getSumsOfProductsOfDimensionsNearest首
45
+ You can compute prefix sums of reversed dimension products for head-first coordinate arithmetic.
46
+ reverseLookup
47
+ You can find a key in a `dict` by matching a value.
48
+
49
+ Flow control
50
+ indicesMapShapeDimensionLengthsAreEqual
51
+ You can group dimension indices by repeated dimension lengths.
52
+ mapShapeIs2上nDimensions
53
+ You can test whether `mapShape` is a $2^n$-dimensional map, optionally with a minimum dimension count.
54
+
55
+ References
56
+ ----------
57
+ [1] mapFolding._e.dataBaskets.EliminationState
58
+ Internal package reference
59
+
60
+ """
61
+ from collections.abc import Iterable, Iterator, Mapping
62
+ from cytoolz.dicttoolz import dissoc as dissociatePiles
63
+ from cytoolz.functoolz import curry as syntacticCurry
64
+ from cytoolz.itertoolz import unique
65
+ from functools import partial, reduce
66
+ from gmpy2 import bit_clear, bit_mask, bit_set, xmpz
67
+ from hunterMakesPy import raiseIfNone
68
+ from itertools import accumulate
69
+ from mapFolding import inclusive, zeroIndexed
70
+ from mapFolding._e import (
71
+ Leaf, LeafOrPileRangeOfLeaves, PermutationSpace, Pile, PileRangeOfLeaves, PilesWithPileRangeOfLeaves, PinnedLeaves)
72
+ from mapFolding._e.filters import extractPinnedLeaves, thisIsALeaf, thisIsAPileRangeOfLeaves
73
+ from more_itertools import iter_index
74
+ from operator import add, mul
75
+ from typing import Any
76
+
77
+ #======== Group-by functions ================================================
78
+
79
+ def bifurcatePermutationSpace(permutationSpace: PermutationSpace) -> tuple[PinnedLeaves, PilesWithPileRangeOfLeaves]:
80
+ """Separate `permutationSpace` into two dictionaries: one of `pile: leaf` and one of `pile: pileRangeOfLeaves`.
81
+
82
+ Parameters
83
+ ----------
84
+ permutationSpace : PermutationSpace
85
+ Dictionary of `pile: leaf` and `pile: pileRangeOfLeaves`.
86
+
87
+ Returns
88
+ -------
89
+ leavesPinned, pilesWithPileRangeOfLeaves : tuple[PinnedLeaves, PilesWithPileRangeOfLeaves]
90
+ """
91
+ leavesPinned: PinnedLeaves = extractPinnedLeaves(permutationSpace)
92
+ return (leavesPinned, dissociatePiles(permutationSpace, *DOTkeys(leavesPinned))) # pyright: ignore[reportReturnType] # ty:ignore[invalid-return-type]
93
+
94
+ #======== Disaggregation and deconstruction functions ================================================
95
+
96
+ def DOTitems[文件, 文义](dictionary: Mapping[文件, 文义], /) -> Iterator[tuple[文件, 文义]]:
97
+ """Analogous to `dict.items()`: create an `Iterator` with the "items" from `dictionary`.
98
+
99
+ Parameters
100
+ ----------
101
+ dictionary : Mapping[文件, 文义]
102
+ Source mapping.
103
+
104
+ Returns
105
+ -------
106
+ aRiverOfItems : Iterator[tuple[文件, 文义]]
107
+ `Iterator` of items from `dictionary`.
108
+ """
109
+ return iter(dictionary.items())
110
+
111
+ def DOTkeys[个](dictionary: Mapping[个, Any], /) -> Iterator[个]:
112
+ """Analogous to `dict.keys()`: create an `Iterator` with the "keys" from `dictionary`.
113
+
114
+ Parameters
115
+ ----------
116
+ dictionary : Mapping[个, Any]
117
+ Source mapping.
118
+
119
+ Returns
120
+ -------
121
+ aRiverOfKeys : Iterator[个]
122
+ `Iterator` of keys from `dictionary`.
123
+ """
124
+ return iter(dictionary.keys())
125
+
126
+ def DOTvalues[个](dictionary: Mapping[Any, 个], /) -> Iterator[个]:
127
+ """Analogous to `dict.values()`: create an `Iterator` with the "values" from `dictionary`.
128
+
129
+ Parameters
130
+ ----------
131
+ dictionary : Mapping[Any, 个]
132
+ Source mapping.
133
+
134
+ Returns
135
+ -------
136
+ aRiverOfValues : Iterator[个]
137
+ `Iterator` of values from `dictionary`.
138
+ """
139
+ return iter(dictionary.values())
140
+
141
+ def getIteratorOfLeaves(pileRangeOfLeaves: PileRangeOfLeaves) -> Iterator[Leaf]:
142
+ """Convert `pileRangeOfLeaves` to an `Iterator` of `type` `int` `leaf`.
143
+
144
+ Parameters
145
+ ----------
146
+ pileRangeOfLeaves : PileRangeOfLeaves
147
+ An integer with one bit for each `leaf` in `leavesTotal`, plus an extra bit that means "I'm a `pileRangeOfLeaves` not a `leaf`.
148
+
149
+ Returns
150
+ -------
151
+ iteratorOfLeaves : Iterator[int]
152
+ An `Iterator` with one `int` for each `leaf` in `pileRangeOfLeaves`.
153
+
154
+ See Also
155
+ --------
156
+ https://gmpy2.readthedocs.io/en/latest/advmpz.html#gmpy2.xmpz.iter_set
157
+ """
158
+ iteratorOfLeaves: xmpz = xmpz(pileRangeOfLeaves)
159
+ iteratorOfLeaves[-1] = 0
160
+ return iteratorOfLeaves.iter_set()
161
+
162
+ #======== `PileRangeOfLeaves` functions ================================================
163
+
164
+ # TODO Should `PermutationSpace` be a subclass of `dict` so I can add methods? NOTE I REFUSE TO BE AN OBJECT-ORIENTED
165
+ # PROGRAMMER!!! But, I'll use some OOP if it makes sense. I think collections has some my-first-dict-subclass functions.
166
+ def DOTgetPileIfLeaf(permutationSpace: PermutationSpace, pile: Pile, default: Leaf | None = None) -> Leaf | None:
167
+ """Like `permutationSpace.get(pile)`, but only return a `leaf` or `default`."""
168
+ ImaLeaf: LeafOrPileRangeOfLeaves | None = permutationSpace.get(pile)
169
+ if thisIsALeaf(ImaLeaf):
170
+ return ImaLeaf
171
+ return default
172
+
173
+ def DOTgetPileIfPileRangeOfLeaves(permutationSpace: PermutationSpace, pile: Pile, default: PileRangeOfLeaves | None = None) -> PileRangeOfLeaves | None:
174
+ """You can read `permutationSpace[pile]` only when `permutationSpace[pile]` is a `PileRangeOfLeaves`.
175
+
176
+ This function is a typed analogue of `dict.get`. The function returns a `PileRangeOfLeaves` when `permutationSpace[pile]` is a
177
+ `PileRangeOfLeaves`, and the function returns `default` when `permutationSpace[pile]` is a `Leaf` or `None`.
178
+
179
+ Parameters
180
+ ----------
181
+ permutationSpace : PermutationSpace
182
+ Dictionary that maps each `Pile` to either a pinned `Leaf` or a `PileRangeOfLeaves` domain.
183
+ pile : Pile
184
+ `Pile` key to look up.
185
+ default : PileRangeOfLeaves | None = None
186
+ Value to return when `permutationSpace[pile]` is not a `PileRangeOfLeaves`.
187
+
188
+ Returns
189
+ -------
190
+ pileRangeOfLeavesOrNone : PileRangeOfLeaves | None
191
+ `PileRangeOfLeaves` value from `permutationSpace[pile]`, or `default`.
192
+
193
+ Examples
194
+ --------
195
+ The function is used to retrieve a domain bitset with a fallback mask.
196
+
197
+ pileRangeOfLeaves: PileRangeOfLeaves = raiseIfNone(DOTgetPileIfPileRangeOfLeaves(permutationSpace, domain[index], default=bit_mask(len(permutationSpace))))
198
+
199
+ References
200
+ ----------
201
+ [1] mapFolding._e.filters.thisIsAPileRangeOfLeaves
202
+ Internal package reference
203
+ [2] gmpy2 - Integer arithmetic
204
+ https://gmpy2.readthedocs.io/en/latest/
205
+ [3] hunterMakesPy - Context7
206
+ https://context7.com/hunterhogan/huntermakespy
207
+
208
+ """
209
+ ImaPileRangeOfLeaves: LeafOrPileRangeOfLeaves | None = permutationSpace.get(pile)
210
+ if thisIsAPileRangeOfLeaves(ImaPileRangeOfLeaves):
211
+ return ImaPileRangeOfLeaves
212
+ return default
213
+
214
+ # TODO Improve semiotics of identifier `getAntiPileRangeOfLeaves`.
215
+ def getAntiPileRangeOfLeaves(leavesTotal: int, leaves: Iterable[Leaf]) -> PileRangeOfLeaves:
216
+ """You can build a complement `PileRangeOfLeaves` by clearing each `Leaf` bit in `leaves`.
217
+
218
+ The returned `PileRangeOfLeaves` contains a bit for every `Leaf` in `range(leavesTotal)` except each `Leaf` in `leaves`.
219
+ The returned `PileRangeOfLeaves` also preserves the sentinel bit that indicates the value is a `PileRangeOfLeaves`.
220
+
221
+ Parameters
222
+ ----------
223
+ leavesTotal : int
224
+ Total number of leaves in the map.
225
+ leaves : Iterable[Leaf]
226
+ Iterable of `Leaf` indices to exclude from the returned `PileRangeOfLeaves`.
227
+
228
+ Returns
229
+ -------
230
+ antiPileRangeOfLeaves : PileRangeOfLeaves
231
+ `PileRangeOfLeaves` bitset containing each allowed `Leaf` plus the `PileRangeOfLeaves` sentinel bit.
232
+
233
+ Examples
234
+ --------
235
+ The function is used to start from the full domain.
236
+
237
+ antiPileRangeOfLeaves: PileRangeOfLeaves = getAntiPileRangeOfLeaves(state.leavesTotal, frozenset())
238
+
239
+ The function is used to exclude every `Leaf` not in a crease relation.
240
+
241
+ antiPileRangeOfLeaves = getAntiPileRangeOfLeaves(state.leavesTotal, set(range(state.leavesTotal)).difference(leavesCrease))
242
+
243
+ References
244
+ ----------
245
+ [1] gmpy2 - Integer arithmetic
246
+ https://gmpy2.readthedocs.io/en/latest/
247
+ [2] mapFolding.inclusive
248
+ Internal package reference
249
+
250
+ """
251
+ return reduce(bit_clear, leaves, bit_mask(leavesTotal + inclusive))
252
+
253
+ def getPileRangeOfLeaves(leavesTotal: int, leaves: Iterable[Leaf]) -> PileRangeOfLeaves:
254
+ """You can build a `PileRangeOfLeaves` by setting each `Leaf` bit in `leaves`.
255
+
256
+ The returned `PileRangeOfLeaves` contains the sentinel bit that indicates the value is a `PileRangeOfLeaves`. The returned
257
+ `PileRangeOfLeaves` also contains a bit for each `Leaf` in `leaves`.
258
+
259
+ Parameters
260
+ ----------
261
+ leavesTotal : int
262
+ Total number of leaves in the map.
263
+ leaves : Iterable[Leaf]
264
+ Iterable of `Leaf` indices to include in the returned `PileRangeOfLeaves`.
265
+
266
+ Returns
267
+ -------
268
+ pileRangeOfLeaves : PileRangeOfLeaves
269
+ `PileRangeOfLeaves` bitset containing each `Leaf` in `leaves` plus the `PileRangeOfLeaves` sentinel bit.
270
+
271
+ Examples
272
+ --------
273
+ The function is used to create a domain bitset before normalizing with `JeanValjean`.
274
+
275
+ permutationSpace2上nDomainDefaults: PermutationSpace = {pile: raiseIfNone(JeanValjean(getPileRangeOfLeaves(state.leavesTotal, pileRangeOfLeaves)))
276
+ for pile, pileRangeOfLeaves in getDictionaryPileRanges(state).items()}
277
+
278
+ References
279
+ ----------
280
+ [1] gmpy2 - Integer arithmetic
281
+ https://gmpy2.readthedocs.io/en/latest/
282
+ [2] mapFolding._e._beDRY.JeanValjean
283
+ Internal package reference
284
+
285
+ """
286
+ return reduce(bit_set, leaves, bit_set(0, leavesTotal))
287
+
288
+ def JeanValjean(p24601: PileRangeOfLeaves, /) -> LeafOrPileRangeOfLeaves | None:
289
+ """You can normalize a `PileRangeOfLeaves` into a `Leaf` or `None` when the range is degenerate.
290
+
291
+ When `p24601` is a `PileRangeOfLeaves`, `p24601` contains one sentinel bit that indicates the value is a `PileRangeOfLeaves`.
292
+ This function interprets the total set-bit count as a compact encoding of domain cardinality.
293
+
294
+ - When `p24601.bit_count() == 1`, `p24601` is an empty domain. The only set bit is the sentinel bit, so the function returns `None`.
295
+ - When `p24601.bit_count() == 2`, `p24601` contains exactly one `Leaf` plus the sentinel bit. The function converts the range to a
296
+ `Leaf` by returning `raiseIfNone(p24601.bit_scan1())`.
297
+ - Otherwise, the function returns `p24601` unchanged.
298
+
299
+ Parameters
300
+ ----------
301
+ p24601 : PileRangeOfLeaves
302
+ Candidate `PileRangeOfLeaves` value.
303
+
304
+ Returns
305
+ -------
306
+ leafOrPileRangeOfLeavesOrNone : LeafOrPileRangeOfLeaves | None
307
+ A `Leaf` when `p24601` encodes exactly one leaf, `None` when `p24601` encodes an empty domain, or `p24601` otherwise.
308
+
309
+ Examples
310
+ --------
311
+ The function is used to normalize a masked domain.
312
+
313
+ if (ImaLeafOrPileRangeOfLeavesNotAWalrusSubscript := JeanValjean(pileRangeOfLeavesAND(antiPileRangeOfLeaves, pileRangeOfLeaves))) is None:
314
+ return {}
315
+
316
+ The function is used to normalize per-pile domains into pinned leaves when possible.
317
+
318
+ permutationSpace2上nDomainDefaults: PermutationSpace = {pile: raiseIfNone(JeanValjean(getPileRangeOfLeaves(state.leavesTotal, pileRangeOfLeaves)))
319
+ for pile, pileRangeOfLeaves in getDictionaryPileRanges(state).items()}
320
+
321
+ References
322
+ ----------
323
+ [1] gmpy2 - Integer arithmetic
324
+ https://gmpy2.readthedocs.io/en/latest/
325
+ [2] mapFolding._e.filters.thisIsAPileRangeOfLeaves
326
+ Internal package reference
327
+ [3] hunterMakesPy - Context7
328
+ https://context7.com/hunterhogan/huntermakespy
329
+
330
+ """
331
+ whoAmI: LeafOrPileRangeOfLeaves | None = p24601
332
+ if thisIsAPileRangeOfLeaves(p24601):
333
+ if p24601.bit_count() == 1:
334
+ whoAmI = None
335
+ elif p24601.bit_count() == 2:
336
+ whoAmI = raiseIfNone(p24601.bit_scan1())
337
+ return whoAmI
338
+
339
+ @syntacticCurry
340
+ def pileRangeOfLeavesAND(pileRangeOfLeavesDISPOSABLE: PileRangeOfLeaves, pileRangeOfLeaves: PileRangeOfLeaves) -> PileRangeOfLeaves:
341
+ """Modify `pileRangeOfLeaves` by bitwise AND with `pileRangeOfLeavesDISPOSABLE`.
342
+
343
+ Important
344
+ ---------
345
+ The order of the parameters is likely the opposite of what you expect. This is to facilitate currying.
346
+ """
347
+ return pileRangeOfLeaves & pileRangeOfLeavesDISPOSABLE
348
+
349
+ #======== Be DRY functions ================================================
350
+
351
+ def getProductsOfDimensions(mapShape: tuple[int, ...]) -> tuple[int, ...]:
352
+ """You can compute prefix products of each dimension length in `mapShape`.
353
+
354
+ The returned tuple starts with the product of zero dimensions, which is `1`. Each subsequent element multiplies the next
355
+ dimension length in `mapShape`.
356
+
357
+ Parameters
358
+ ----------
359
+ mapShape : tuple[int, ...]
360
+ Map shape as a tuple of dimension lengths.
361
+
362
+ Returns
363
+ -------
364
+ productsOfDimensions : tuple[int, ...]
365
+ Tuple of prefix products with `productsOfDimensions[0] == 1`.
366
+
367
+ Examples
368
+ --------
369
+ The function is used during `EliminationState` initialization.
370
+
371
+ self.productsOfDimensions = getProductsOfDimensions(self.mapShape)
372
+
373
+ References
374
+ ----------
375
+ [1] itertools.accumulate
376
+ https://docs.python.org/3/library/itertools.html#itertools.accumulate
377
+ [2] operator.mul
378
+ https://docs.python.org/3/library/operator.html#operator.mul
379
+ [3] mapFolding._e.dataBaskets.EliminationState
380
+ Internal package reference
381
+
382
+ """
383
+ return tuple(accumulate(mapShape, mul, initial=1))
384
+
385
+ def getSumsOfProductsOfDimensions(mapShape: tuple[int, ...]) -> tuple[int, ...]:
386
+ """You can compute prefix sums of `getProductsOfDimensions(mapShape)`.
387
+
388
+ The returned tuple starts with the sum of zero products, which is `0`. Each subsequent element adds the next product from
389
+ `getProductsOfDimensions(mapShape)`.
390
+
391
+ Parameters
392
+ ----------
393
+ mapShape : tuple[int, ...]
394
+ Map shape as a tuple of dimension lengths.
395
+
396
+ Returns
397
+ -------
398
+ sumsOfProductsOfDimensions : tuple[int, ...]
399
+ Tuple of prefix sums with `sumsOfProductsOfDimensions[0] == 0`.
400
+
401
+ Examples
402
+ --------
403
+ The function is used during `EliminationState` initialization.
404
+
405
+ self.sumsOfProductsOfDimensions = getSumsOfProductsOfDimensions(self.mapShape)
406
+
407
+ References
408
+ ----------
409
+ [1] itertools.accumulate
410
+ https://docs.python.org/3/library/itertools.html#itertools.accumulate
411
+ [2] operator.add
412
+ https://docs.python.org/3/library/operator.html#operator.add
413
+ [3] mapFolding._e._beDRY.getProductsOfDimensions
414
+ Internal package reference
415
+ [4] mapFolding._e.dataBaskets.EliminationState
416
+ Internal package reference
417
+
418
+ """
419
+ return tuple(accumulate(getProductsOfDimensions(mapShape), add, initial=0))
420
+
421
+ def getSumsOfProductsOfDimensionsNearest首(productsOfDimensions: tuple[int, ...], dimensionsTotal: int | None = None, dimensionFrom首: int | None = None) -> tuple[int, ...]:
422
+ """Get a useful list of numbers.
423
+
424
+ This list of numbers is useful because I am using integers as a proxy for Cartesian coordinates in multidimensional space--and
425
+ because I am trying to abstract the coordinates whether I am enumerating from the origin (0, 0, ..., 0) as represented by the
426
+ integer 0 or from the "anti-origin", which is represented by an integer: but that integer varies based on the mapShape.
427
+
428
+ By using products of dimensions and sums of products of dimensions, I can use the integer-as-coordinate by referencing its
429
+ relative location in the products and sums of products of dimensions.
430
+
431
+ `sumsOfProductsOfDimensionsNearest首` is yet another perspective on these abstractions. Instead of ordering the products in
432
+ ascending order, I order them descending. Then I sum the descending-ordered products.
433
+
434
+ (At least I think that is what I am doing. 2025 December 29.)
435
+
436
+ `dimensionFrom首` almost certainly needs a better identifier. The purpose of the parameter is to define the list of products
437
+ of which I want the sums.
438
+
439
+ """
440
+ if dimensionsTotal is None:
441
+ dimensionsTotal = len(productsOfDimensions) - 1
442
+
443
+ if dimensionFrom首 is None:
444
+ dimensionFrom首 = dimensionsTotal
445
+
446
+ productsOfDimensionsTruncator: int = dimensionFrom首 - (dimensionsTotal + zeroIndexed)
447
+
448
+ productsOfDimensionsFrom首: tuple[int, ...] = productsOfDimensions[0:productsOfDimensionsTruncator][::-1]
449
+
450
+ sumsOfProductsOfDimensionsNearest首: tuple[int, ...] = tuple(
451
+ sum(productsOfDimensionsFrom首[0:aProduct], start=0)
452
+ for aProduct in range(len(productsOfDimensionsFrom首) + inclusive)
453
+ )
454
+ return sumsOfProductsOfDimensionsNearest首
455
+
456
+ def reverseLookup[文件, 文义](dictionary: dict[文件, 文义], keyValue: 文义) -> 文件 | None:
457
+ """Return the key in `dictionary` that corresponds to `keyValue`.
458
+
459
+ - I assume all `dictionary.values()` are distinct. If multiple keys contain `keyValue`, the returned key is not predictable.
460
+ - I return `None` if no key maps to `keyValue`, but it is not an efficient way to check for membership.
461
+ - If you *know* a value will be returned, consider combining with `hunterMakesPy.raiseIfNone`.
462
+ """
463
+ for key, value in dictionary.items():
464
+ if value == keyValue:
465
+ return key
466
+ return None
467
+
468
+ #======== Flow control ================================================
469
+
470
+ def indicesMapShapeDimensionLengthsAreEqual(mapShape: tuple[int, ...]) -> Iterator[tuple[int, ...]]:
471
+ """You can group dimension indices in `mapShape` by repeated dimension lengths.
472
+
473
+ The returned `Iterator` yields one `tuple` per distinct dimension length in `mapShape` where the dimension length occurs more
474
+ than once. Each yielded `tuple` contains each index where `mapShape[index]` equals the repeated dimension length.
475
+
476
+ Parameters
477
+ ----------
478
+ mapShape : tuple[int, ...]
479
+ Map shape as a tuple of dimension lengths.
480
+
481
+ Returns
482
+ -------
483
+ iteratorIndicesSameDimensionLength : Iterator[tuple[int, ...]]
484
+ Iterator of index tuples. Each tuple has length at least 2.
485
+
486
+ Examples
487
+ --------
488
+ The function is used to iterate repeated dimension magnitudes during elimination.
489
+
490
+ for indicesSameDimensionLength in indicesMapShapeDimensionLengthsAreEqual(state.mapShape):
491
+ state.Theorem4Multiplier *= factorial(len(indicesSameDimensionLength))
492
+ for index_k, index_r in pairwise(indicesSameDimensionLength):
493
+ state = excludeLeaf_rBeforeLeaf_k(state, state.productsOfDimensions[index_k], state.productsOfDimensions[index_r])
494
+
495
+ References
496
+ ----------
497
+ [1] cytoolz.itertoolz.unique
498
+ https://toolz.readthedocs.io/en/latest/api.html#toolz.itertoolz.unique
499
+ [2] more_itertools.iter_index
500
+ https://more-itertools.readthedocs.io/en/stable/api.html#more_itertools.iter_index
501
+ [3] mapFolding._e.algorithms.elimination.theorem4
502
+ Internal package reference
503
+
504
+ """
505
+ return filter(lambda indices: 1 < len(indices), map(tuple, map(partial(iter_index, mapShape), unique(mapShape))))
506
+
507
+ # NOTE This 2^n-dimensional function is in this module to avoid `import` problems.
508
+ def mapShapeIs2上nDimensions(mapShape: tuple[int, ...], *, youMustBeDimensionsTallToPinThis: int = 3) -> bool:
509
+ """You can test whether `mapShape` is a $2^n$-dimensional map with a configurable minimum dimension count.
510
+
511
+ This predicate is used as a flow guard for algorithms and pinning rules that only apply to the `mapShape == (2,) * n` special
512
+ case. The predicate returns `True` only when `len(mapShape) >= youMustBeDimensionsTallToPinThis` and each `dimensionLength` in
513
+ `mapShape` equals `2`.
514
+
515
+ Parameters
516
+ ----------
517
+ mapShape : tuple[int, ...]
518
+ Map shape as a tuple of dimension lengths.
519
+ youMustBeDimensionsTallToPinThis : int = 3
520
+ Minimum number of dimensions required before treating a $2^n$-dimensional special case as eligible.
521
+
522
+ Returns
523
+ -------
524
+ is2上nDimensions : bool
525
+ `True` when `mapShape` is a $2^n$-dimensional map with the required minimum dimension count.
526
+
527
+ Examples
528
+ --------
529
+ The predicate is used to gate pinning logic.
530
+
531
+ if not mapShapeIs2上nDimensions(state.mapShape):
532
+ return state
533
+
534
+ The predicate is used to gate deeper special cases.
535
+
536
+ if not mapShapeIs2上nDimensions(state.mapShape, youMustBeDimensionsTallToPinThis=5):
537
+ return state
538
+
539
+ References
540
+ ----------
541
+ [1] mapFolding._e.pin2上nDimensions.pinPilesAtEnds
542
+ Internal package reference
543
+ [2] mapFolding._e._dataDynamic.addPileRangesOfLeaves
544
+ Internal package reference
545
+
546
+ """
547
+ return (youMustBeDimensionsTallToPinThis <= len(mapShape)) and all(dimensionLength == 2 for dimensionLength in mapShape)