@cubingcenter/scrambler 0.5.3 → 0.6.0

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 (244) hide show
  1. package/README.md +24 -9
  2. package/dist/cli/index.js +0 -0
  3. package/dist/core/api.d.ts.map +1 -1
  4. package/dist/core/api.js +11 -1
  5. package/dist/core/types.d.ts +1 -1
  6. package/dist/core/types.d.ts.map +1 -1
  7. package/dist/puzzles/cube4/index.d.ts +4 -2
  8. package/dist/puzzles/cube4/index.d.ts.map +1 -1
  9. package/dist/puzzles/cube4/index.js +3 -1
  10. package/dist/puzzles/cube4/random-state.d.ts +16 -0
  11. package/dist/puzzles/cube4/random-state.d.ts.map +1 -0
  12. package/dist/puzzles/cube4/random-state.js +76 -0
  13. package/dist/puzzles/cube4/reduction/browser-loader.d.ts +18 -0
  14. package/dist/puzzles/cube4/reduction/browser-loader.d.ts.map +1 -0
  15. package/dist/puzzles/cube4/reduction/browser-loader.js +95 -0
  16. package/dist/puzzles/cube4/reduction/center1.d.ts +65 -0
  17. package/dist/puzzles/cube4/reduction/center1.d.ts.map +1 -0
  18. package/dist/puzzles/cube4/reduction/center1.js +245 -0
  19. package/dist/puzzles/cube4/reduction/center2.d.ts +91 -0
  20. package/dist/puzzles/cube4/reduction/center2.d.ts.map +1 -0
  21. package/dist/puzzles/cube4/reduction/center2.js +449 -0
  22. package/dist/puzzles/cube4/reduction/center3.d.ts +47 -0
  23. package/dist/puzzles/cube4/reduction/center3.d.ts.map +1 -0
  24. package/dist/puzzles/cube4/reduction/center3.js +278 -0
  25. package/dist/puzzles/cube4/reduction/edge3.d.ts +100 -0
  26. package/dist/puzzles/cube4/reduction/edge3.d.ts.map +1 -0
  27. package/dist/puzzles/cube4/reduction/edge3.js +511 -0
  28. package/dist/puzzles/cube4/reduction/generated/center1-distance.bin +1 -0
  29. package/dist/puzzles/cube4/reduction/generated/center1-manifest.json +46 -0
  30. package/dist/puzzles/cube4/reduction/generated/center1-move-maps.bin +0 -0
  31. package/dist/puzzles/cube4/reduction/generated/center2-ct-move.bin +0 -0
  32. package/dist/puzzles/cube4/reduction/generated/center2-manifest.json +87 -0
  33. package/dist/puzzles/cube4/reduction/generated/center2-pruning.bin +1 -0
  34. package/dist/puzzles/cube4/reduction/generated/center2-rl-move.bin +0 -0
  35. package/dist/puzzles/cube4/reduction/generated/center3-manifest.json +40 -0
  36. package/dist/puzzles/cube4/reduction/generated/center3-move.bin +0 -0
  37. package/dist/puzzles/cube4/reduction/generated/center3-pruning.bin +0 -0
  38. package/dist/puzzles/cube4/reduction/generated/edge3-distances.bin +1 -0
  39. package/dist/puzzles/cube4/reduction/generated/edge3-manifest.json +12 -0
  40. package/dist/puzzles/cube4/reduction/geometry.d.ts +33 -0
  41. package/dist/puzzles/cube4/reduction/geometry.d.ts.map +1 -0
  42. package/dist/puzzles/cube4/reduction/geometry.js +302 -0
  43. package/dist/puzzles/cube4/reduction/node-loader.d.ts +17 -0
  44. package/dist/puzzles/cube4/reduction/node-loader.d.ts.map +1 -0
  45. package/dist/puzzles/cube4/reduction/node-loader.js +98 -0
  46. package/dist/puzzles/cube4/reduction/pairing-coordinate.d.ts +130 -0
  47. package/dist/puzzles/cube4/reduction/pairing-coordinate.d.ts.map +1 -0
  48. package/dist/puzzles/cube4/reduction/pairing-coordinate.js +281 -0
  49. package/dist/puzzles/cube4/reduction/phase3-search.d.ts +42 -0
  50. package/dist/puzzles/cube4/reduction/phase3-search.d.ts.map +1 -0
  51. package/dist/puzzles/cube4/reduction/phase3-search.js +133 -0
  52. package/dist/puzzles/cube4/reduction/phase3.d.ts +34 -0
  53. package/dist/puzzles/cube4/reduction/phase3.d.ts.map +1 -0
  54. package/dist/puzzles/cube4/reduction/phase3.js +83 -0
  55. package/dist/puzzles/cube4/reduction/phase4.d.ts +35 -0
  56. package/dist/puzzles/cube4/reduction/phase4.d.ts.map +1 -0
  57. package/dist/puzzles/cube4/reduction/phase4.js +82 -0
  58. package/dist/puzzles/cube4/reduction/solve.d.ts +31 -0
  59. package/dist/puzzles/cube4/reduction/solve.d.ts.map +1 -0
  60. package/dist/puzzles/cube4/reduction/solve.js +311 -0
  61. package/dist/puzzles/cube4/scrambler.d.ts +9 -1
  62. package/dist/puzzles/cube4/scrambler.d.ts.map +1 -1
  63. package/dist/puzzles/cube4/scrambler.js +123 -81
  64. package/dist/puzzles/cube4/types.d.ts +6 -0
  65. package/dist/puzzles/cube4/types.d.ts.map +1 -1
  66. package/dist/puzzles/cube4/validation.d.ts +6 -0
  67. package/dist/puzzles/cube4/validation.d.ts.map +1 -0
  68. package/dist/puzzles/cube4/validation.js +91 -0
  69. package/dist/puzzles/fto/coordinates.d.ts +53 -0
  70. package/dist/puzzles/fto/coordinates.d.ts.map +1 -0
  71. package/dist/puzzles/fto/coordinates.js +228 -0
  72. package/dist/puzzles/fto/facelets.d.ts +6 -0
  73. package/dist/puzzles/fto/facelets.d.ts.map +1 -0
  74. package/dist/puzzles/fto/facelets.js +99 -0
  75. package/dist/puzzles/fto/index.d.ts +12 -0
  76. package/dist/puzzles/fto/index.d.ts.map +1 -0
  77. package/dist/puzzles/fto/index.js +13 -0
  78. package/dist/puzzles/fto/moves.d.ts +12 -0
  79. package/dist/puzzles/fto/moves.d.ts.map +1 -0
  80. package/dist/puzzles/fto/moves.js +115 -0
  81. package/dist/puzzles/fto/random-state.d.ts +17 -0
  82. package/dist/puzzles/fto/random-state.d.ts.map +1 -0
  83. package/dist/puzzles/fto/random-state.js +40 -0
  84. package/dist/puzzles/fto/scrambler.d.ts +6 -0
  85. package/dist/puzzles/fto/scrambler.d.ts.map +1 -0
  86. package/dist/puzzles/fto/scrambler.js +49 -0
  87. package/dist/puzzles/fto/solver/engine.d.ts +18 -0
  88. package/dist/puzzles/fto/solver/engine.d.ts.map +1 -0
  89. package/dist/puzzles/fto/solver/engine.js +1168 -0
  90. package/dist/puzzles/fto/solver/index.d.ts +2 -0
  91. package/dist/puzzles/fto/solver/index.d.ts.map +1 -0
  92. package/dist/puzzles/fto/solver/index.js +1 -0
  93. package/dist/puzzles/fto/state.d.ts +16 -0
  94. package/dist/puzzles/fto/state.d.ts.map +1 -0
  95. package/dist/puzzles/fto/state.js +61 -0
  96. package/dist/puzzles/fto/types.d.ts +32 -0
  97. package/dist/puzzles/fto/types.d.ts.map +1 -0
  98. package/dist/puzzles/fto/types.js +46 -0
  99. package/dist/puzzles/fto/validation.d.ts +19 -0
  100. package/dist/puzzles/fto/validation.d.ts.map +1 -0
  101. package/dist/puzzles/fto/validation.js +143 -0
  102. package/dist/puzzles/index.d.ts +2 -0
  103. package/dist/puzzles/index.d.ts.map +1 -1
  104. package/dist/puzzles/index.js +6 -0
  105. package/dist/puzzles/skewb/index.d.ts +1 -1
  106. package/dist/puzzles/skewb/index.d.ts.map +1 -1
  107. package/dist/puzzles/skewb/index.js +1 -1
  108. package/dist/puzzles/skewb/random-state.d.ts.map +1 -1
  109. package/dist/puzzles/skewb/random-state.js +4 -1
  110. package/dist/puzzles/sq1/facelets.d.ts +12 -0
  111. package/dist/puzzles/sq1/facelets.d.ts.map +1 -0
  112. package/dist/puzzles/sq1/facelets.js +26 -0
  113. package/dist/puzzles/sq1/index.d.ts +10 -0
  114. package/dist/puzzles/sq1/index.d.ts.map +1 -0
  115. package/dist/puzzles/sq1/index.js +11 -0
  116. package/dist/puzzles/sq1/moves.d.ts +55 -0
  117. package/dist/puzzles/sq1/moves.d.ts.map +1 -0
  118. package/dist/puzzles/sq1/moves.js +220 -0
  119. package/dist/puzzles/sq1/random-state.d.ts +6 -0
  120. package/dist/puzzles/sq1/random-state.d.ts.map +1 -0
  121. package/dist/puzzles/sq1/random-state.js +49 -0
  122. package/dist/puzzles/sq1/scrambler.d.ts +10 -0
  123. package/dist/puzzles/sq1/scrambler.d.ts.map +1 -0
  124. package/dist/puzzles/sq1/scrambler.js +90 -0
  125. package/dist/puzzles/sq1/solver/browser-loader.d.ts +5 -0
  126. package/dist/puzzles/sq1/solver/browser-loader.d.ts.map +1 -0
  127. package/dist/puzzles/sq1/solver/browser-loader.js +92 -0
  128. package/dist/puzzles/sq1/solver/full-cube.d.ts +53 -0
  129. package/dist/puzzles/sq1/solver/full-cube.d.ts.map +1 -0
  130. package/dist/puzzles/sq1/solver/full-cube.js +281 -0
  131. package/dist/puzzles/sq1/solver/generated/manifest.json +50 -0
  132. package/dist/puzzles/sq1/solver/generated/shape-bottom-move.bin +0 -0
  133. package/dist/puzzles/sq1/solver/generated/shape-idx.bin +0 -0
  134. package/dist/puzzles/sq1/solver/generated/shape-prun.bin +0 -0
  135. package/dist/puzzles/sq1/solver/generated/shape-top-move.bin +0 -0
  136. package/dist/puzzles/sq1/solver/generated/shape-twist-move.bin +0 -0
  137. package/dist/puzzles/sq1/solver/generated/square-bottom-move.bin +0 -0
  138. package/dist/puzzles/sq1/solver/generated/square-prun.bin +0 -0
  139. package/dist/puzzles/sq1/solver/generated/square-top-move.bin +0 -0
  140. package/dist/puzzles/sq1/solver/generated/square-twist-move.bin +0 -0
  141. package/dist/puzzles/sq1/solver/index.d.ts +5 -0
  142. package/dist/puzzles/sq1/solver/index.d.ts.map +1 -0
  143. package/dist/puzzles/sq1/solver/index.js +4 -0
  144. package/dist/puzzles/sq1/solver/node-loader.d.ts +4 -0
  145. package/dist/puzzles/sq1/solver/node-loader.d.ts.map +1 -0
  146. package/dist/puzzles/sq1/solver/node-loader.js +113 -0
  147. package/dist/puzzles/sq1/solver/search.d.ts +27 -0
  148. package/dist/puzzles/sq1/solver/search.d.ts.map +1 -0
  149. package/dist/puzzles/sq1/solver/search.js +225 -0
  150. package/dist/puzzles/sq1/solver/shape.d.ts +22 -0
  151. package/dist/puzzles/sq1/solver/shape.d.ts.map +1 -0
  152. package/dist/puzzles/sq1/solver/shape.js +185 -0
  153. package/dist/puzzles/sq1/solver/square.d.ts +10 -0
  154. package/dist/puzzles/sq1/solver/square.d.ts.map +1 -0
  155. package/dist/puzzles/sq1/solver/square.js +90 -0
  156. package/dist/puzzles/sq1/solver/table-metadata.d.ts +48 -0
  157. package/dist/puzzles/sq1/solver/table-metadata.d.ts.map +1 -0
  158. package/dist/puzzles/sq1/solver/table-metadata.js +47 -0
  159. package/dist/puzzles/sq1/solver/tables.d.ts +17 -0
  160. package/dist/puzzles/sq1/solver/tables.d.ts.map +1 -0
  161. package/dist/puzzles/sq1/solver/tables.js +66 -0
  162. package/dist/puzzles/sq1/state.d.ts +10 -0
  163. package/dist/puzzles/sq1/state.d.ts.map +1 -0
  164. package/dist/puzzles/sq1/state.js +74 -0
  165. package/dist/puzzles/sq1/types.d.ts +32 -0
  166. package/dist/puzzles/sq1/types.d.ts.map +1 -0
  167. package/dist/puzzles/sq1/types.js +1 -0
  168. package/dist/puzzles/sq1/validation.d.ts +7 -0
  169. package/dist/puzzles/sq1/validation.d.ts.map +1 -0
  170. package/dist/puzzles/sq1/validation.js +64 -0
  171. package/dist/random/prng.d.ts.map +1 -1
  172. package/dist/random/prng.js +9 -4
  173. package/dist-cjs/core/api.js +11 -1
  174. package/dist-cjs/puzzles/cube4/index.js +11 -4
  175. package/dist-cjs/puzzles/cube4/random-state.js +79 -0
  176. package/dist-cjs/puzzles/cube4/reduction/browser-loader.js +100 -0
  177. package/dist-cjs/puzzles/cube4/reduction/center1.js +258 -0
  178. package/dist-cjs/puzzles/cube4/reduction/center2.js +462 -0
  179. package/dist-cjs/puzzles/cube4/reduction/center3.js +284 -0
  180. package/dist-cjs/puzzles/cube4/reduction/edge3.js +522 -0
  181. package/dist-cjs/puzzles/cube4/reduction/generated/center1-distance.bin +1 -0
  182. package/dist-cjs/puzzles/cube4/reduction/generated/center1-manifest.json +46 -0
  183. package/dist-cjs/puzzles/cube4/reduction/generated/center1-move-maps.bin +0 -0
  184. package/dist-cjs/puzzles/cube4/reduction/generated/center2-ct-move.bin +0 -0
  185. package/dist-cjs/puzzles/cube4/reduction/generated/center2-manifest.json +87 -0
  186. package/dist-cjs/puzzles/cube4/reduction/generated/center2-pruning.bin +1 -0
  187. package/dist-cjs/puzzles/cube4/reduction/generated/center2-rl-move.bin +0 -0
  188. package/dist-cjs/puzzles/cube4/reduction/generated/center3-manifest.json +40 -0
  189. package/dist-cjs/puzzles/cube4/reduction/generated/center3-move.bin +0 -0
  190. package/dist-cjs/puzzles/cube4/reduction/generated/center3-pruning.bin +0 -0
  191. package/dist-cjs/puzzles/cube4/reduction/generated/edge3-distances.bin +1 -0
  192. package/dist-cjs/puzzles/cube4/reduction/generated/edge3-manifest.json +12 -0
  193. package/dist-cjs/puzzles/cube4/reduction/geometry.js +308 -0
  194. package/dist-cjs/puzzles/cube4/reduction/node-loader.js +104 -0
  195. package/dist-cjs/puzzles/cube4/reduction/pairing-coordinate.js +294 -0
  196. package/dist-cjs/puzzles/cube4/reduction/phase3-search.js +138 -0
  197. package/dist-cjs/puzzles/cube4/reduction/phase3.js +86 -0
  198. package/dist-cjs/puzzles/cube4/reduction/phase4.js +87 -0
  199. package/dist-cjs/puzzles/cube4/reduction/solve.js +314 -0
  200. package/dist-cjs/puzzles/cube4/scrambler.js +122 -79
  201. package/dist-cjs/puzzles/cube4/validation.js +97 -0
  202. package/dist-cjs/puzzles/fto/coordinates.js +240 -0
  203. package/dist-cjs/puzzles/fto/facelets.js +104 -0
  204. package/dist-cjs/puzzles/fto/index.js +68 -0
  205. package/dist-cjs/puzzles/fto/moves.js +126 -0
  206. package/dist-cjs/puzzles/fto/random-state.js +43 -0
  207. package/dist-cjs/puzzles/fto/scrambler.js +53 -0
  208. package/dist-cjs/puzzles/fto/solver/engine.js +1175 -0
  209. package/dist-cjs/puzzles/fto/solver/index.js +9 -0
  210. package/dist-cjs/puzzles/fto/state.js +69 -0
  211. package/dist-cjs/puzzles/fto/types.js +49 -0
  212. package/dist-cjs/puzzles/fto/validation.js +147 -0
  213. package/dist-cjs/puzzles/index.js +7 -1
  214. package/dist-cjs/puzzles/skewb/index.js +2 -1
  215. package/dist-cjs/puzzles/skewb/random-state.js +4 -1
  216. package/dist-cjs/puzzles/sq1/facelets.js +30 -0
  217. package/dist-cjs/puzzles/sq1/index.js +52 -0
  218. package/dist-cjs/puzzles/sq1/moves.js +234 -0
  219. package/dist-cjs/puzzles/sq1/random-state.js +52 -0
  220. package/dist-cjs/puzzles/sq1/scrambler.js +95 -0
  221. package/dist-cjs/puzzles/sq1/solver/browser-loader.js +97 -0
  222. package/dist-cjs/puzzles/sq1/solver/full-cube.js +289 -0
  223. package/dist-cjs/puzzles/sq1/solver/generated/manifest.json +50 -0
  224. package/dist-cjs/puzzles/sq1/solver/generated/shape-bottom-move.bin +0 -0
  225. package/dist-cjs/puzzles/sq1/solver/generated/shape-idx.bin +0 -0
  226. package/dist-cjs/puzzles/sq1/solver/generated/shape-prun.bin +0 -0
  227. package/dist-cjs/puzzles/sq1/solver/generated/shape-top-move.bin +0 -0
  228. package/dist-cjs/puzzles/sq1/solver/generated/shape-twist-move.bin +0 -0
  229. package/dist-cjs/puzzles/sq1/solver/generated/square-bottom-move.bin +0 -0
  230. package/dist-cjs/puzzles/sq1/solver/generated/square-prun.bin +0 -0
  231. package/dist-cjs/puzzles/sq1/solver/generated/square-top-move.bin +0 -0
  232. package/dist-cjs/puzzles/sq1/solver/generated/square-twist-move.bin +0 -0
  233. package/dist-cjs/puzzles/sq1/solver/index.js +18 -0
  234. package/dist-cjs/puzzles/sq1/solver/node-loader.js +120 -0
  235. package/dist-cjs/puzzles/sq1/solver/search.js +229 -0
  236. package/dist-cjs/puzzles/sq1/solver/shape.js +191 -0
  237. package/dist-cjs/puzzles/sq1/solver/square.js +93 -0
  238. package/dist-cjs/puzzles/sq1/solver/table-metadata.js +50 -0
  239. package/dist-cjs/puzzles/sq1/solver/tables.js +106 -0
  240. package/dist-cjs/puzzles/sq1/state.js +81 -0
  241. package/dist-cjs/puzzles/sq1/types.js +2 -0
  242. package/dist-cjs/puzzles/sq1/validation.js +68 -0
  243. package/dist-cjs/random/prng.js +9 -4
  244. package/package.json +43 -14
