@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,115 @@
1
+ import { FTO_AXIS_MAP } from "./types.js";
2
+ import { FtoCubie } from "./state.js";
3
+ const moveU = new FtoCubie([1, 2, 0, 3, 4, 5], [0, 0, 0, 0, 0, 0], [2, 0, 1, 3, 4, 5, 6, 7, 8, 9, 10, 11], [1, 2, 0, 3, 4, 5, 6, 7, 8, 9, 10, 11], [0, 1, 2, 3, 6, 7, 11, 9, 8, 5, 10, 4]);
4
+ const moveF = new FtoCubie([4, 1, 2, 3, 5, 0], [1, 0, 0, 0, 1, 0], [0, 1, 2, 3, 4, 6, 7, 5, 8, 9, 10, 11], [0, 1, 2, 4, 5, 3, 6, 7, 8, 9, 10, 11], [0, 9, 10, 3, 4, 5, 2, 7, 1, 8, 6, 11]);
5
+ const moveBR = new FtoCubie([0, 5, 2, 1, 4, 3], [0, 1, 0, 0, 0, 1], [0, 1, 2, 3, 10, 5, 6, 7, 8, 9, 11, 4], [0, 1, 2, 3, 4, 5, 7, 8, 6, 9, 10, 11], [5, 3, 2, 11, 4, 10, 6, 7, 8, 9, 0, 1]);
6
+ const moveBL = new FtoCubie([0, 1, 3, 4, 2, 5], [0, 0, 1, 1, 0, 0], [0, 1, 2, 8, 4, 5, 6, 7, 9, 3, 10, 11], [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 9], [8, 1, 7, 2, 0, 5, 6, 3, 4, 9, 10, 11]);
7
+ const moveD = new FtoCubie([0, 1, 2, 5, 3, 4], [0, 0, 0, 0, 0, 0], [0, 1, 2, 4, 5, 3, 6, 7, 8, 9, 10, 11], [0, 1, 2, 3, 9, 10, 5, 7, 4, 8, 6, 11], [1, 2, 0, 3, 4, 5, 6, 7, 8, 9, 10, 11]);
8
+ const moveB = new FtoCubie([0, 3, 1, 2, 4, 5], [0, 1, 1, 0, 0, 0], [0, 1, 10, 3, 4, 5, 6, 7, 8, 2, 9, 11], [0, 6, 7, 3, 4, 5, 11, 9, 8, 2, 10, 1], [0, 1, 2, 4, 5, 3, 6, 7, 8, 9, 10, 11]);
9
+ const moveR = new FtoCubie([5, 0, 2, 3, 4, 1], [1, 1, 0, 0, 0, 0], [6, 1, 2, 3, 4, 5, 11, 7, 8, 9, 10, 0], [5, 3, 2, 8, 4, 7, 6, 0, 1, 9, 10, 11], [0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 9]);
10
+ const moveL = new FtoCubie([2, 1, 4, 3, 0, 5], [1, 0, 1, 0, 0, 0], [0, 8, 2, 3, 4, 5, 6, 1, 7, 9, 10, 11], [11, 1, 10, 2, 0, 5, 6, 7, 8, 9, 3, 4], [0, 1, 2, 3, 4, 5, 7, 8, 6, 9, 10, 11]);
11
+ export const FTO_MOVE_MAP = {
12
+ U: moveU,
13
+ "U'": FtoCubie.multiply(moveU, moveU),
14
+ F: moveF,
15
+ "F'": FtoCubie.multiply(moveF, moveF),
16
+ BR: moveBR,
17
+ "BR'": FtoCubie.multiply(moveBR, moveBR),
18
+ BL: moveBL,
19
+ "BL'": FtoCubie.multiply(moveBL, moveBL),
20
+ D: moveD,
21
+ "D'": FtoCubie.multiply(moveD, moveD),
22
+ B: moveB,
23
+ "B'": FtoCubie.multiply(moveB, moveB),
24
+ R: moveR,
25
+ "R'": FtoCubie.multiply(moveR, moveR),
26
+ L: moveL,
27
+ "L'": FtoCubie.multiply(moveL, moveL)
28
+ };
29
+ export function getFtoMoveFace(move) {
30
+ const base = move.replace(/'$/, "");
31
+ return base;
32
+ }
33
+ export function invertFtoMove(move) {
34
+ if (move.endsWith("'")) {
35
+ return move.slice(0, -1);
36
+ }
37
+ return `${move}'`;
38
+ }
39
+ export function invertFtoAlgorithm(moves) {
40
+ const inverted = new Array(moves.length);
41
+ for (let i = 0; i < moves.length; i++) {
42
+ inverted[moves.length - 1 - i] = invertFtoMove(moves[i]);
43
+ }
44
+ return inverted;
45
+ }
46
+ export function parseFtoAlgorithm(algorithm) {
47
+ const tokens = algorithm.trim().split(/\s+/).filter(Boolean);
48
+ const result = [];
49
+ for (const token of tokens) {
50
+ if (token in FTO_MOVE_MAP) {
51
+ result.push(token);
52
+ }
53
+ else {
54
+ throw new Error(`Invalid FTO move: ${token}`);
55
+ }
56
+ }
57
+ return result;
58
+ }
59
+ export function formatFtoAlgorithm(moves) {
60
+ return moves.join(" ");
61
+ }
62
+ export function applyFtoMove(state, move) {
63
+ const moveCubie = FTO_MOVE_MAP[move];
64
+ if (!moveCubie) {
65
+ throw new Error(`Unsupported FTO move: ${move}`);
66
+ }
67
+ return FtoCubie.multiply(state, moveCubie);
68
+ }
69
+ export function applyFtoAlgorithm(state, algorithm) {
70
+ const moves = typeof algorithm === "string" ? parseFtoAlgorithm(algorithm) : algorithm;
71
+ let current = state;
72
+ for (const move of moves) {
73
+ current = applyFtoMove(current, move);
74
+ }
75
+ return current;
76
+ }
77
+ const FTO_AXIS_ORDER = {
78
+ U: 0,
79
+ D: 1,
80
+ F: 0,
81
+ B: 1,
82
+ L: 0,
83
+ BR: 1,
84
+ R: 0,
85
+ BL: 1
86
+ };
87
+ export function isRedundantFtoMove(moves, newMove) {
88
+ if (moves.length === 0)
89
+ return false;
90
+ const newFace = getFtoMoveFace(newMove);
91
+ const newAxis = FTO_AXIS_MAP[newFace];
92
+ const lastMove = moves[moves.length - 1];
93
+ const lastFace = getFtoMoveFace(lastMove);
94
+ // No same face consecutively
95
+ if (lastFace === newFace)
96
+ return true;
97
+ const lastAxis = FTO_AXIS_MAP[lastFace];
98
+ // Different axis is always allowed
99
+ if (newAxis !== lastAxis)
100
+ return false;
101
+ // Same axis (commutes): enforce canonical order
102
+ // to avoid duplicates like [D, U] vs [U, D] and prevent sequences like [U, D, U]
103
+ if (moves.length >= 2) {
104
+ const prevMove = moves[moves.length - 2];
105
+ const prevFace = getFtoMoveFace(prevMove);
106
+ if (FTO_AXIS_MAP[prevFace] === newAxis) {
107
+ return true; // Already 2 moves on this axis in a row
108
+ }
109
+ }
110
+ // Canonical ordering for commuting faces on the same axis
111
+ if (FTO_AXIS_ORDER[newFace] <= FTO_AXIS_ORDER[lastFace]) {
112
+ return true;
113
+ }
114
+ return false;
115
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Uniform random-state generation for Face-Turning Octahedron (FTO).
3
+ *
4
+ * Samples uniformly from the 3.14 x 10^22 reachable states:
5
+ * - Corner permutation in A_6 (360)
6
+ * - Corner orientation in Z_2^5 with sum ≡ 0 (mod 2) (32)
7
+ * - Edge permutation in A_12 (239,500,800)
8
+ * - Orbit 1 centers (uf): multiset arrangement C(12,3)*C(9,3)*C(6,3) (369,600)
9
+ * - Orbit 2 centers (rl): multiset arrangement C(12,3)*C(9,3)*C(6,3) (369,600)
10
+ */
11
+ import type { FtoRandomStateOptions } from "./types.js";
12
+ import { FtoCubie } from "./state.js";
13
+ /**
14
+ * Generates a legal, uniformly-sampled random FTO state.
15
+ */
16
+ export declare function generateRandomFtoState(options?: FtoRandomStateOptions): FtoCubie;
17
+ //# sourceMappingURL=random-state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"random-state.d.ts","sourceRoot":"","sources":["../../../src/puzzles/fto/random-state.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAWH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAQtC;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,GAAE,qBAA0B,GAAG,QAAQ,CA2BpF"}
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Uniform random-state generation for Face-Turning Octahedron (FTO).
3
+ *
4
+ * Samples uniformly from the 3.14 x 10^22 reachable states:
5
+ * - Corner permutation in A_6 (360)
6
+ * - Corner orientation in Z_2^5 with sum ≡ 0 (mod 2) (32)
7
+ * - Edge permutation in A_12 (239,500,800)
8
+ * - Orbit 1 centers (uf): multiset arrangement C(12,3)*C(9,3)*C(6,3) (369,600)
9
+ * - Orbit 2 centers (rl): multiset arrangement C(12,3)*C(9,3)*C(6,3) (369,600)
10
+ */
11
+ import { createRandomSource } from "../../random/index.js";
12
+ import { FTO_CENTER_ORBIT_STATES, FTO_CORNER_COUNT, FTO_CORNER_ORI_STATES, FTO_CORNER_PERM_STATES, FTO_EDGE_COUNT, FTO_EDGE_PERM_STATES } from "./types.js";
13
+ import { FtoCubie } from "./state.js";
14
+ import { unpackCenterOrbit, unpackCornerOrientation, unpackEvenPerm } from "./coordinates.js";
15
+ import { isTrivialFtoState } from "./validation.js";
16
+ /**
17
+ * Generates a legal, uniformly-sampled random FTO state.
18
+ */
19
+ export function generateRandomFtoState(options = {}) {
20
+ const random = createRandomSource(options.seed);
21
+ const rejectTrivial = options.rejectTrivial ?? true;
22
+ for (let attempt = 0; attempt < 100; attempt++) {
23
+ const cpRank = random.nextInt(FTO_CORNER_PERM_STATES);
24
+ const coRank = random.nextInt(FTO_CORNER_ORI_STATES);
25
+ const epRank = random.nextInt(FTO_EDGE_PERM_STATES);
26
+ const ufRank = random.nextInt(FTO_CENTER_ORBIT_STATES);
27
+ const rlRank = random.nextInt(FTO_CENTER_ORBIT_STATES);
28
+ const cp = unpackEvenPerm(FTO_CORNER_COUNT, cpRank);
29
+ const co = unpackCornerOrientation(coRank);
30
+ const ep = unpackEvenPerm(FTO_EDGE_COUNT, epRank);
31
+ const uf = unpackCenterOrbit(ufRank);
32
+ const rl = unpackCenterOrbit(rlRank);
33
+ const state = new FtoCubie(cp, co, ep, uf, rl);
34
+ if (rejectTrivial && isTrivialFtoState(state)) {
35
+ continue;
36
+ }
37
+ return state;
38
+ }
39
+ throw new Error("Unable to generate a non-trivial random FTO state.");
40
+ }
@@ -0,0 +1,6 @@
1
+ import type { ScrambleGenerator, ScrambleOptions, ScrambleResult } from "../../core/index.js";
2
+ export declare const ftoScrambleGenerator: ScrambleGenerator;
3
+ export declare function generateFtoScramble(options?: ScrambleOptions & {
4
+ skipValidation?: boolean;
5
+ }): ScrambleResult;
6
+ //# sourceMappingURL=scrambler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scrambler.d.ts","sourceRoot":"","sources":["../../../src/puzzles/fto/scrambler.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,iBAAiB,EACjB,eAAe,EACf,cAAc,EACf,MAAM,qBAAqB,CAAC;AAU7B,eAAO,MAAM,oBAAoB,EAAE,iBAalC,CAAC;AAEF,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,eAAe,GAAG;IAAE,cAAc,CAAC,EAAE,OAAO,CAAA;CAAO,GAC3D,cAAc,CAuChB"}
@@ -0,0 +1,49 @@
1
+ import { createRandomSource } from "../../random/index.js";
2
+ import { applyFtoAlgorithm, invertFtoAlgorithm } from "./moves.js";
3
+ import { createSolvedFtoState } from "./state.js";
4
+ import { formatFtoFacelets } from "./facelets.js";
5
+ import { generateFtoRandomState } from "./solver/index.js";
6
+ export const ftoScrambleGenerator = {
7
+ info: {
8
+ eventId: "fto",
9
+ name: "Face-Turning Octahedron",
10
+ puzzle: "fto",
11
+ quality: "random-state",
12
+ generator: "fto-three-phase",
13
+ description: "Random-state Face-Turning Octahedron scramble generated by a 3-phase reduction solver."
14
+ },
15
+ generate(options = {}) {
16
+ return generateFtoScramble(options);
17
+ }
18
+ };
19
+ export function generateFtoScramble(options = {}) {
20
+ const random = createRandomSource(options.seed);
21
+ const { scramble, moves, state, facelets } = generateFtoRandomState(() => random.next());
22
+ if (!options.skipValidation) {
23
+ const replayed = applyFtoAlgorithm(createSolvedFtoState(), moves);
24
+ if (!replayed.isEqual(state)) {
25
+ throw new Error("Generated FTO scramble does not reproduce the target random state.");
26
+ }
27
+ }
28
+ const solutionMoves = invertFtoAlgorithm(moves);
29
+ const faceletString = formatFtoFacelets(facelets);
30
+ const result = {
31
+ eventId: "fto",
32
+ scramble,
33
+ moves,
34
+ quality: "random-state",
35
+ generator: "fto-three-phase",
36
+ metadata: {
37
+ totalMoves: moves.length,
38
+ solutionDepth: solutionMoves.length,
39
+ solutionMoves,
40
+ state,
41
+ facelets,
42
+ faceletString
43
+ }
44
+ };
45
+ if (options.seed !== undefined) {
46
+ result.seed = options.seed;
47
+ }
48
+ return result;
49
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Face-Turning Octahedron (FTO) 3-Phase Random-State Solver & Scrambler Engine.
3
+ * Adapted from cs0x7f / Shuang Chen reference implementation under MIT License.
4
+ */
5
+ import { FtoCubie } from "../state.js";
6
+ import { toFtoFacelets } from "../facelets.js";
7
+ import type { FtoMove } from "../types.js";
8
+ export declare function initFtoSolver(): void;
9
+ export declare function isFtoSolverInitialized(): boolean;
10
+ export declare function solveFtoFacelet(facelet: readonly number[], invSol?: boolean): string;
11
+ export declare function solveFto(fc: FtoCubie): FtoMove[];
12
+ export declare function generateFtoRandomState(rng?: () => number): {
13
+ scramble: string;
14
+ moves: FtoMove[];
15
+ state: FtoCubie;
16
+ facelets: ReturnType<typeof toFtoFacelets>;
17
+ };
18
+ //# sourceMappingURL=engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../../../../src/puzzles/fto/solver/engine.ts"],"names":[],"mappings":"AACA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAEvC,OAAO,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAC/C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AA2rC3C,wBAAgB,aAAa,IAAI,IAAI,CAEpC;AAED,wBAAgB,sBAAsB,IAAI,OAAO,CAEhD;AAED,wBAAgB,eAAe,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,MAAM,UAAQ,GAAG,MAAM,CAElF;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,EAAE,CAIhD;AAED,wBAAgB,sBAAsB,CAAC,GAAG,GAAE,MAAM,MAAoB,GAAG;IACvE,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,KAAK,EAAE,QAAQ,CAAC;IAChB,QAAQ,EAAE,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;CAC5C,CAYA"}