@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,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.generateFtoRandomState = exports.solveFtoFacelet = exports.isFtoSolverInitialized = exports.initFtoSolver = exports.solveFto = void 0;
4
+ var engine_js_1 = require("./engine.js");
5
+ Object.defineProperty(exports, "solveFto", { enumerable: true, get: function () { return engine_js_1.solveFto; } });
6
+ Object.defineProperty(exports, "initFtoSolver", { enumerable: true, get: function () { return engine_js_1.initFtoSolver; } });
7
+ Object.defineProperty(exports, "isFtoSolverInitialized", { enumerable: true, get: function () { return engine_js_1.isFtoSolverInitialized; } });
8
+ Object.defineProperty(exports, "solveFtoFacelet", { enumerable: true, get: function () { return engine_js_1.solveFtoFacelet; } });
9
+ Object.defineProperty(exports, "generateFtoRandomState", { enumerable: true, get: function () { return engine_js_1.generateFtoRandomState; } });
@@ -0,0 +1,69 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FtoCubie = void 0;
4
+ exports.createSolvedFtoState = createSolvedFtoState;
5
+ exports.cloneFtoState = cloneFtoState;
6
+ exports.statesEqual = statesEqual;
7
+ exports.isSolvedFtoState = isSolvedFtoState;
8
+ class FtoCubie {
9
+ cp;
10
+ co;
11
+ ep;
12
+ uf;
13
+ rl;
14
+ constructor(cp, co, ep, uf, rl) {
15
+ this.cp = cp ? Array.from(cp) : [0, 1, 2, 3, 4, 5];
16
+ this.co = co ? Array.from(co) : [0, 0, 0, 0, 0, 0];
17
+ this.ep = ep ? Array.from(ep) : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
18
+ this.uf = uf ? Array.from(uf) : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
19
+ this.rl = rl ? Array.from(rl) : [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
20
+ }
21
+ clone() {
22
+ return new FtoCubie(this.cp, this.co, this.ep, this.uf, this.rl);
23
+ }
24
+ isEqual(other) {
25
+ for (let i = 0; i < 6; i++) {
26
+ if (this.cp[i] !== other.cp[i] || this.co[i] !== other.co[i]) {
27
+ return false;
28
+ }
29
+ }
30
+ for (let i = 0; i < 12; i++) {
31
+ if (this.ep[i] !== other.ep[i] ||
32
+ this.uf[i] !== other.uf[i] ||
33
+ this.rl[i] !== other.rl[i]) {
34
+ return false;
35
+ }
36
+ }
37
+ return true;
38
+ }
39
+ static multiply(...args) {
40
+ const prod = new FtoCubie();
41
+ for (let k = args.length - 1; k >= 0; k--) {
42
+ const a = args[k];
43
+ for (let i = 0; i < 6; i++) {
44
+ prod.co[i] = a.co[prod.cp[i]] ^ prod.co[i];
45
+ prod.cp[i] = a.cp[prod.cp[i]];
46
+ }
47
+ for (let i = 0; i < 12; i++) {
48
+ prod.ep[i] = a.ep[prod.ep[i]];
49
+ prod.uf[i] = a.uf[prod.uf[i]];
50
+ prod.rl[i] = a.rl[prod.rl[i]];
51
+ }
52
+ }
53
+ return prod;
54
+ }
55
+ }
56
+ exports.FtoCubie = FtoCubie;
57
+ function createSolvedFtoState() {
58
+ return new FtoCubie();
59
+ }
60
+ function cloneFtoState(state) {
61
+ return state.clone();
62
+ }
63
+ function statesEqual(a, b) {
64
+ return a.isEqual(b);
65
+ }
66
+ function isSolvedFtoState(state) {
67
+ const solved = new FtoCubie();
68
+ return state.isEqual(solved);
69
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FTO_CENTER_ORBIT_STATES = exports.FTO_EDGE_PERM_STATES = exports.FTO_CORNER_ORI_STATES = exports.FTO_CORNER_PERM_STATES = exports.FTO_CENTER_ORBIT_COUNT = exports.FTO_EDGE_COUNT = exports.FTO_CORNER_COUNT = exports.SCRAMBLE_LENGTH = exports.FTO_AXIS_MAP = exports.FTO_ALL_MOVES = exports.FTO_FACES = void 0;
4
+ exports.FTO_FACES = [
5
+ "U",
6
+ "D",
7
+ "F",
8
+ "B",
9
+ "L",
10
+ "BR",
11
+ "R",
12
+ "BL"
13
+ ];
14
+ exports.FTO_ALL_MOVES = [
15
+ "U",
16
+ "U'",
17
+ "D",
18
+ "D'",
19
+ "F",
20
+ "F'",
21
+ "B",
22
+ "B'",
23
+ "L",
24
+ "L'",
25
+ "R",
26
+ "R'",
27
+ "BL",
28
+ "BL'",
29
+ "BR",
30
+ "BR'"
31
+ ];
32
+ exports.FTO_AXIS_MAP = {
33
+ U: 0,
34
+ D: 0,
35
+ F: 1,
36
+ B: 1,
37
+ L: 2,
38
+ BR: 2,
39
+ R: 3,
40
+ BL: 3
41
+ };
42
+ exports.SCRAMBLE_LENGTH = 30;
43
+ exports.FTO_CORNER_COUNT = 6;
44
+ exports.FTO_EDGE_COUNT = 12;
45
+ exports.FTO_CENTER_ORBIT_COUNT = 12;
46
+ exports.FTO_CORNER_PERM_STATES = 360; // 6! / 2
47
+ exports.FTO_CORNER_ORI_STATES = 32; // 2^5
48
+ exports.FTO_EDGE_PERM_STATES = 239500800; // 12! / 2
49
+ exports.FTO_CENTER_ORBIT_STATES = 369600; // C(12,3) * C(9,3) * C(6,3)
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ /**
3
+ * Validation and reachability checking for FTO (Face-Turning Octahedron) states.
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.validateFtoState = validateFtoState;
7
+ exports.isTrivialFtoState = isTrivialFtoState;
8
+ const types_js_1 = require("./types.js");
9
+ const state_js_1 = require("./state.js");
10
+ const moves_js_1 = require("./moves.js");
11
+ const coordinates_js_1 = require("./coordinates.js");
12
+ /**
13
+ * Validates the physical and group-theoretic reachability constraints of an FTO state:
14
+ * - 6 corners with unique indices in 0..5 and even permutation parity (A_6)
15
+ * - 6 corner orientations in {0, 1} with sum ≡ 0 (mod 2)
16
+ * - 12 edges with unique indices in 0..11 and even permutation parity (A_12)
17
+ * - 12 centers in orbit 1 (uf) with exactly 3 of each of the 4 colors (0..3)
18
+ * - 12 centers in orbit 2 (rl) with exactly 3 of each of the 4 colors (0..3)
19
+ */
20
+ function validateFtoState(state) {
21
+ const errors = [];
22
+ // 1. Validate corners (cp)
23
+ if (!Array.isArray(state.cp) || state.cp.length !== types_js_1.FTO_CORNER_COUNT) {
24
+ errors.push(`Corner permutation array (cp) must have length ${types_js_1.FTO_CORNER_COUNT}`);
25
+ }
26
+ else {
27
+ const cpSeen = new Uint8Array(types_js_1.FTO_CORNER_COUNT);
28
+ let validRange = true;
29
+ for (let i = 0; i < types_js_1.FTO_CORNER_COUNT; i++) {
30
+ const v = state.cp[i];
31
+ if (v < 0 || v >= types_js_1.FTO_CORNER_COUNT || cpSeen[v] > 0) {
32
+ validRange = false;
33
+ break;
34
+ }
35
+ cpSeen[v] = 1;
36
+ }
37
+ if (!validRange) {
38
+ errors.push("Corner permutation array (cp) must contain a valid permutation of 0..5");
39
+ }
40
+ else if ((0, coordinates_js_1.getPermutationParity)(state.cp)) {
41
+ errors.push("Corner permutation must have even parity (A_6)");
42
+ }
43
+ }
44
+ // 2. Validate corner orientations (co)
45
+ if (!Array.isArray(state.co) || state.co.length !== types_js_1.FTO_CORNER_COUNT) {
46
+ errors.push(`Corner orientation array (co) must have length ${types_js_1.FTO_CORNER_COUNT}`);
47
+ }
48
+ else {
49
+ let sum = 0;
50
+ let validValues = true;
51
+ for (let i = 0; i < types_js_1.FTO_CORNER_COUNT; i++) {
52
+ const o = state.co[i];
53
+ if (o !== 0 && o !== 1) {
54
+ validValues = false;
55
+ break;
56
+ }
57
+ sum += o;
58
+ }
59
+ if (!validValues) {
60
+ errors.push("Corner orientations must be 0 or 1");
61
+ }
62
+ else if ((sum & 1) !== 0) {
63
+ errors.push("Sum of corner orientations must be even (mod 2)");
64
+ }
65
+ }
66
+ // 3. Validate edges (ep)
67
+ if (!Array.isArray(state.ep) || state.ep.length !== types_js_1.FTO_EDGE_COUNT) {
68
+ errors.push(`Edge permutation array (ep) must have length ${types_js_1.FTO_EDGE_COUNT}`);
69
+ }
70
+ else {
71
+ const epSeen = new Uint8Array(types_js_1.FTO_EDGE_COUNT);
72
+ let validRange = true;
73
+ for (let i = 0; i < types_js_1.FTO_EDGE_COUNT; i++) {
74
+ const v = state.ep[i];
75
+ if (v < 0 || v >= types_js_1.FTO_EDGE_COUNT || epSeen[v] > 0) {
76
+ validRange = false;
77
+ break;
78
+ }
79
+ epSeen[v] = 1;
80
+ }
81
+ if (!validRange) {
82
+ errors.push("Edge permutation array (ep) must contain a valid permutation of 0..11");
83
+ }
84
+ else if ((0, coordinates_js_1.getPermutationParity)(state.ep)) {
85
+ errors.push("Edge permutation must have even parity (A_12)");
86
+ }
87
+ }
88
+ // 4. Validate center orbit 1 (uf)
89
+ if (!Array.isArray(state.uf) || state.uf.length !== 12) {
90
+ errors.push("Center orbit 1 (uf) must have length 12");
91
+ }
92
+ else {
93
+ const counts = [0, 0, 0, 0];
94
+ for (let i = 0; i < 12; i++) {
95
+ const color = Math.floor(state.uf[i] / 3);
96
+ if (color >= 0 && color < 4) {
97
+ counts[color]++;
98
+ }
99
+ }
100
+ if (!counts.every((c) => c === 3)) {
101
+ errors.push("Center orbit 1 (uf) must contain exactly 3 pieces of each of the 4 colors");
102
+ }
103
+ }
104
+ // 5. Validate center orbit 2 (rl)
105
+ if (!Array.isArray(state.rl) || state.rl.length !== 12) {
106
+ errors.push("Center orbit 2 (rl) must have length 12");
107
+ }
108
+ else {
109
+ const counts = [0, 0, 0, 0];
110
+ for (let i = 0; i < 12; i++) {
111
+ const color = Math.floor(state.rl[i] / 3);
112
+ if (color >= 0 && color < 4) {
113
+ counts[color]++;
114
+ }
115
+ }
116
+ if (!counts.every((c) => c === 3)) {
117
+ errors.push("Center orbit 2 (rl) must contain exactly 3 pieces of each of the 4 colors");
118
+ }
119
+ }
120
+ return {
121
+ valid: errors.length === 0,
122
+ errors
123
+ };
124
+ }
125
+ let singleMoveStates = null;
126
+ function getSingleMoveStates() {
127
+ if (!singleMoveStates) {
128
+ const solved = (0, state_js_1.createSolvedFtoState)();
129
+ singleMoveStates = types_js_1.FTO_ALL_MOVES.map((move) => (0, moves_js_1.applyFtoMove)(solved, move));
130
+ }
131
+ return singleMoveStates;
132
+ }
133
+ /**
134
+ * Checks if a state is trivial (solved or 1 move away from solved).
135
+ */
136
+ function isTrivialFtoState(state) {
137
+ if ((0, state_js_1.isSolvedFtoState)(state)) {
138
+ return true;
139
+ }
140
+ const oneMoveStates = getSingleMoveStates();
141
+ for (let i = 0; i < oneMoveStates.length; i++) {
142
+ if (state.isEqual(oneMoveStates[i])) {
143
+ return true;
144
+ }
145
+ }
146
+ return false;
147
+ }
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.skewb = exports.clock = exports.pyraminx = exports.cube7x7 = exports.cube6x6 = exports.cube5x5 = exports.megaminx = exports.cube4 = exports.cube3 = exports.cube2 = void 0;
36
+ exports.sq1 = exports.fto = exports.skewb = exports.clock = exports.pyraminx = exports.cube7x7 = exports.cube6x6 = exports.cube5x5 = exports.megaminx = exports.cube4 = exports.cube3 = exports.cube2 = void 0;
37
37
  const index_js_1 = require("../core/index.js");
38
38
  const index_js_2 = require("./cube2/index.js");
39
39
  const index_js_3 = require("./cube3/index.js");
@@ -45,6 +45,8 @@ const index_js_8 = require("./cube7x7/index.js");
45
45
  const index_js_9 = require("./pyraminx/index.js");
46
46
  const index_js_10 = require("./clock/index.js");
47
47
  const index_js_11 = require("./skewb/index.js");
48
+ const index_js_12 = require("./fto/index.js");
49
+ const index_js_13 = require("./sq1/index.js");
48
50
  (0, index_js_1.registerScrambleGenerator)(index_js_2.cube2ScrambleGenerator);
49
51
  (0, index_js_1.registerScrambleGenerator)(index_js_3.cube3ScrambleGenerator);
50
52
  (0, index_js_1.registerScrambleGenerator)(index_js_4.cube4ScrambleGenerator);
@@ -55,6 +57,8 @@ const index_js_11 = require("./skewb/index.js");
55
57
  (0, index_js_1.registerScrambleGenerator)(index_js_9.pyraminxScrambleGenerator);
56
58
  (0, index_js_1.registerScrambleGenerator)(index_js_10.clockScrambleGenerator);
57
59
  (0, index_js_1.registerScrambleGenerator)(index_js_11.skewbScrambleGenerator);
60
+ (0, index_js_1.registerScrambleGenerator)(index_js_12.ftoScrambleGenerator);
61
+ (0, index_js_1.registerScrambleGenerator)(index_js_13.sq1ScrambleGenerator);
58
62
  exports.cube2 = __importStar(require("./cube2/index.js"));
59
63
  exports.cube3 = __importStar(require("./cube3/index.js"));
60
64
  exports.cube4 = __importStar(require("./cube4/index.js"));
@@ -65,3 +69,5 @@ exports.cube7x7 = __importStar(require("./cube7x7/index.js"));
65
69
  exports.pyraminx = __importStar(require("./pyraminx/index.js"));
66
70
  exports.clock = __importStar(require("./clock/index.js"));
67
71
  exports.skewb = __importStar(require("./skewb/index.js"));
72
+ exports.fto = __importStar(require("./fto/index.js"));
73
+ exports.sq1 = __importStar(require("./sq1/index.js"));
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.initializeScrambler = exports.getSupportedEvents = exports.getEventInfo = exports.generateScrambles = exports.generateScramble = exports.skewbScrambleGenerator = exports.generateSkewbScramble = exports.solver = exports.getStateFromIndex = exports.getStateIndex = exports.verifySkewbSolution = exports.verifySkewbScramble = exports.solveSkewbSync = exports.solveSkewbWithInfo = exports.solveSkewb = exports.toSkewbFacelets = exports.getSkewbFaceOrder = exports.formatSkewbFacelets = exports.createSolvedSkewbFacelets = exports.generateRandomSkewbState = exports.isOneMoveFromSolvedSkewbState = exports.isAllowedRandomSkewbState = exports.validateSkewbState = exports.permutationParity = exports.skewbStatesEqual = exports.isSolvedSkewbState = exports.createSolvedSkewbState = exports.cloneSkewbState = exports.parseSkewbMove = exports.parseSkewbAlgorithm = exports.invertSkewbMove = exports.invertSkewbAlgorithm = exports.formatSkewbAlgorithm = exports.applySkewbMove = exports.applySkewbAlgorithm = exports.SKEWB_FACES = exports.SKEWB_MOVES = void 0;
36
+ exports.initializeScrambler = exports.getSupportedEvents = exports.getEventInfo = exports.generateScrambles = exports.generateScramble = exports.skewbScrambleGenerator = exports.generateSkewbScramble = exports.solver = exports.getStateFromIndex = exports.getStateIndex = exports.verifySkewbSolution = exports.verifySkewbScramble = exports.solveSkewbSync = exports.solveSkewbWithInfo = exports.solveSkewb = exports.toSkewbFacelets = exports.getSkewbFaceOrder = exports.formatSkewbFacelets = exports.createSolvedSkewbFacelets = exports.generateRandomSkewbStateSync = exports.generateRandomSkewbState = exports.isOneMoveFromSolvedSkewbState = exports.isAllowedRandomSkewbState = exports.validateSkewbState = exports.permutationParity = exports.skewbStatesEqual = exports.isSolvedSkewbState = exports.createSolvedSkewbState = exports.cloneSkewbState = exports.parseSkewbMove = exports.parseSkewbAlgorithm = exports.invertSkewbMove = exports.invertSkewbAlgorithm = exports.formatSkewbAlgorithm = exports.applySkewbMove = exports.applySkewbAlgorithm = exports.SKEWB_FACES = exports.SKEWB_MOVES = void 0;
37
37
  const index_js_1 = require("../../core/index.js");
38
38
  const scrambler_js_1 = require("./scrambler.js");
39
39
  (0, index_js_1.registerScrambleGenerator)(scrambler_js_1.skewbScrambleGenerator);
@@ -60,6 +60,7 @@ Object.defineProperty(exports, "isAllowedRandomSkewbState", { enumerable: true,
60
60
  Object.defineProperty(exports, "isOneMoveFromSolvedSkewbState", { enumerable: true, get: function () { return validation_js_1.isOneMoveFromSolvedSkewbState; } });
61
61
  var random_state_js_1 = require("./random-state.js");
62
62
  Object.defineProperty(exports, "generateRandomSkewbState", { enumerable: true, get: function () { return random_state_js_1.generateRandomSkewbState; } });
63
+ Object.defineProperty(exports, "generateRandomSkewbStateSync", { enumerable: true, get: function () { return random_state_js_1.generateRandomSkewbStateSync; } });
63
64
  var facelets_js_1 = require("./facelets.js");
64
65
  Object.defineProperty(exports, "createSolvedSkewbFacelets", { enumerable: true, get: function () { return facelets_js_1.createSolvedSkewbFacelets; } });
65
66
  Object.defineProperty(exports, "formatSkewbFacelets", { enumerable: true, get: function () { return facelets_js_1.formatSkewbFacelets; } });
@@ -5,7 +5,10 @@ exports.generateRandomSkewbStateSync = generateRandomSkewbStateSync;
5
5
  const index_js_1 = require("../../random/index.js");
6
6
  const index_js_2 = require("./solver/index.js");
7
7
  async function generateRandomSkewbState(options = {}) {
8
- await (0, index_js_2.ensureTablesLoaded)();
8
+ // Only pay the await/table-load cost when the tables are not already
9
+ // loaded: in the hot path this runs the sync body directly.
10
+ if (!(0, index_js_2.areSkewbTablesLoaded)())
11
+ await (0, index_js_2.ensureTablesLoaded)();
9
12
  return generateRandomSkewbStateSync(options);
10
13
  }
11
14
  // Synchronous variant for callers that have already ensured the tables are
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.toSquare1Facelets = toSquare1Facelets;
4
+ exports.formatSquare1Facelets = formatSquare1Facelets;
5
+ /**
6
+ * Converts a Square-1 state into a Square1Facelets structure.
7
+ * Extracting face colors and side rim colors for the 12 slots on top and bottom,
8
+ * and the middle layer state.
9
+ */
10
+ function toSquare1Facelets(state) {
11
+ return {
12
+ top: state.top.map((s) => s.faceColor),
13
+ topSides: state.top.map((s) => s.sideColor),
14
+ bottom: state.bottom.map((s) => s.faceColor),
15
+ bottomSides: state.bottom.map((s) => s.sideColor),
16
+ middle: state.middle,
17
+ topSlots: state.top.map((s) => ({ ...s })),
18
+ bottomSlots: state.bottom.map((s) => ({ ...s })),
19
+ };
20
+ }
21
+ /**
22
+ * Formats Square1Facelets into a compact serialization string.
23
+ */
24
+ function formatSquare1Facelets(facelets) {
25
+ const topStr = facelets.top.join("");
26
+ const topSidesStr = facelets.topSides.join("");
27
+ const botStr = facelets.bottom.join("");
28
+ const botSidesStr = facelets.bottomSides.join("");
29
+ return `${topStr}:${topSidesStr}/${botStr}:${botSidesStr}/${facelets.middle}`;
30
+ }
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initializeScrambler = exports.getSupportedEvents = exports.getEventInfo = exports.generateScrambles = exports.generateScramble = exports.INVERSE_SOLUTION = exports.generateSquare1SolverTables = exports.getSquare1SolverTablesSync = exports.areSquare1TablesLoaded = exports.ensureSquare1TablesLoaded = exports.Square1Searcher = exports.stateToFullCube = exports.fullCubeToState = exports.FullCube = exports.generateSquare1ScrambleSync = exports.generateSquare1Scramble = exports.sq1ScrambleGenerator = exports.generateRandomSquare1State = exports.isTrivialSquare1State = exports.validateSquare1State = exports.formatSquare1Facelets = exports.toSquare1Facelets = exports.invertSquare1Algorithm = exports.invertSquare1Move = exports.applySquare1Algorithm = exports.applySquare1Move = exports.formatSquare1Algorithm = exports.parseSquare1Algorithm = exports.getValidTurns = exports.applySlice = exports.applyTurn = exports.applyBottomTurn = exports.applyTopTurn = exports.isSliceable = exports.isSolvedSquare1State = exports.statesEqual = exports.cloneSquare1State = exports.createSolvedSquare1State = void 0;
4
+ const index_js_1 = require("../../core/index.js");
5
+ const scrambler_js_1 = require("./scrambler.js");
6
+ (0, index_js_1.registerScrambleGenerator)(scrambler_js_1.sq1ScrambleGenerator);
7
+ var state_js_1 = require("./state.js");
8
+ Object.defineProperty(exports, "createSolvedSquare1State", { enumerable: true, get: function () { return state_js_1.createSolvedSquare1State; } });
9
+ Object.defineProperty(exports, "cloneSquare1State", { enumerable: true, get: function () { return state_js_1.cloneSquare1State; } });
10
+ Object.defineProperty(exports, "statesEqual", { enumerable: true, get: function () { return state_js_1.statesEqual; } });
11
+ Object.defineProperty(exports, "isSolvedSquare1State", { enumerable: true, get: function () { return state_js_1.isSolvedSquare1State; } });
12
+ var moves_js_1 = require("./moves.js");
13
+ Object.defineProperty(exports, "isSliceable", { enumerable: true, get: function () { return moves_js_1.isSliceable; } });
14
+ Object.defineProperty(exports, "applyTopTurn", { enumerable: true, get: function () { return moves_js_1.applyTopTurn; } });
15
+ Object.defineProperty(exports, "applyBottomTurn", { enumerable: true, get: function () { return moves_js_1.applyBottomTurn; } });
16
+ Object.defineProperty(exports, "applyTurn", { enumerable: true, get: function () { return moves_js_1.applyTurn; } });
17
+ Object.defineProperty(exports, "applySlice", { enumerable: true, get: function () { return moves_js_1.applySlice; } });
18
+ Object.defineProperty(exports, "getValidTurns", { enumerable: true, get: function () { return moves_js_1.getValidTurns; } });
19
+ Object.defineProperty(exports, "parseSquare1Algorithm", { enumerable: true, get: function () { return moves_js_1.parseSquare1Algorithm; } });
20
+ Object.defineProperty(exports, "formatSquare1Algorithm", { enumerable: true, get: function () { return moves_js_1.formatSquare1Algorithm; } });
21
+ Object.defineProperty(exports, "applySquare1Move", { enumerable: true, get: function () { return moves_js_1.applySquare1Move; } });
22
+ Object.defineProperty(exports, "applySquare1Algorithm", { enumerable: true, get: function () { return moves_js_1.applySquare1Algorithm; } });
23
+ Object.defineProperty(exports, "invertSquare1Move", { enumerable: true, get: function () { return moves_js_1.invertSquare1Move; } });
24
+ Object.defineProperty(exports, "invertSquare1Algorithm", { enumerable: true, get: function () { return moves_js_1.invertSquare1Algorithm; } });
25
+ var facelets_js_1 = require("./facelets.js");
26
+ Object.defineProperty(exports, "toSquare1Facelets", { enumerable: true, get: function () { return facelets_js_1.toSquare1Facelets; } });
27
+ Object.defineProperty(exports, "formatSquare1Facelets", { enumerable: true, get: function () { return facelets_js_1.formatSquare1Facelets; } });
28
+ var validation_js_1 = require("./validation.js");
29
+ Object.defineProperty(exports, "validateSquare1State", { enumerable: true, get: function () { return validation_js_1.validateSquare1State; } });
30
+ Object.defineProperty(exports, "isTrivialSquare1State", { enumerable: true, get: function () { return validation_js_1.isTrivialSquare1State; } });
31
+ var random_state_js_1 = require("./random-state.js");
32
+ Object.defineProperty(exports, "generateRandomSquare1State", { enumerable: true, get: function () { return random_state_js_1.generateRandomSquare1State; } });
33
+ var scrambler_js_2 = require("./scrambler.js");
34
+ Object.defineProperty(exports, "sq1ScrambleGenerator", { enumerable: true, get: function () { return scrambler_js_2.sq1ScrambleGenerator; } });
35
+ Object.defineProperty(exports, "generateSquare1Scramble", { enumerable: true, get: function () { return scrambler_js_2.generateSquare1Scramble; } });
36
+ Object.defineProperty(exports, "generateSquare1ScrambleSync", { enumerable: true, get: function () { return scrambler_js_2.generateSquare1ScrambleSync; } });
37
+ var index_js_2 = require("./solver/index.js");
38
+ Object.defineProperty(exports, "FullCube", { enumerable: true, get: function () { return index_js_2.FullCube; } });
39
+ Object.defineProperty(exports, "fullCubeToState", { enumerable: true, get: function () { return index_js_2.fullCubeToState; } });
40
+ Object.defineProperty(exports, "stateToFullCube", { enumerable: true, get: function () { return index_js_2.stateToFullCube; } });
41
+ Object.defineProperty(exports, "Square1Searcher", { enumerable: true, get: function () { return index_js_2.Square1Searcher; } });
42
+ Object.defineProperty(exports, "ensureSquare1TablesLoaded", { enumerable: true, get: function () { return index_js_2.ensureSquare1TablesLoaded; } });
43
+ Object.defineProperty(exports, "areSquare1TablesLoaded", { enumerable: true, get: function () { return index_js_2.areSquare1TablesLoaded; } });
44
+ Object.defineProperty(exports, "getSquare1SolverTablesSync", { enumerable: true, get: function () { return index_js_2.getSquare1SolverTablesSync; } });
45
+ Object.defineProperty(exports, "generateSquare1SolverTables", { enumerable: true, get: function () { return index_js_2.generateSquare1SolverTables; } });
46
+ Object.defineProperty(exports, "INVERSE_SOLUTION", { enumerable: true, get: function () { return index_js_2.INVERSE_SOLUTION; } });
47
+ var index_js_3 = require("../../core/index.js");
48
+ Object.defineProperty(exports, "generateScramble", { enumerable: true, get: function () { return index_js_3.generateScramble; } });
49
+ Object.defineProperty(exports, "generateScrambles", { enumerable: true, get: function () { return index_js_3.generateScrambles; } });
50
+ Object.defineProperty(exports, "getEventInfo", { enumerable: true, get: function () { return index_js_3.getEventInfo; } });
51
+ Object.defineProperty(exports, "getSupportedEvents", { enumerable: true, get: function () { return index_js_3.getSupportedEvents; } });
52
+ Object.defineProperty(exports, "initializeScrambler", { enumerable: true, get: function () { return index_js_3.initializeScrambler; } });
@@ -0,0 +1,234 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isSliceable = isSliceable;
4
+ exports.applyTopTurn = applyTopTurn;
5
+ exports.applyBottomTurn = applyBottomTurn;
6
+ exports.applyTurn = applyTurn;
7
+ exports.applySlice = applySlice;
8
+ exports.getValidTurns = getValidTurns;
9
+ exports.parseSquare1Algorithm = parseSquare1Algorithm;
10
+ exports.formatSquare1Algorithm = formatSquare1Algorithm;
11
+ exports.applySquare1Move = applySquare1Move;
12
+ exports.applySquare1Algorithm = applySquare1Algorithm;
13
+ exports.invertSquare1Move = invertSquare1Move;
14
+ exports.invertSquare1Algorithm = invertSquare1Algorithm;
15
+ const state_js_1 = require("./state.js");
16
+ /**
17
+ * Checks whether the puzzle is in a state where a slice (/) turn is physically possible.
18
+ * Both top and bottom layers must have clean cuts at 11/0 (Back seam) and 5/6 (Front seam).
19
+ */
20
+ function isSliceable(state) {
21
+ // Top layer seam at 11/0
22
+ if (state.top[11].isCorner && state.top[0].isCorner && state.top[11].pieceId === state.top[0].pieceId) {
23
+ return false;
24
+ }
25
+ // Top layer seam at 5/6
26
+ if (state.top[5].isCorner && state.top[6].isCorner && state.top[5].pieceId === state.top[6].pieceId) {
27
+ return false;
28
+ }
29
+ // Bottom layer seam at 11/0
30
+ if (state.bottom[11].isCorner && state.bottom[0].isCorner && state.bottom[11].pieceId === state.bottom[0].pieceId) {
31
+ return false;
32
+ }
33
+ // Bottom layer seam at 5/6
34
+ if (state.bottom[5].isCorner && state.bottom[6].isCorner && state.bottom[5].pieceId === state.bottom[6].pieceId) {
35
+ return false;
36
+ }
37
+ return true;
38
+ }
39
+ /**
40
+ * Applies a clockwise turn of the top layer by u * 30 degrees (u in range -5..6 or any integer).
41
+ */
42
+ function applyTopTurn(state, u) {
43
+ const normU = ((u % 12) + 12) % 12;
44
+ if (normU === 0)
45
+ return (0, state_js_1.cloneSquare1State)(state);
46
+ const newTop = Array.from({ length: 12 }, (_, i) => ({
47
+ ...state.top[(i - normU + 12) % 12],
48
+ }));
49
+ return {
50
+ top: newTop,
51
+ bottom: state.bottom.map((s) => ({ ...s })),
52
+ middle: state.middle,
53
+ };
54
+ }
55
+ /**
56
+ * Applies a turn of the bottom layer by d * 30 degrees (d in range -5..6 or any integer).
57
+ */
58
+ function applyBottomTurn(state, d) {
59
+ const normD = ((d % 12) + 12) % 12;
60
+ if (normD === 0)
61
+ return (0, state_js_1.cloneSquare1State)(state);
62
+ const newBottom = Array.from({ length: 12 }, (_, i) => ({
63
+ ...state.bottom[(i - normD + 12) % 12],
64
+ }));
65
+ return {
66
+ top: state.top.map((s) => ({ ...s })),
67
+ bottom: newBottom,
68
+ middle: state.middle,
69
+ };
70
+ }
71
+ /**
72
+ * Applies simultaneous top (u) and bottom (d) turns.
73
+ */
74
+ function applyTurn(state, u, d) {
75
+ const normU = ((u % 12) + 12) % 12;
76
+ const normD = ((d % 12) + 12) % 12;
77
+ const newTop = normU === 0
78
+ ? state.top.map((s) => ({ ...s }))
79
+ : Array.from({ length: 12 }, (_, i) => ({ ...state.top[(i - normU + 12) % 12] }));
80
+ const newBottom = normD === 0
81
+ ? state.bottom.map((s) => ({ ...s }))
82
+ : Array.from({ length: 12 }, (_, i) => ({ ...state.bottom[(i - normD + 12) % 12] }));
83
+ return {
84
+ top: newTop,
85
+ bottom: newBottom,
86
+ middle: state.middle,
87
+ };
88
+ }
89
+ /**
90
+ * Applies a slice (/) move, swapping the right half of top (slots 6..11)
91
+ * with the right half of bottom (slots 0..5).
92
+ */
93
+ function applySlice(state) {
94
+ if (!isSliceable(state)) {
95
+ throw new Error("Square-1: cannot slice non-sliceable state (corner cuts across seam)");
96
+ }
97
+ const next = (0, state_js_1.cloneSquare1State)(state);
98
+ for (let k = 0; k < 6; k++) {
99
+ const topSlot = 6 + k;
100
+ const bottomSlot = k;
101
+ const pieceFromBottom = { ...state.bottom[bottomSlot] };
102
+ const pieceFromTop = { ...state.top[topSlot] };
103
+ next.top[topSlot] = pieceFromBottom;
104
+ next.bottom[bottomSlot] = pieceFromTop;
105
+ }
106
+ next.middle = 1 - next.middle;
107
+ return next;
108
+ }
109
+ /**
110
+ * Returns all (u, d) turns from the current state that lead to a sliceable state.
111
+ * u and d are within range [-5, 6].
112
+ */
113
+ function getValidTurns(state) {
114
+ const valid = [];
115
+ for (let u = -5; u <= 6; u++) {
116
+ for (let d = -5; d <= 6; d++) {
117
+ const turned = applyTurn(state, u, d);
118
+ if (isSliceable(turned)) {
119
+ valid.push([u, d]);
120
+ }
121
+ }
122
+ }
123
+ return valid;
124
+ }
125
+ /**
126
+ * Parses a Square-1 algorithm string into individual move tokens.
127
+ * Supported tokens: "/", "(u, d)", "(u, d) /", etc.
128
+ */
129
+ function parseSquare1Algorithm(alg) {
130
+ if (!alg)
131
+ return [];
132
+ const trimmed = alg.trim();
133
+ if (!trimmed)
134
+ return [];
135
+ // Match (u, d) or /
136
+ const regex = /(\/\s*|\(\s*-?\d+\s*,\s*-?\d+\s*\)\s*)/g;
137
+ const tokens = [];
138
+ let match;
139
+ while ((match = regex.exec(trimmed)) !== null) {
140
+ const token = match[1].trim();
141
+ if (token) {
142
+ tokens.push(token);
143
+ }
144
+ }
145
+ if (tokens.length === 0) {
146
+ return trimmed.split(/\s+/);
147
+ }
148
+ return tokens;
149
+ }
150
+ /**
151
+ * Formats an array of Square-1 move tokens into standard WCA notation.
152
+ */
153
+ function formatSquare1Algorithm(moves) {
154
+ return moves.join(" ").replace(/\s*\/\s*/g, " / ").replace(/\s+/g, " ").trim();
155
+ }
156
+ /**
157
+ * Applies a single move token to the Square-1 state.
158
+ * Token can be "/", "(u, d)", or "(u, d) /".
159
+ */
160
+ function applySquare1Move(state, move) {
161
+ const clean = move.trim();
162
+ if (!clean)
163
+ return state;
164
+ if (clean === "/") {
165
+ return applySlice(state);
166
+ }
167
+ // Check if it's (u, d) or (u, d) /
168
+ const turnMatch = clean.match(/^\(\s*(-?\d+)\s*,\s*(-?\d+)\s*\)(\s*\/)?$/);
169
+ if (turnMatch) {
170
+ const u = parseInt(turnMatch[1], 10);
171
+ const d = parseInt(turnMatch[2], 10);
172
+ let s = applyTurn(state, u, d);
173
+ if (turnMatch[3]) {
174
+ s = applySlice(s);
175
+ }
176
+ return s;
177
+ }
178
+ throw new Error(`Square-1: unrecognized move '${move}'`);
179
+ }
180
+ /**
181
+ * Applies a full algorithm to a Square-1 state.
182
+ */
183
+ function applySquare1Algorithm(state, alg) {
184
+ const moves = Array.isArray(alg) ? alg : parseSquare1Algorithm(alg);
185
+ let current = state;
186
+ for (const move of moves) {
187
+ current = applySquare1Move(current, move);
188
+ }
189
+ return current;
190
+ }
191
+ /**
192
+ * Inverts a single Square-1 move token.
193
+ */
194
+ function invertSquare1Move(move) {
195
+ const clean = move.trim();
196
+ if (!clean || clean === "/")
197
+ return clean;
198
+ const turnMatch = clean.match(/^\(?\s*(-?\d+)\s*,\s*(-?\d+)\s*\)?(\s*\/)?$/);
199
+ if (turnMatch) {
200
+ const u = parseInt(turnMatch[1], 10);
201
+ const d = parseInt(turnMatch[2], 10);
202
+ const invU = u === 0 ? 0 : ((-u % 12) + 12) % 12 > 6 ? (((-u % 12) + 12) % 12) - 12 : ((-u % 12) + 12) % 12;
203
+ const invD = d === 0 ? 0 : ((-d % 12) + 12) % 12 > 6 ? (((-d % 12) + 12) % 12) - 12 : ((-d % 12) + 12) % 12;
204
+ return turnMatch[3] ? `/ (${invU}, ${invD})` : `(${invU}, ${invD})`;
205
+ }
206
+ return clean;
207
+ }
208
+ /**
209
+ * Inverts an entire Square-1 algorithm sequence.
210
+ */
211
+ function invertSquare1Algorithm(alg) {
212
+ const moves = Array.isArray(alg) ? alg : parseSquare1Algorithm(alg);
213
+ const inverted = [];
214
+ for (let i = moves.length - 1; i >= 0; i--) {
215
+ const m = moves[i].trim();
216
+ if (m === "/") {
217
+ inverted.push("/");
218
+ }
219
+ else {
220
+ const turnMatch = m.match(/^\(?\s*(-?\d+)\s*,\s*(-?\d+)\s*\)?(\s*\/)?$/);
221
+ if (turnMatch) {
222
+ const u = parseInt(turnMatch[1], 10);
223
+ const d = parseInt(turnMatch[2], 10);
224
+ const invU = u === 0 ? 0 : ((-u % 12) + 12) % 12 > 6 ? (((-u % 12) + 12) % 12) - 12 : ((-u % 12) + 12) % 12;
225
+ const invD = d === 0 ? 0 : ((-d % 12) + 12) % 12 > 6 ? (((-d % 12) + 12) % 12) - 12 : ((-d % 12) + 12) % 12;
226
+ if (turnMatch[3]) {
227
+ inverted.push("/");
228
+ }
229
+ inverted.push(`(${invU}, ${invD})`);
230
+ }
231
+ }
232
+ }
233
+ return inverted;
234
+ }