@@ -0,0 +1,281 @@
1
+ import { createSolvedSquare1State } from "../state.js";
2
+ /**
3
+ * Low-level bitwise representation of Square-1 state.
4
+ *
5
+ * Each layer is split into left and right 6-slot halves (24 bits per half, 4 bits per slot):
6
+ * - `ul`: top left (slots 0..5)
7
+ * - `ur`: top right (slots 6..11)
8
+ * - `dl`: bottom right / left (slots 0..5 of bottom)
9
+ * - `dr`: bottom left / right (slots 6..11 of bottom)
10
+ * - `ml`: middle layer state (0 = solved, 1 = flipped)
11
+ *
12
+ * Piece encoding in 4-bit values:
13
+ * - Corners: values with LSB 1 (1, 3, 5, 7, 9, 11, 13, 15) -> pieceId = (val >> 1) in [0..7]
14
+ * - Edges: values with LSB 0 (0, 2, 4, 6, 8, 10, 12, 14) -> pieceId = (val >> 1) + 8 in [8..15]
15
+ */
16
+ export class FullCube {
17
+ ul = 0x011233;
18
+ ur = 0x455677;
19
+ dl = 0x998bba;
20
+ dr = 0xddcffe;
21
+ ml = 0;
22
+ copy(c) {
23
+ this.ul = c.ul;
24
+ this.ur = c.ur;
25
+ this.dl = c.dl;
26
+ this.dr = c.dr;
27
+ this.ml = c.ml;
28
+ }
29
+ isSolved() {
30
+ return (this.ul === 0x011233 &&
31
+ this.ur === 0x455677 &&
32
+ this.dl === 0x998bba &&
33
+ this.dr === 0xddcffe &&
34
+ this.ml === 0);
35
+ }
36
+ /**
37
+ * Applies move token:
38
+ * - 0: slice /
39
+ * - >0: top layer turn
40
+ * - <0: bottom layer turn
41
+ */
42
+ doMove(move) {
43
+ let m = move << 2;
44
+ if (m > 24) {
45
+ m = 48 - m;
46
+ const temp = this.ul;
47
+ this.ul = ((this.ul >> m) | (this.ur << (24 - m))) & 0xffffff;
48
+ this.ur = ((this.ur >> m) | (temp << (24 - m))) & 0xffffff;
49
+ }
50
+ else if (m > 0) {
51
+ const temp = this.ul;
52
+ this.ul = ((this.ul << m) | (this.ur >> (24 - m))) & 0xffffff;
53
+ this.ur = ((this.ur << m) | (temp >> (24 - m))) & 0xffffff;
54
+ }
55
+ else if (m === 0) {
56
+ const temp = this.ur;
57
+ this.ur = this.dl;
58
+ this.dl = temp;
59
+ this.ml = 1 - this.ml;
60
+ }
61
+ else if (m >= -24) {
62
+ m = -m;
63
+ const temp = this.dl;
64
+ this.dl = ((this.dl << m) | (this.dr >> (24 - m))) & 0xffffff;
65
+ this.dr = ((this.dr << m) | (temp >> (24 - m))) & 0xffffff;
66
+ }
67
+ else if (m < -24) {
68
+ m = 48 + m;
69
+ const temp = this.dl;
70
+ this.dl = ((this.dl >> m) | (this.dr << (24 - m))) & 0xffffff;
71
+ this.dr = ((this.dr >> m) | (temp << (24 - m))) & 0xffffff;
72
+ }
73
+ }
74
+ pieceAt(idx) {
75
+ let ret;
76
+ if (idx < 6) {
77
+ ret = this.ul >> ((5 - idx) << 2);
78
+ }
79
+ else if (idx < 12) {
80
+ ret = this.ur >> ((11 - idx) << 2);
81
+ }
82
+ else if (idx < 18) {
83
+ ret = this.dl >> ((17 - idx) << 2);
84
+ }
85
+ else {
86
+ ret = this.dr >> ((23 - idx) << 2);
87
+ }
88
+ return ret & 0x0f;
89
+ }
90
+ setPiece(idx, value) {
91
+ const shift = idx < 6
92
+ ? (5 - idx) << 2
93
+ : idx < 12
94
+ ? (11 - idx) << 2
95
+ : idx < 18
96
+ ? (17 - idx) << 2
97
+ : (23 - idx) << 2;
98
+ if (idx < 6) {
99
+ this.ul = (this.ul & ~(0xf << shift)) | (value << shift);
100
+ }
101
+ else if (idx < 12) {
102
+ this.ur = (this.ur & ~(0xf << shift)) | (value << shift);
103
+ }
104
+ else if (idx < 18) {
105
+ this.dl = (this.dl & ~(0xf << shift)) | (value << shift);
106
+ }
107
+ else if (idx < 24) {
108
+ this.dr = (this.dr & ~(0xf << shift)) | (value << shift);
109
+ }
110
+ }
111
+ getParity() {
112
+ const arr = new Array(16);
113
+ let cnt = 0;
114
+ arr[0] = this.pieceAt(0);
115
+ for (let i = 1; i < 24; i++) {
116
+ const p = this.pieceAt(i);
117
+ if (p !== arr[cnt]) {
118
+ arr[++cnt] = p;
119
+ }
120
+ }
121
+ let p = 0;
122
+ for (let a = 0; a < 16; a++) {
123
+ for (let b = a + 1; b < 16; b++) {
124
+ if (arr[a] > arr[b]) {
125
+ p ^= 1;
126
+ }
127
+ }
128
+ }
129
+ return p;
130
+ }
131
+ getShapeIdx(shapeIdxTable) {
132
+ let urx = this.ur & 0x111111;
133
+ urx |= urx >> 3;
134
+ urx |= urx >> 6;
135
+ urx = (urx & 0xf) | ((urx >> 12) & 0x30);
136
+ let ulx = this.ul & 0x111111;
137
+ ulx |= ulx >> 3;
138
+ ulx |= ulx >> 6;
139
+ ulx = (ulx & 0xf) | ((ulx >> 12) & 0x30);
140
+ let drx = this.dr & 0x111111;
141
+ drx |= drx >> 3;
142
+ drx |= drx >> 6;
143
+ drx = (drx & 0xf) | ((drx >> 12) & 0x30);
144
+ let dlx = this.dl & 0x111111;
145
+ dlx |= dlx >> 3;
146
+ dlx |= dlx >> 6;
147
+ dlx = (dlx & 0xf) | ((dlx >> 12) & 0x30);
148
+ const key = ((this.getParity() << 24) | (ulx << 18) | (urx << 12) | (dlx << 6) | drx) >>> 0;
149
+ return getShape2Idx(shapeIdxTable, key);
150
+ }
151
+ getSquare() {
152
+ const prm = new Uint8Array(8);
153
+ for (let a = 0; a < 8; a++) {
154
+ prm[a] = this.pieceAt(a * 3 + 1) >> 1;
155
+ }
156
+ const cornperm = get8Perm(prm);
157
+ const topEdgeFirst = this.pieceAt(0) === this.pieceAt(1);
158
+ let a = topEdgeFirst ? 2 : 0;
159
+ let b = 0;
160
+ for (; b < 4; a += 3, b++) {
161
+ prm[b] = this.pieceAt(a) >> 1;
162
+ }
163
+ const botEdgeFirst = this.pieceAt(12) === this.pieceAt(13);
164
+ a = botEdgeFirst ? 14 : 12;
165
+ for (; b < 8; a += 3, b++) {
166
+ prm[b] = this.pieceAt(a) >> 1;
167
+ }
168
+ const edgeperm = get8Perm(prm);
169
+ return { edgeperm, cornperm, topEdgeFirst, botEdgeFirst, ml: this.ml };
170
+ }
171
+ }
172
+ function getShape2Idx(shapeIdxTable, shp) {
173
+ let low = 0;
174
+ let high = shapeIdxTable.length - 1;
175
+ const key = (shp & 0xffffff) >>> 0;
176
+ while (low <= high) {
177
+ const mid = (low + high) >>> 1;
178
+ const midVal = (shapeIdxTable[mid]) >>> 0;
179
+ if (midVal < key)
180
+ low = mid + 1;
181
+ else if (midVal > key)
182
+ high = mid - 1;
183
+ else
184
+ return (mid << 1) | (shp >>> 24);
185
+ }
186
+ return 0;
187
+ }
188
+ const fact = [1, 1, 2, 6, 24, 120, 720, 5040];
189
+ export function get8Perm(arr) {
190
+ let idx = 0;
191
+ let val = 0x76543210;
192
+ for (let i = 0; i < 7; i++) {
193
+ const v = arr[i] << 2;
194
+ idx = (8 - i) * idx + ((val >> v) & 7);
195
+ val -= 0x11111110 << v;
196
+ }
197
+ return idx;
198
+ }
199
+ export function set8Perm(arr, idx) {
200
+ let val = 0x76543210;
201
+ for (let i = 0; i < 7; i++) {
202
+ const p = fact[7 - i];
203
+ const v = Math.floor(idx / p);
204
+ idx -= v * p;
205
+ const shift = v << 2;
206
+ arr[i] = (val >> shift) & 7;
207
+ const m = (1 << shift) - 1;
208
+ val = (val & m) + ((val >> 4) & ~m);
209
+ }
210
+ arr[7] = val & 7;
211
+ }
212
+ /**
213
+ * Converts a FullCube instance to a high-level Square1State.
214
+ */
215
+ export function fullCubeToState(cube) {
216
+ const solved = createSolvedSquare1State();
217
+ const allSlots = [...solved.top, ...solved.bottom];
218
+ const getSlotDef = (pieceId, isCorner, partIndex) => {
219
+ const def = allSlots.find((s) => s.pieceId === pieceId && s.partIndex === partIndex);
220
+ return def || { faceColor: (pieceId < 8 ? "U" : "D"), sideColor: "F" };
221
+ };
222
+ const top = Array.from({ length: 12 }, (_, i) => {
223
+ const raw = cube.pieceAt(i);
224
+ const isCorner = (raw & 1) === 1;
225
+ const pieceId = isCorner ? (raw >> 1) : ((raw >> 1) + 8);
226
+ let partIndex = 0;
227
+ if (isCorner) {
228
+ const prevRaw = cube.pieceAt((i - 1 + 12) % 12);
229
+ if (prevRaw === raw)
230
+ partIndex = 1;
231
+ else
232
+ partIndex = 0;
233
+ }
234
+ const def = getSlotDef(pieceId, isCorner, partIndex);
235
+ return {
236
+ pieceId,
237
+ isCorner,
238
+ partIndex,
239
+ faceColor: "U",
240
+ sideColor: def.sideColor
241
+ };
242
+ });
243
+ const bottom = Array.from({ length: 12 }, (_, i) => {
244
+ const raw = cube.pieceAt(12 + i);
245
+ const isCorner = (raw & 1) === 1;
246
+ const pieceId = isCorner ? (raw >> 1) : ((raw >> 1) + 8);
247
+ let partIndex = 0;
248
+ if (isCorner) {
249
+ const prevRaw = cube.pieceAt(12 + ((i - 1 + 12) % 12));
250
+ if (prevRaw === raw)
251
+ partIndex = 1;
252
+ else
253
+ partIndex = 0;
254
+ }
255
+ const def = getSlotDef(pieceId, isCorner, partIndex);
256
+ return {
257
+ pieceId,
258
+ isCorner,
259
+ partIndex,
260
+ faceColor: "D",
261
+ sideColor: def.sideColor
262
+ };
263
+ });
264
+ return { top, bottom, middle: cube.ml };
265
+ }
266
+ /**
267
+ * Converts a high-level Square1State to a FullCube.
268
+ */
269
+ export function stateToFullCube(state) {
270
+ const cube = new FullCube();
271
+ cube.ml = state.middle;
272
+ for (let i = 0; i < 12; i++) {
273
+ const s = state.top[i];
274
+ const raw = s.isCorner ? ((s.pieceId << 1) | 1) : ((s.pieceId - 8) << 1);
275
+ cube.setPiece(i, raw);
276
+ const sb = state.bottom[i];
277
+ const rawB = sb.isCorner ? ((sb.pieceId << 1) | 1) : ((sb.pieceId - 8) << 1);
278
+ cube.setPiece(12 + i, rawB);
279
+ }
280
+ return cube;
281
+ }
@@ -0,0 +1,50 @@
1
+ {
2
+ "version": 1,
3
+ "files": {
4
+ "shapeIdx": {
5
+ "file": "shape-idx.bin",
6
+ "entries": 3678,
7
+ "checksum": 3187990008
8
+ },
9
+ "shapePrun": {
10
+ "file": "shape-prun.bin",
11
+ "entries": 7356,
12
+ "checksum": 2116325776
13
+ },
14
+ "shapeTopMove": {
15
+ "file": "shape-top-move.bin",
16
+ "entries": 7356,
17
+ "checksum": 4112891337
18
+ },
19
+ "shapeBottomMove": {
20
+ "file": "shape-bottom-move.bin",
21
+ "entries": 7356,
22
+ "checksum": 161984121
23
+ },
24
+ "shapeTwistMove": {
25
+ "file": "shape-twist-move.bin",
26
+ "entries": 7356,
27
+ "checksum": 694153781
28
+ },
29
+ "squareTwistMove": {
30
+ "file": "square-twist-move.bin",
31
+ "entries": 40320,
32
+ "checksum": 4150758597
33
+ },
34
+ "squareTopMove": {
35
+ "file": "square-top-move.bin",
36
+ "entries": 40320,
37
+ "checksum": 1003750981
38
+ },
39
+ "squareBottomMove": {
40
+ "file": "square-bottom-move.bin",
41
+ "entries": 40320,
42
+ "checksum": 2028613829
43
+ },
44
+ "squarePrun": {
45
+ "file": "square-prun.bin",
46
+ "entries": 80640,
47
+ "checksum": 1475475221
48
+ }
49
+ }
50
+ }
@@ -0,0 +1,5 @@
1
+ export { FullCube, fullCubeToState, stateToFullCube } from "./full-cube.js";
2
+ export { areSquare1TablesLoaded, ensureSquare1TablesLoaded, getSquare1SolverTablesSync, generateSquare1SolverTables, setCachedSquare1Tables, type Square1SolverTables } from "./tables.js";
3
+ export { Square1Searcher, INVERSE_SOLUTION, type Square1Solution } from "./search.js";
4
+ export { SQ1_SOLVER_TABLE_METADATA } from "./table-metadata.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/puzzles/sq1/solver/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAC5E,OAAO,EACL,sBAAsB,EACtB,yBAAyB,EACzB,0BAA0B,EAC1B,2BAA2B,EAC3B,sBAAsB,EACtB,KAAK,mBAAmB,EACzB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,eAAe,EACf,gBAAgB,EAChB,KAAK,eAAe,EACrB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,4 @@
1
+ export { FullCube, fullCubeToState, stateToFullCube } from "./full-cube.js";
2
+ export { areSquare1TablesLoaded, ensureSquare1TablesLoaded, getSquare1SolverTablesSync, generateSquare1SolverTables, setCachedSquare1Tables } from "./tables.js";
3
+ export { Square1Searcher, INVERSE_SOLUTION } from "./search.js";
4
+ export { SQ1_SOLVER_TABLE_METADATA } from "./table-metadata.js";
@@ -0,0 +1,4 @@
1
+ import type { Square1SolverTables } from "./tables.js";
2
+ export declare function readGeneratedSquare1SolverTables(): Square1SolverTables;
3
+ export declare function checksum(values: ArrayLike<number>): number;
4
+ //# sourceMappingURL=node-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-loader.d.ts","sourceRoot":"","sources":["../../../../src/puzzles/sq1/solver/node-loader.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAmBvD,wBAAgB,gCAAgC,IAAI,mBAAmB,CAgCtE;AAqGD,wBAAgB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,MAAM,CAAC,GAAG,MAAM,CAO1D"}
@@ -0,0 +1,113 @@
1
+ import { existsSync, readFileSync } from "node:fs";
2
+ import { createRequire } from "node:module";
3
+ import path from "node:path";
4
+ import { SQ1_SOLVER_TABLE_METADATA } from "./table-metadata.js";
5
+ const GENERATED_DIRECTORY = "puzzles/sq1/solver/generated";
6
+ export function readGeneratedSquare1SolverTables() {
7
+ const assetDirectory = resolveGeneratedAssetDirectory();
8
+ const manifest = JSON.parse(readFileSync(path.join(assetDirectory, "manifest.json"), "utf8"));
9
+ if (manifest.version !== 1) {
10
+ throw new Error(`Unsupported square1 solver table manifest version: ${manifest.version}`);
11
+ }
12
+ const shapeIdx = readInt32Table(assetDirectory, manifest.files.shapeIdx, SQ1_SOLVER_TABLE_METADATA.shapeIdx.checksum);
13
+ const shapePrun = readInt8Table(assetDirectory, manifest.files.shapePrun, SQ1_SOLVER_TABLE_METADATA.shapePrun.checksum);
14
+ const shapeTopMove = readInt32Table(assetDirectory, manifest.files.shapeTopMove, SQ1_SOLVER_TABLE_METADATA.shapeTopMove.checksum);
15
+ const shapeBottomMove = readInt32Table(assetDirectory, manifest.files.shapeBottomMove, SQ1_SOLVER_TABLE_METADATA.shapeBottomMove.checksum);
16
+ const shapeTwistMove = readInt32Table(assetDirectory, manifest.files.shapeTwistMove, SQ1_SOLVER_TABLE_METADATA.shapeTwistMove.checksum);
17
+ const squareTwistMove = readUint16Table(assetDirectory, manifest.files.squareTwistMove, SQ1_SOLVER_TABLE_METADATA.squareTwistMove.checksum);
18
+ const squareTopMove = readUint16Table(assetDirectory, manifest.files.squareTopMove, SQ1_SOLVER_TABLE_METADATA.squareTopMove.checksum);
19
+ const squareBottomMove = readUint16Table(assetDirectory, manifest.files.squareBottomMove, SQ1_SOLVER_TABLE_METADATA.squareBottomMove.checksum);
20
+ const squarePrun = readInt8Table(assetDirectory, manifest.files.squarePrun, SQ1_SOLVER_TABLE_METADATA.squarePrun.checksum);
21
+ return {
22
+ shapeIdx,
23
+ shapePrun,
24
+ shapeTopMove,
25
+ shapeBottomMove,
26
+ shapeTwistMove,
27
+ squareTwistMove,
28
+ squareTopMove,
29
+ squareBottomMove,
30
+ squarePrun
31
+ };
32
+ }
33
+ function readInt32Table(assetDirectory, entry, expectedChecksum) {
34
+ const buffer = readFileSync(path.join(assetDirectory, entry.file));
35
+ if (buffer.length !== entry.entries * 4) {
36
+ throw new Error(`Invalid byte size for ${entry.file}`);
37
+ }
38
+ const values = new Int32Array(entry.entries);
39
+ for (let index = 0; index < values.length; index += 1) {
40
+ values[index] = buffer.readInt32LE(index * 4);
41
+ }
42
+ if (expectedChecksum !== 0) {
43
+ assertChecksum(entry.file, checksum(values), expectedChecksum);
44
+ }
45
+ return values;
46
+ }
47
+ function readUint16Table(assetDirectory, entry, expectedChecksum) {
48
+ const buffer = readFileSync(path.join(assetDirectory, entry.file));
49
+ if (buffer.length !== entry.entries * 2) {
50
+ throw new Error(`Invalid byte size for ${entry.file}`);
51
+ }
52
+ const values = new Uint16Array(entry.entries);
53
+ for (let index = 0; index < values.length; index += 1) {
54
+ values[index] = buffer.readUInt16LE(index * 2);
55
+ }
56
+ if (expectedChecksum !== 0) {
57
+ assertChecksum(entry.file, checksum(values), expectedChecksum);
58
+ }
59
+ return values;
60
+ }
61
+ function readInt8Table(assetDirectory, entry, expectedChecksum) {
62
+ const buffer = readFileSync(path.join(assetDirectory, entry.file));
63
+ if (buffer.length !== entry.entries) {
64
+ throw new Error(`Invalid byte size for ${entry.file}`);
65
+ }
66
+ const values = new Int8Array(buffer);
67
+ if (expectedChecksum !== 0) {
68
+ assertChecksum(entry.file, checksum(values), expectedChecksum);
69
+ }
70
+ return values;
71
+ }
72
+ function resolveGeneratedAssetDirectory() {
73
+ const envDirectory = process.env.CUBINGCENTER_SCRAMBLER_TABLES_DIR;
74
+ if (envDirectory && existsSync(path.join(envDirectory, "manifest.json"))) {
75
+ return envDirectory;
76
+ }
77
+ for (const candidate of getAssetDirectoryCandidates()) {
78
+ if (existsSync(path.join(candidate, "manifest.json"))) {
79
+ return candidate;
80
+ }
81
+ }
82
+ throw new Error("Unable to find generated Square-1 solver tables. Run pnpm sq1:tables.");
83
+ }
84
+ function getAssetDirectoryCandidates() {
85
+ const cwd = process.cwd();
86
+ const candidates = [
87
+ path.join(cwd, "src", GENERATED_DIRECTORY),
88
+ path.join(cwd, "dist", GENERATED_DIRECTORY),
89
+ path.join(cwd, "dist-cjs", GENERATED_DIRECTORY)
90
+ ];
91
+ try {
92
+ const requireFromCwd = createRequire(path.join(cwd, "package.json"));
93
+ const packageEntry = requireFromCwd.resolve("@cubingcenter/scrambler");
94
+ candidates.push(path.join(path.dirname(packageEntry), GENERATED_DIRECTORY));
95
+ }
96
+ catch {
97
+ // Source-tree usage is covered by the cwd candidates.
98
+ }
99
+ return candidates;
100
+ }
101
+ function assertChecksum(file, actual, expected) {
102
+ if (actual !== expected) {
103
+ throw new Error(`Checksum mismatch for ${file}: expected ${expected}, received ${actual}.`);
104
+ }
105
+ }
106
+ export function checksum(values) {
107
+ let hash = 0x811c9dc5;
108
+ for (let index = 0; index < values.length; index += 1) {
109
+ hash ^= values[index];
110
+ hash = Math.imul(hash, 0x01000193);
111
+ }
112
+ return hash >>> 0;
113
+ }
@@ -0,0 +1,27 @@
1
+ import { FullCube } from "./full-cube.js";
2
+ import { type Square1SolverTables } from "./tables.js";
3
+ export declare const INVERSE_SOLUTION = 2;
4
+ export interface Square1Solution {
5
+ moves: string[];
6
+ scramble: string;
7
+ depth: number;
8
+ }
9
+ export declare class Square1Searcher {
10
+ private tables;
11
+ private move;
12
+ private c;
13
+ private d;
14
+ private length1;
15
+ private movelen1;
16
+ private maxlen2;
17
+ private verbose;
18
+ private solString;
19
+ private solMoves;
20
+ constructor(tables?: Square1SolverTables);
21
+ solution(c: FullCube, verbose?: number): Square1Solution;
22
+ private idaPhase1;
23
+ private initPhase2;
24
+ private idaPhase2;
25
+ private formatSolution;
26
+ }
27
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../../../src/puzzles/sq1/solver/search.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAC1C,OAAO,EAA8B,KAAK,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAEnF,eAAO,MAAM,gBAAgB,IAAM,CAAC;AAEpC,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,qBAAa,eAAe;IAC1B,OAAO,CAAC,MAAM,CAAsB;IACpC,OAAO,CAAC,IAAI,CAA4B;IACxC,OAAO,CAAC,CAAC,CAA4B;IACrC,OAAO,CAAC,CAAC,CAA4B;IACrC,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,OAAO,CAAa;IAC5B,OAAO,CAAC,SAAS,CAAc;IAC/B,OAAO,CAAC,QAAQ,CAAgB;gBAEpB,MAAM,CAAC,EAAE,mBAAmB;IAIxC,QAAQ,CAAC,CAAC,EAAE,QAAQ,EAAE,OAAO,GAAE,MAAU,GAAG,eAAe;IAqB3D,OAAO,CAAC,SAAS;IA6DjB,OAAO,CAAC,UAAU;IAsBlB,OAAO,CAAC,SAAS;IA2FjB,OAAO,CAAC,cAAc;CA0CvB"}