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
@@ -1,184 +0,0 @@
1
- # ruff: noqa: ERA001
2
- from concurrent.futures import as_completed, Future, ProcessPoolExecutor
3
- from copy import deepcopy
4
- from itertools import pairwise, product as CartesianProduct
5
- from mapFolding.algorithms.patternFinder import getDictionaryIndexLeafRanges
6
- from mapFolding.algorithms.pinning2Dn import pinByFormula, secondOrderLeaves, secondOrderPilings
7
- from mapFolding.dataBaskets import EliminationState
8
- from math import factorial, prod
9
- from more_itertools import iter_index, unique
10
- from ortools.sat.python import cp_model
11
- from tqdm import tqdm
12
- from typing import Final
13
-
14
- def findValidFoldings(state: EliminationState) -> int:
15
- model = cp_model.CpModel()
16
-
17
- listIndicesLeafInPilingsOrder: list[cp_model.IntVar] = [model.NewIntVar(0, state.leavesTotal - 1, f"indexLeafInPile[{pile}]") for pile in range(state.leavesTotal)]
18
- listPilingsInIndexLeafOrder: list[cp_model.IntVar] = [model.NewIntVar(0, state.leavesTotal - 1, f"pileOfIndexLeaf[{indexLeaf}]") for indexLeaf in range(state.leavesTotal)]
19
- model.AddInverse(listIndicesLeafInPilingsOrder, listPilingsInIndexLeafOrder)
20
-
21
- # ------- Leaf domain restrictions from dictionaryLeafRanges -----------------------------
22
- if (state.dimensionsTotal > 2) and (state.mapShape[0] == 2):
23
- dictionaryLeafRanges: Final[dict[int, range]] = getDictionaryIndexLeafRanges(state)
24
- for indexLeaf, rangePilings in dictionaryLeafRanges.items():
25
- if indexLeaf < 2:
26
- continue
27
- model.AddAllowedAssignments([listPilingsInIndexLeafOrder[indexLeaf]], [(pile,) for pile in rangePilings])
28
-
29
- if state.leavesTotal in [64, 128]:
30
- from mapFolding.algorithms.patternFinder import getDictionaryAddends4Next # noqa: PLC0415
31
- dictionaryAddends4Next: Final[dict[int, list[int]]] = getDictionaryAddends4Next(state)
32
- dictionaryNextLeaf: dict[int, list[int]] = {}
33
- for indexLeaf, listDifferences in dictionaryAddends4Next.items():
34
- listAllowedNextLeaves: list[int] = []
35
- for difference in listDifferences:
36
- listAllowedNextLeaves.append(indexLeaf + difference) # noqa: PERF401
37
- dictionaryNextLeaf[indexLeaf] = listAllowedNextLeaves
38
-
39
- # ------- Constraints from dictionaryNextLeaf -----------------------------
40
- for indexLeaf, listAllowedNextLeaves in dictionaryNextLeaf.items():
41
- if not listAllowedNextLeaves:
42
- continue
43
- for pile in range(state.leavesTotal - 1):
44
- currentLeafAtThisPile: cp_model.IntVar = listIndicesLeafInPilingsOrder[pile]
45
- nextLeafAtNextPile: cp_model.IntVar = listIndicesLeafInPilingsOrder[pile + 1]
46
-
47
- isCurrentLeafEqualToIndexLeaf: cp_model.IntVar = model.NewBoolVar(f"pile{pile}_leaf{indexLeaf}")
48
- model.Add(currentLeafAtThisPile == indexLeaf).OnlyEnforceIf(isCurrentLeafEqualToIndexLeaf)
49
- model.Add(currentLeafAtThisPile != indexLeaf).OnlyEnforceIf(isCurrentLeafEqualToIndexLeaf.Not())
50
-
51
- model.AddAllowedAssignments([nextLeafAtNextPile], [(leaf,) for leaf in listAllowedNextLeaves]).OnlyEnforceIf(isCurrentLeafEqualToIndexLeaf)
52
-
53
- # ------- Manual concurrency -----------------------------
54
- for pile, indexLeaf in state.pinnedLeaves.items():
55
- model.Add(listIndicesLeafInPilingsOrder[pile] == indexLeaf)
56
-
57
- # ------- Lunnon Theorem 2(a): foldsTotal is divisible by leavesTotal; fix in pile at 0, indexLeaf at 0 -----------------------------
58
- model.Add(listIndicesLeafInPilingsOrder[0] == 0)
59
-
60
- # ------- Lunnon Theorem 4: "G(p^d) is divisible by d!p^d." ---------------
61
- for listIndicesSameMagnitude in [list(iter_index(state.mapShape, magnitude)) for magnitude in unique(state.mapShape)]:
62
- if len(listIndicesSameMagnitude) > 1:
63
- state.subsetsTheorem4 *= factorial(len(listIndicesSameMagnitude))
64
- for dimensionAlpha, dimensionBeta in pairwise(listIndicesSameMagnitude):
65
- k, r = (prod(state.mapShape[0:dimension]) for dimension in (dimensionAlpha, dimensionBeta))
66
- model.Add(listPilingsInIndexLeafOrder[k] < listPilingsInIndexLeafOrder[r])
67
-
68
- # ------- Lunnon Theorem 2(b): "If some [magnitude in state.mapShape] > 2, [foldsTotal] is divisible by 2 * [leavesTotal]." -----------------------------
69
- if state.subsetsTheorem4 == 1:
70
- for aDimension in range(state.dimensionsTotal - 1, -1, -1):
71
- if state.mapShape[aDimension] > 2:
72
- state.subsetsTheorem2 = 2
73
- indexLeafOrigin下_aDimension: int = prod(state.mapShape[0:aDimension])
74
- model.Add(listPilingsInIndexLeafOrder[indexLeafOrigin下_aDimension] < listPilingsInIndexLeafOrder[2 * indexLeafOrigin下_aDimension])
75
- break
76
-
77
- # ------- Forbidden inequalities -----------------------------
78
- def addLessThan(comparatorLeft: int, comparatorRight: int) -> cp_model.IntVar:
79
- ruleΩ: cp_model.IntVar = model.NewBoolVar(f"this_{comparatorLeft}_lessThan_{comparatorRight}")
80
- model.Add(listPilingsInIndexLeafOrder[comparatorLeft] < listPilingsInIndexLeafOrder[comparatorRight]).OnlyEnforceIf(ruleΩ)
81
- model.Add(listPilingsInIndexLeafOrder[comparatorLeft] >= listPilingsInIndexLeafOrder[comparatorRight]).OnlyEnforceIf(ruleΩ.Not())
82
- return ruleΩ
83
-
84
- def addForbiddenInequalityCycle(k: int, r: int, k1: int, r1: int) -> None:
85
- k__小于_r: cp_model.IntVar = addLessThan(k, r) # 小, xiǎo: small, less; as in 李小龍, Lǐ Xiǎolóng, Lǐ little dragon, aka Bruce Lee
86
- r1_小于_k: cp_model.IntVar = addLessThan(r1, k)
87
- k1_小于_r1: cp_model.IntVar = addLessThan(k1, r1)
88
- model.AddBoolOr([k1_小于_r1.Not(), r1_小于_k.Not(), k__小于_r.Not()]) # [k+1 < r+1 < k < r]
89
-
90
- r__小于_k1: cp_model.IntVar = addLessThan(r, k1)
91
- model.AddBoolOr([r1_小于_k.Not(), k__小于_r.Not(), r__小于_k1.Not()]) # [r+1 < k < r < k+1]
92
-
93
- model.AddBoolOr([k__小于_r.Not(), r__小于_k1.Not(), k1_小于_r1.Not()]) # [k < r < k+1 < r+1]
94
-
95
- k__小于_r1: cp_model.IntVar = addLessThan(k, r1)
96
- r1_小于_k1: cp_model.IntVar = addLessThan(r1, k1)
97
- k1_小于_r: cp_model.IntVar = addLessThan(k1, r)
98
- model.AddBoolOr([k__小于_r1.Not(), r1_小于_k1.Not(), k1_小于_r.Not()]) # [k < r+1 < k+1 < r]
99
-
100
- def indexLeaf2IndicesCartesian(indexLeaf: int) -> tuple[int, ...]:
101
- return tuple((indexLeaf // prod(state.mapShape[0:dimension])) % state.mapShape[dimension] for dimension in range(state.dimensionsTotal))
102
-
103
- def indexLeafNextCrease(indexLeaf: int, dimension: int) -> int | None:
104
- indexLeafNext: int | None = None
105
- if indexLeaf2IndicesCartesian(indexLeaf)[dimension] + 1 < state.mapShape[dimension]:
106
- indexLeafNext = indexLeaf + prod(state.mapShape[0:dimension])
107
- return indexLeafNext
108
-
109
- for k, r in CartesianProduct(range(state.leavesTotal-1), range(1, state.leavesTotal-1)):
110
- if k == r:
111
- continue
112
-
113
- k下_indicesCartesian: tuple[int, ...] = indexLeaf2IndicesCartesian(k) # 下, xià: below, subscript
114
- r下_indicesCartesian: tuple[int, ...] = indexLeaf2IndicesCartesian(r)
115
-
116
- for aDimension in range(state.dimensionsTotal):
117
- k1下_aDimension: int | None = indexLeafNextCrease(k, aDimension)
118
- r1下_aDimension: int | None = indexLeafNextCrease(r, aDimension)
119
-
120
- if k1下_aDimension and r1下_aDimension and ((k下_indicesCartesian[aDimension] - r下_indicesCartesian[aDimension]) % 2 == 0):
121
- addForbiddenInequalityCycle(k, r, k1下_aDimension, r1下_aDimension)
122
-
123
- # ------- Solver -----------------------------
124
- solver = cp_model.CpSolver()
125
- solver.parameters.enumerate_all_solutions = True
126
-
127
- solver.parameters.log_search_progress = False
128
-
129
- class FoldingCollector(cp_model.CpSolverSolutionCallback):
130
- def __init__(self, _listOfIndicesLeafInPilingsOrder: list[cp_model.IntVar]) -> None:
131
- super().__init__()
132
- self._listOfIndicesLeafInPilingsOrder: list[cp_model.IntVar] = _listOfIndicesLeafInPilingsOrder
133
- self.listFoldings: list[list[int]] = []
134
-
135
- def OnSolutionCallback(self) -> None:
136
- self.listFoldings.append([self.Value(indexLeaf) for indexLeaf in self._listOfIndicesLeafInPilingsOrder]) # pyright: ignore[reportUnknownMemberType]
137
-
138
- foldingCollector = FoldingCollector(listIndicesLeafInPilingsOrder)
139
- solver.Solve(model, foldingCollector)
140
-
141
- # if not foldingCollector.listFoldings:
142
- # print("\n",state.pinnedLeaves)
143
- # if foldingCollector.listFoldings:
144
- # print(*foldingCollector.listFoldings, sep="\n")
145
-
146
- return len(foldingCollector.listFoldings) * state.subsetsTheorem2 * state.subsetsTheorem4
147
-
148
- def doTheNeedful(state: EliminationState, workersMaximum: int) -> EliminationState:
149
- """Find the quantity of valid foldings for a given map."""
150
- # state = pinByFormula(state)
151
- # state = secondOrderLeaves(state)
152
- # state = secondOrderPilings(state)
153
-
154
- if state.listPinnedLeaves:
155
-
156
- with ProcessPoolExecutor(workersMaximum) as concurrencyManager:
157
- listClaimTickets: list[Future[int]] = []
158
-
159
- listPinnedLeavesCopy: list[dict[int, int]] = deepcopy(state.listPinnedLeaves)
160
- state.listPinnedLeaves = []
161
- for pinnedLeaves in listPinnedLeavesCopy:
162
- stateCopy: EliminationState = deepcopy(state)
163
- stateCopy.pinnedLeaves = pinnedLeaves
164
- listClaimTickets.append(concurrencyManager.submit(findValidFoldings, stateCopy))
165
-
166
- for claimTicket in tqdm(as_completed(listClaimTickets), total=len(listClaimTickets), disable=False):
167
- state.groupsOfFolds += claimTicket.result()
168
-
169
- elif workersMaximum > 1:
170
- pile = 2
171
- with ProcessPoolExecutor(workersMaximum) as concurrencyManager:
172
- listClaimTickets: list[Future[int]] = []
173
- for indicesLeaf in range(1, state.leavesTotal):
174
- stateCopy: EliminationState = deepcopy(state)
175
- stateCopy.pinnedLeaves = {pile: indicesLeaf}
176
- listClaimTickets.append(concurrencyManager.submit(findValidFoldings, stateCopy))
177
-
178
- for claimTicket in listClaimTickets:
179
- state.groupsOfFolds += claimTicket.result()
180
-
181
- else:
182
- state.groupsOfFolds = findValidFoldings(deepcopy(state))
183
-
184
- return state
@@ -1,131 +0,0 @@
1
- from cytoolz.functoolz import curry as syntacticCurry
2
- from cytoolz.itertoolz import groupby as toolz_groupby
3
- from itertools import pairwise, repeat
4
- from mapFolding.algorithms.eliminationCount import count, permutands
5
- from mapFolding.algorithms.iff import productOfDimensions
6
- from mapFolding.algorithms.pinning2Dn import pinByFormula
7
- from mapFolding.dataBaskets import EliminationState
8
- from math import factorial
9
- from more_itertools import flatten, iter_index, unique
10
- from typing import Any, TYPE_CHECKING
11
-
12
- if TYPE_CHECKING:
13
- from collections.abc import Callable
14
-
15
- @syntacticCurry
16
- def _excludeLeafAtColumn(sequencePinnedLeaves: list[dict[int, int]], leaf: int, column: int, leavesTotal: int) -> list[dict[int, int]]:
17
- listPinnedLeaves: list[dict[int, int]] = []
18
- for pinnedLeaves in sequencePinnedLeaves:
19
- leafAtColumn: int | None = pinnedLeaves.get(column)
20
- if leaf == leafAtColumn:
21
- continue # Exclude `leaf` previously fixed at `column`.
22
- if (leafAtColumn is not None) or (leaf in pinnedLeaves.values()): # `column` is occupied, which excludes `leaf`.
23
- listPinnedLeaves.append(pinnedLeaves) # Or `leaf` is pinned, but not at `column`.
24
- continue
25
- deconstructedPinnedLeaves: dict[int, dict[int, int]] = deconstructPinnedLeaves(pinnedLeaves, column, leavesTotal)
26
- deconstructedPinnedLeaves.pop(leaf) # Exclude dictionary with `leaf` fixed at `column`.
27
- listPinnedLeaves.extend(deconstructedPinnedLeaves.values())
28
- return listPinnedLeaves
29
-
30
- def pinLeafAtColumn(sequencePinnedLeaves: list[dict[int, int]], leaf: int, column: int, leavesTotal: int) -> list[dict[int, int]]:
31
- listPinnedLeaves: list[dict[int, int]] = []
32
- for pinnedLeaves in sequencePinnedLeaves:
33
- leafAtColumn: int | None = pinnedLeaves.get(column)
34
- if leaf == leafAtColumn:
35
- listPinnedLeaves.append(pinnedLeaves) # That was easy.
36
- continue
37
- if leafAtColumn is not None: # `column` is occupied, but not by `leaf`, so exclude it.
38
- continue
39
- listPinnedLeaves.append(deconstructPinnedLeaves(pinnedLeaves, column, leavesTotal).pop(leaf)) # Keep the dictionary with `leaf` fixed at `column`.
40
- return listPinnedLeaves
41
-
42
- @syntacticCurry
43
- def _isPinnedAtColumn(pinnedLeaves: dict[int, int], leaf: int, column: int) -> bool:
44
- return leaf == pinnedLeaves.get(column)
45
-
46
- def _segregatePinnedAtColumn(listPinnedLeaves: list[dict[int, int]], leaf: int, column: int) -> tuple[list[dict[int, int]], list[dict[int, int]]]:
47
- isPinned: Callable[[dict[int, int]], bool] = _isPinnedAtColumn(leaf=leaf, column=column)
48
- grouped: dict[bool, list[dict[int, int]]] = toolz_groupby(isPinned, listPinnedLeaves)
49
- return (grouped.get(False, []), grouped.get(True, []))
50
-
51
- @syntacticCurry
52
- def atColumnPinLeaf(pinnedLeaves: dict[int, int], column: int, leaf: int) -> dict[int, int]:
53
- dictionaryPinnedLeaves: dict[int, int] = dict(pinnedLeaves)
54
- dictionaryPinnedLeaves[column] = leaf
55
- return dictionaryPinnedLeaves
56
-
57
- def deconstructPinnedLeaves(pinnedLeaves: dict[int, int], column: int, leavesTotal: int) -> dict[int, dict[int, int]]:
58
- """Replace `pinnedLeaves`, which doesn't pin a leaf at `column`, with the equivalent group of dictionaries, which each pin a distinct leaf at `column`.
59
-
60
- Parameters
61
- ----------
62
- pinnedLeaves : dict[int, int]
63
- Dictionary to divide and replace.
64
- column : int
65
- Column in which to pin a leaf.
66
-
67
- Returns
68
- -------
69
- deconstructedPinnedLeaves : dict[int, dict[int, int]]
70
- Dictionary mapping from `leaf` pinned at `column` to the dictionary with the `leaf` pinned at `column`.
71
- """
72
- leafAtColumn: int | None = pinnedLeaves.get(column)
73
- if leafAtColumn is not None:
74
- deconstructedPinnedLeaves: dict[int, dict[int, int]] = {leafAtColumn: pinnedLeaves}
75
- else:
76
- pin: Callable[[int], dict[int, int]] = atColumnPinLeaf(pinnedLeaves, column)
77
- deconstructedPinnedLeaves = {leaf: pin(leaf) for leaf in permutands(pinnedLeaves, leavesTotal)}
78
- return deconstructedPinnedLeaves
79
-
80
- def DOTvalues[个](dictionary: dict[Any, 个]) -> list[个]:
81
- return list(dictionary.values())
82
-
83
- def deconstructListPinnedLeaves(listPinnedLeaves: list[dict[int, int]], column: int, leavesTotal: int) -> list[dict[int, int]]:
84
- return list(flatten(map(DOTvalues, map(deconstructPinnedLeaves, listPinnedLeaves, repeat(column), repeat(leavesTotal)))))
85
-
86
- def _excludeLeafRBeforeLeafK(state: EliminationState, k: int, r: int, columnK: int, listPinnedLeaves: list[dict[int, int]]) -> list[dict[int, int]]:
87
- listPinnedLeaves = deconstructListPinnedLeaves(listPinnedLeaves, columnK, state.leavesTotal)
88
- listPinned: list[dict[int, int]] = []
89
- for column in range(columnK, state.columnLast + 1):
90
- (listPinnedLeaves, listPinnedAtColumn) = _segregatePinnedAtColumn(listPinnedLeaves, k, column)
91
- listPinned.extend(listPinnedAtColumn)
92
- listPinnedLeaves.extend(_excludeLeafAtColumn(listPinned, r, columnK - 1, state.leavesTotal))
93
- return listPinnedLeaves
94
-
95
- def excludeLeafRBeforeLeafK(state: EliminationState, k: int, r: int) -> EliminationState:
96
- for columnK in range(state.columnLast, 0, -1):
97
- state.listPinnedLeaves = _excludeLeafRBeforeLeafK(state, k, r, columnK, state.listPinnedLeaves)
98
- return state
99
-
100
- def theorem4(state: EliminationState) -> EliminationState:
101
- # ------- Lunnon Theorem 4: "G(p^d) is divisible by d!p^d." ---------------
102
- for listIndicesSameMagnitude in [list(iter_index(state.mapShape, magnitude)) for magnitude in unique(state.mapShape)]:
103
- if len(listIndicesSameMagnitude) > 1:
104
- state.subsetsTheorem4 = factorial(len(listIndicesSameMagnitude))
105
- for dimensionAlpha, dimensionBeta in pairwise(listIndicesSameMagnitude):
106
- k, r = (productOfDimensions(state.mapShape, dimension) + 1 for dimension in (dimensionAlpha, dimensionBeta))
107
- state = excludeLeafRBeforeLeafK(state, k, r)
108
- return state
109
-
110
- def theorem2b(state: EliminationState) -> EliminationState:
111
- # ------- Lunnon Theorem 2(b): "If some pᵢ > 2, G is divisible by 2n." -----------------------------
112
- if state.subsetsTheorem4 == 1 and max(state.mapShape) > 2:
113
- state.subsetsTheorem2 = 2
114
- dimension: int = state.mapShape.index(max(state.mapShape))
115
- k: int = productOfDimensions(state.mapShape, dimension) + 1
116
- r: int = 2 * k
117
- state = excludeLeafRBeforeLeafK(state, k, r)
118
-
119
- return state
120
-
121
- def doTheNeedful(state: EliminationState, workersMaximum: int) -> EliminationState: # noqa: ARG001
122
- """Count the number of valid foldings for a given number of leaves."""
123
- # ------- Lunnon Theorem 2(a): foldsTotal is divisible by leavesTotal; Pin leaf1 in column0 and exclude leaf2--leafN at column0 ----------------------------
124
- state.listPinnedLeaves = [{0: 1}]
125
-
126
- state = theorem4(state)
127
- state = theorem2b(state)
128
- state = pinByFormula(state)
129
- state = count(state)
130
-
131
- return state
@@ -1,26 +0,0 @@
1
- from collections.abc import Iterator
2
- from cytoolz.functoolz import memoize
3
- from itertools import permutations, repeat
4
- from mapFolding.algorithms.iff import thisLeafFoldingIsValid
5
- from mapFolding.dataBaskets import EliminationState
6
-
7
- def _makeFolding(pinnedLeaves: dict[int, int], permutandsPermutation: tuple[int, ...], leavesTotal: int) -> tuple[int, ...]:
8
- permutand: Iterator[int] = iter(permutandsPermutation)
9
- return tuple([pinnedLeaves.get(column) or next(permutand) for column in range(leavesTotal)])
10
-
11
- @memoize
12
- def setOfLeaves(leavesTotal: int) -> set[int]:
13
- return set(range(1, leavesTotal + 1))
14
-
15
- def permutands(pinnedLeaves: dict[int, int], leavesTotal: int) -> tuple[int, ...]:
16
- return tuple(setOfLeaves(leavesTotal).difference(pinnedLeaves.values()))
17
-
18
- def permutePermutands(pinnedLeaves: dict[int, int], leavesTotal: int) -> Iterator[tuple[int, ...]]:
19
- return permutations(permutands(pinnedLeaves, leavesTotal))
20
-
21
- def countPinnedLeaves(pinnedLeaves: dict[int, int], mapShape: tuple[int, ...], leavesTotal: int) -> int:
22
- return sum(map(thisLeafFoldingIsValid, map(_makeFolding, repeat(pinnedLeaves), permutePermutands(pinnedLeaves, leavesTotal), repeat(leavesTotal)), repeat(mapShape)))
23
-
24
- def count(state: EliminationState) -> EliminationState:
25
- state.groupsOfFolds += sum(map(countPinnedLeaves, state.listPinnedLeaves, repeat(state.mapShape), repeat(state.leavesTotal)))
26
- return state
@@ -1,35 +0,0 @@
1
- from concurrent.futures import as_completed, Future, ProcessPoolExecutor
2
- from copy import deepcopy
3
- from mapFolding.algorithms.eliminationCount import count
4
- from mapFolding.algorithms.pinning2Dn import pinByFormula
5
- from mapFolding.dataBaskets import EliminationState
6
- from math import e, factorial
7
- from more_itertools import chunked_even
8
- from tqdm import tqdm
9
-
10
- def doTheNeedful(state: EliminationState, workersMaximum: int) -> EliminationState:
11
- """Find the quantity of valid foldings for a given map."""
12
- state = pinByFormula(state)
13
-
14
- groupsOfFolds:int = 0
15
-
16
- with ProcessPoolExecutor(workersMaximum) as concurrencyManager:
17
- listClaimTickets: list[Future[EliminationState]] = []
18
-
19
- listPinnedLeavesCopy: list[dict[int, int]] = deepcopy(state.listPinnedLeaves)
20
- state.listPinnedLeaves = []
21
-
22
- # lengthChunk:int = max(1, int(len(listPinnedLeavesCopy) / (e * workersMaximum)))
23
- lengthChunk:int = 5
24
-
25
- for listPinnedLeaves in chunked_even(listPinnedLeavesCopy, lengthChunk):
26
- stateCopy: EliminationState = deepcopy(state)
27
- stateCopy.listPinnedLeaves = listPinnedLeaves
28
- listClaimTickets.append(concurrencyManager.submit(count, stateCopy))
29
-
30
- for claimTicket in tqdm(as_completed(listClaimTickets), total=len(listClaimTickets), disable=False):
31
- groupsOfFolds += claimTicket.result().groupsOfFolds
32
-
33
- state.subsetsTheorem4 = factorial(state.dimensionsTotal)
34
-
35
- return state
@@ -1,206 +0,0 @@
1
- """Verify that a folding sequence is possible.
2
-
3
- Notes
4
- -----
5
- Eight forbidden inequalities of matching parity k and r *à la* Koehler (1968), indices of:
6
- [k < r < k+1 < r+1] [r < k+1 < r+1 < k] [k+1 < r+1 < k < r] [r+1 < k < r < k+1]
7
- [r < k < r+1 < k+1] [k < r+1 < k+1 < r] [r+1 < k+1 < r < k] [k+1 < r < k < r+1]
8
-
9
- Four forbidden inequalities of matching parity k and r *à la* Legendre (2014), indices of:
10
- [k < r < k+1 < r+1] [k+1 < r+1 < k < r] [r+1 < k < r < k+1] [k < r+1 < k+1 < r]
11
-
12
- Citations
13
- ---------
14
- - John E. Koehler, Folding a strip of stamps, Journal of Combinatorial Theory, Volume 5, Issue 2, 1968, Pages 135-152, ISSN
15
- 0021-9800, https://doi.org/10.1016/S0021-9800(68)80048-1.
16
- - Stéphane Legendre, Foldings and meanders, The Australasian Journal of Combinatorics, Volume 58, Part 2, 2014, Pages 275-291,
17
- ISSN 2202-3518, https://ajc.maths.uq.edu.au/pdf/58/ajc_v58_p275.pdf.
18
-
19
- See Also
20
- --------
21
- - "[Annotated, corrected, scanned copy]" of Koehler (1968) at https://oeis.org/A001011.
22
- - Citations in BibTeX format "mapFolding/citations".
23
- """
24
- from collections.abc import Callable
25
- from cytoolz.curried import get
26
- from cytoolz.functoolz import curry as syntacticCurry
27
- from functools import cache
28
- from itertools import combinations, filterfalse, product as CartesianProduct
29
- from mapFolding import getLeavesTotal
30
- from mapFolding.dataBaskets import EliminationState
31
- from math import prod
32
- from operator import indexOf
33
-
34
- def thisIsAViolation(column: int, columnComparand: int, getLeafNextCrease: Callable[[], int | None], getComparandNextCrease: Callable[[], int | None], columnOf: Callable[[int], int | None]) -> bool: # noqa: PLR0911
35
- """Validate.
36
-
37
- Mathematical reasons for the design of this function
38
- ----------------------------------------------------
39
-
40
- 1. To confirm that a multidimensional folding is valid, confirm that each of the constituent one-dimensional¹ foldings is valid.
41
- 2. To confirm that a one-dimensional folding is valid, check that all creases that might cross do not cross.
42
-
43
- A "crease" is a convenient lie: it is a shorthand description of two leaves that are physically connected to each other.
44
- Leaves in a one-dimensional folding are physically connected to at most two other leaves: the prior leaf and the next leaf.
45
- When talking about a one-dimensional section of a multidimensional folding, we ignore the other dimension and still
46
- reference the prior and next leaves. To check whether two creases cross, we must compare the four leaves of the two creases.
47
-
48
- ¹ A so-called one-dimensional folding, map, or strip of stamps has two dimensions, but one of the dimensions has a width of 1.
49
-
50
- Idiosyncratic reasons for the design of this function
51
- -----------------------------------------------------
52
-
53
- I name the first leaf of the first crease `leaf`. I name the leaf to which I am comparing it `comparand`. A crease² is a leaf
54
- and the next leaf, therefore, the crease of `leaf` connects it to `leafNextCrease`, and the crease of `comparand` connects it
55
- to `comparandNextCrease`. Nearly everyone else uses letters for names, such as k, k+1, r, and r+1. (Which stand for Kahlo and
56
- Rivera, of course.)
57
-
58
- ² "increase" from Latin *in-* "in" + *crescere* "to grow" (from PIE root ⋆ker- "to grow"). https://www.etymonline.com/word/increase
59
-
60
- Computational reasons for the design of this function
61
- -----------------------------------------------------
62
-
63
- If `leaf` and `comparand` do not have matching parity in the dimension, then their creases cannot cross. To call this
64
- function, you need `leaf` and `comparand`, and because determining parity-by-dimension is easiest when you first select `leaf`
65
- and `comparand`, this function will not check the parity of `leaf` and `comparand`.
66
-
67
- Computing the next leaf is not expensive, but 100,000,000 unnecessary but cheap computations is expensive. Therefore, instead of
68
- passing `leafNextCrease` and `comparandNextCrease`, pass the functions by which those values may be computed on demand.
69
-
70
- Finally, we need to compare the relative positions of the leaves, so pass a function that returns the position of the "next" leaf.
71
-
72
- """
73
- if column < columnComparand:
74
-
75
- comparandNextCrease: int | None = getComparandNextCrease()
76
- if comparandNextCrease is None:
77
- return False
78
-
79
- leafNextCrease: int | None = getLeafNextCrease()
80
- if leafNextCrease is None:
81
- return False
82
-
83
- columnComparandNextCrease: int | None = columnOf(comparandNextCrease)
84
- if columnComparandNextCrease is None:
85
- return False
86
- columnLeafNextCrease: int | None = columnOf(leafNextCrease)
87
- if columnLeafNextCrease is None:
88
- return False
89
-
90
- if columnComparandNextCrease < column:
91
- if columnLeafNextCrease < columnComparandNextCrease: # [k+1 < r+1 < k < r]
92
- return True
93
- return columnComparand < columnLeafNextCrease # [r+1 < k < r < k+1]
94
-
95
- if columnComparand < columnLeafNextCrease:
96
- if columnLeafNextCrease < columnComparandNextCrease: # [k < r < k+1 < r+1]
97
- return True
98
- elif column < columnComparandNextCrease < columnLeafNextCrease < columnComparand: # [k < r+1 < k+1 < r]
99
- return True
100
- return False
101
-
102
- # ------- ad hoc computations -----------------------------
103
- # @cache
104
- def _dimensionsTotal(mapShape: tuple[int, ...]) -> int:
105
- return len(mapShape)
106
-
107
- @cache
108
- def _leavesTotal(mapShape: tuple[int, ...]) -> int:
109
- return getLeavesTotal(mapShape)
110
-
111
- # @cache
112
- def productOfDimensions(mapShape: tuple[int, ...], dimension: int) -> int:
113
- return prod(mapShape[0:dimension])
114
-
115
- # ------- Functions for 'leaf', named 1, 2, ... n, not for 'indexLeaf' -------------
116
-
117
- @cache
118
- def ImaOddLeaf(mapShape: tuple[int, ...], leaf: int, dimension: int) -> int:
119
- # NOTE `leaf-1` because `leaf` is not zero-based indexing.
120
- return (((leaf-1) // productOfDimensions(mapShape, dimension)) % mapShape[dimension]) & 1
121
-
122
- def _matchingParityLeaf(mapShape: tuple[int, ...], leaf: int, comparand: int, dimension: int) -> bool:
123
- return ImaOddLeaf(mapShape, leaf, dimension) == ImaOddLeaf(mapShape, comparand, dimension)
124
-
125
- @syntacticCurry
126
- def matchingParityLeaf(mapShape: tuple[int, ...]) -> Callable[[tuple[tuple[tuple[int, int], tuple[int, int]], int]], bool]:
127
- def repack(aCartesianProduct: tuple[tuple[tuple[int, int], tuple[int, int]], int]) -> bool:
128
- ((_column, leaf), (_columnComparand, comparand)), dimension = aCartesianProduct
129
- return _matchingParityLeaf(mapShape, leaf, comparand, dimension)
130
- return repack
131
-
132
- @cache
133
- def nextCreaseLeaf(mapShape: tuple[int, ...], leaf: int, dimension: int) -> int | None:
134
- leafNext: int | None = None
135
- if (((leaf-1) // productOfDimensions(mapShape, dimension)) % mapShape[dimension]) + 1 < mapShape[dimension]:
136
- leafNext = leaf + productOfDimensions(mapShape, dimension)
137
- return leafNext
138
-
139
- inThis_pileOf = syntacticCurry(indexOf)
140
-
141
- def howToGetNextCreaseLeaf(mapShape: tuple[int, ...], leaf: int, dimension: int) -> Callable[[], int | None]:
142
- return lambda: nextCreaseLeaf(mapShape, leaf, dimension)
143
-
144
- def thisLeafFoldingIsValid(folding: tuple[int, ...], mapShape: tuple[int, ...]) -> bool:
145
- """Return `True` if the folding is valid."""
146
- foldingFiltered: filterfalse[tuple[int, int]] = filterfalse(lambda columnLeaf: columnLeaf[1] == _leavesTotal(mapShape), enumerate(folding)) # leafNPlus1 does not exist.
147
- leafAndComparand: combinations[tuple[tuple[int, int], tuple[int, int]]] = combinations(foldingFiltered, 2)
148
-
149
- leafAndComparandAcrossDimensions: CartesianProduct[tuple[tuple[tuple[int, int], tuple[int, int]], int]] = CartesianProduct(leafAndComparand, range(_dimensionsTotal(mapShape)))
150
- parityInThisDimension: Callable[[tuple[tuple[tuple[int, int], tuple[int, int]], int]], bool] = matchingParityLeaf(mapShape)
151
- leafAndComparandAcrossDimensionsFiltered: filter[tuple[tuple[tuple[int, int], tuple[int, int]], int]] = filter(parityInThisDimension, leafAndComparandAcrossDimensions)
152
-
153
- return all(not thisIsAViolation(column, columnComparand, howToGetNextCreaseLeaf(mapShape, leaf, aDimension), howToGetNextCreaseLeaf(mapShape, comparand, aDimension), inThis_pileOf(folding))
154
- for ((column, leaf), (columnComparand, comparand)), aDimension in leafAndComparandAcrossDimensionsFiltered)
155
-
156
- # ------- Functions for `indexLeaf`, named 0, 1, ... n-1, not for `leaf` -------------
157
-
158
- @cache
159
- def ImaOddIndexLeaf(mapShape: tuple[int, ...], indexLeaf: int, dimension: int) -> int:
160
- return ((indexLeaf // productOfDimensions(mapShape, dimension)) % mapShape[dimension]) & 1
161
-
162
- def _matchingParityIndexLeaf(mapShape: tuple[int, ...], indexLeaf: int, comparand: int, dimension: int) -> bool:
163
- return ImaOddIndexLeaf(mapShape, indexLeaf, dimension) == ImaOddIndexLeaf(mapShape, comparand, dimension)
164
-
165
- @syntacticCurry
166
- def matchingParityIndexLeaf(mapShape: tuple[int, ...]) -> Callable[[tuple[tuple[tuple[int, int], tuple[int, int]], int]], bool]:
167
- def repack(aCartesianProduct: tuple[tuple[tuple[int, int], tuple[int, int]], int]) -> bool:
168
- ((_pile, indexLeaf), (_pileComparand, comparand)), dimension = aCartesianProduct
169
- return _matchingParityIndexLeaf(mapShape, indexLeaf, comparand, dimension)
170
- return repack
171
-
172
- @cache
173
- def nextCreaseIndexLeaf(mapShape: tuple[int, ...], indexLeaf: int, dimension: int) -> int | None:
174
- indexLeafNext: int | None = None
175
- if ((indexLeaf // productOfDimensions(mapShape, dimension)) % mapShape[dimension]) + 1 < mapShape[dimension]:
176
- indexLeafNext = indexLeaf + productOfDimensions(mapShape, dimension)
177
- return indexLeafNext
178
-
179
- inThis_pileOf = syntacticCurry(indexOf)
180
-
181
- def getNextCreaseIndexLeaf(mapShape: tuple[int, ...], indexLeaf: int, dimension: int) -> Callable[[], int | None]:
182
- return lambda: nextCreaseIndexLeaf(mapShape, indexLeaf, dimension)
183
-
184
- def thisIndexLeafFoldingIsValid(folding: tuple[int, ...], mapShape: tuple[int, ...]) -> bool:
185
- """Return `True` if the folding is valid."""
186
- foldingFiltered: filterfalse[tuple[int, int]] = filterfalse(lambda pileIndexLeaf: pileIndexLeaf[1] == _leavesTotal(mapShape) - 1, enumerate(folding)) # indexLeafNPlus1 does not exist.
187
- indexLeafAndComparand: combinations[tuple[tuple[int, int], tuple[int, int]]] = combinations(foldingFiltered, 2)
188
-
189
- indexLeafAndComparandAcrossDimensions: CartesianProduct[tuple[tuple[tuple[int, int], tuple[int, int]], int]] = CartesianProduct(indexLeafAndComparand, range(_dimensionsTotal(mapShape)))
190
- parityInThisDimension: Callable[[tuple[tuple[tuple[int, int], tuple[int, int]], int]], bool] = matchingParityIndexLeaf(mapShape)
191
- indexLeafAndComparandAcrossDimensionsFiltered: filter[tuple[tuple[tuple[int, int], tuple[int, int]], int]] = filter(parityInThisDimension, indexLeafAndComparandAcrossDimensions)
192
-
193
- return all(not thisIsAViolation(pile, pileComparand, getNextCreaseIndexLeaf(mapShape, indexLeaf, aDimension), getNextCreaseIndexLeaf(mapShape, comparand, aDimension), inThis_pileOf(folding))
194
- for ((pile, indexLeaf), (pileComparand, comparand)), aDimension in indexLeafAndComparandAcrossDimensionsFiltered)
195
-
196
- # ------- Functions for `indexLeaf` in `pinnedLeaves` dictionary, not for `leaf` in `folding` -------------
197
-
198
- def pinnedLeavesHasAViolation(state: EliminationState, indexLeaf: int) -> bool:
199
- """Return `True` if `state.pinnedLeaves` or the addition of `indexLeaf` at `state.pile` has a violation."""
200
- pinnedLeaves: dict[int, int] = state.pinnedLeaves.copy()
201
- pinnedLeaves[state.pile] = indexLeaf
202
- indexLeaf2pile: dict[int, int] = {indexLeaf: pile for pile, indexLeaf in pinnedLeaves.items()}
203
- pinnedLeavesFiltered: filterfalse[tuple[int, int]] = filterfalse(lambda pileIndexLeaf: pileIndexLeaf[1] == state.leavesTotal, pinnedLeaves.items()) # indexLeafNPlus1 does not exist.
204
- indexLeafAndComparandAcrossDimensions = filter(matchingParityIndexLeaf(state.mapShape), CartesianProduct(combinations(pinnedLeavesFiltered, 2), range(state.dimensionsTotal)))
205
- return any(thisIsAViolation(pile, pileComparand, getNextCreaseIndexLeaf(state.mapShape, indexLeaf, aDimension), getNextCreaseIndexLeaf(state.mapShape, comparand, aDimension), get(seq=indexLeaf2pile, default=None))
206
- for ((pile, indexLeaf), (pileComparand, comparand)), aDimension in indexLeafAndComparandAcrossDimensions)