@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
@@ -40,8 +40,14 @@ export interface Cube4State {
40
40
  }
41
41
  export type Cube4Sticker = "U" | "R" | "F" | "D" | "L" | "B";
42
42
  export type Cube4Facelets = Record<Cube4Face, Cube4Sticker[]>;
43
+ export interface Cube4ValidationResult {
44
+ valid: boolean;
45
+ errors: string[];
46
+ }
43
47
  export interface Cube4RandomStateOptions {
44
48
  seed?: string | number;
49
+ /** Reject the solved state and the 36 single-move states. Defaults to true. */
50
+ rejectTrivial?: boolean;
45
51
  }
46
52
  /**
47
53
  * Corner numbering (same as 3x3):
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/puzzles/cube4/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,YAAY,IAAI,CAAC;AAC9B,eAAO,MAAM,UAAU,KAAK,CAAC;AAC7B,eAAO,MAAM,YAAY,KAAK,CAAC;AAC/B,eAAO,MAAM,UAAU,IAAI,CAAC;AAC5B,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAIlC,eAAO,MAAM,CAAC,IAAI,CAAC;AACnB,eAAO,MAAM,CAAC,IAAI,CAAC;AACnB,eAAO,MAAM,CAAC,IAAI,CAAC;AACnB,eAAO,MAAM,CAAC,IAAI,CAAC;AACnB,eAAO,MAAM,CAAC,IAAI,CAAC;AACnB,eAAO,MAAM,CAAC,IAAI,CAAC;AAEnB,MAAM,MAAM,SAAS,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAK1D,MAAM,MAAM,aAAa,GACrB,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GACjC,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE5C,MAAM,MAAM,eAAe,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,CAAC;AAC7C,MAAM,MAAM,SAAS,GAAG,GAAG,aAAa,GAAG,eAAe,EAAE,CAAC;AAE7D,eAAO,MAAM,gBAAgB,EAAE,SAAS,aAAa,EAGpD,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,SAAS,SAAS,EAE/C,CAAC;AAGF,eAAO,MAAM,iBAAiB,EAAE,SAAS,SAAS,EAIjD,CAAC;AAIF;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;CAC9B;AAED,MAAM,MAAM,YAAY,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE7D,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;AAE9D,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/puzzles/cube4/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,eAAO,MAAM,YAAY,IAAI,CAAC;AAC9B,eAAO,MAAM,UAAU,KAAK,CAAC;AAC7B,eAAO,MAAM,YAAY,KAAK,CAAC;AAC/B,eAAO,MAAM,UAAU,IAAI,CAAC;AAC5B,eAAO,MAAM,gBAAgB,IAAI,CAAC;AAIlC,eAAO,MAAM,CAAC,IAAI,CAAC;AACnB,eAAO,MAAM,CAAC,IAAI,CAAC;AACnB,eAAO,MAAM,CAAC,IAAI,CAAC;AACnB,eAAO,MAAM,CAAC,IAAI,CAAC;AACnB,eAAO,MAAM,CAAC,IAAI,CAAC;AACnB,eAAO,MAAM,CAAC,IAAI,CAAC;AAEnB,MAAM,MAAM,SAAS,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAK1D,MAAM,MAAM,aAAa,GACrB,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GACjC,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE5C,MAAM,MAAM,eAAe,GAAG,EAAE,GAAG,GAAG,GAAG,GAAG,CAAC;AAC7C,MAAM,MAAM,SAAS,GAAG,GAAG,aAAa,GAAG,eAAe,EAAE,CAAC;AAE7D,eAAO,MAAM,gBAAgB,EAAE,SAAS,aAAa,EAGpD,CAAC;AAEF,eAAO,MAAM,eAAe,EAAE,SAAS,SAAS,EAE/C,CAAC;AAGF,eAAO,MAAM,iBAAiB,EAAE,SAAS,SAAS,EAIjD,CAAC;AAIF;;;;;;;GAOG;AACH,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,UAAU,CAAC;IACxB,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;CAC9B;AAED,MAAM,MAAM,YAAY,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,CAAC;AAE7D,MAAM,MAAM,aAAa,GAAG,MAAM,CAAC,SAAS,EAAE,YAAY,EAAE,CAAC,CAAC;AAE9D,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACvB,+EAA+E;IAC/E,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG"}
@@ -0,0 +1,6 @@
1
+ import type { Cube4State, Cube4ValidationResult } from "./types.js";
2
+ export declare function validateCube4State(state: Cube4State): Cube4ValidationResult;
3
+ export declare function isOneMoveFromSolvedCube4State(state: Cube4State): boolean;
4
+ export declare function isTrivialCube4State(state: Cube4State): boolean;
5
+ export declare function isAllowedRandomCube4State(state: Cube4State): boolean;
6
+ //# sourceMappingURL=validation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../src/puzzles/cube4/validation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAKpE,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,qBAAqB,CAoB3E;AASD,wBAAgB,6BAA6B,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAExE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAE9D;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAEpE"}
@@ -0,0 +1,91 @@
1
+ import { CENTER_COUNT, CORNER_COUNT, CUBE4_ALL_MOVES, FACE_COUNT, CENTERS_PER_FACE, WING_COUNT } from "./types.js";
2
+ import { applyCube4Move } from "./moves.js";
3
+ import { createSolvedCube4State, cube4StatesEqual, isSolvedCube4State } from "./state.js";
4
+ export function validateCube4State(state) {
5
+ const errors = [
6
+ ...validatePermutation("corner", state.cp, CORNER_COUNT),
7
+ ...validateOrientations("corner", state.co, CORNER_COUNT, 3),
8
+ ...validatePermutation("wing", state.wp, WING_COUNT),
9
+ ...validateCenters(state.centers)
10
+ ];
11
+ if (errors.length === 0) {
12
+ const cornerOrientation = sum(state.co) % 3;
13
+ if (cornerOrientation !== 0) {
14
+ errors.push("Corner orientation sum must be divisible by 3.");
15
+ }
16
+ }
17
+ return {
18
+ valid: errors.length === 0,
19
+ errors
20
+ };
21
+ }
22
+ // The 36 single-move states (12 base faces × 3 suffixes), precomputed once so
23
+ // the hot random-state path checks "solved or one move from solved" with pure
24
+ // array comparisons.
25
+ const ONE_MOVE_FROM_SOLVED_STATES = CUBE4_ALL_MOVES.map((move) => applyCube4Move(createSolvedCube4State(), move));
26
+ export function isOneMoveFromSolvedCube4State(state) {
27
+ return ONE_MOVE_FROM_SOLVED_STATES.some((candidate) => cube4StatesEqual(candidate, state));
28
+ }
29
+ export function isTrivialCube4State(state) {
30
+ return isSolvedCube4State(state) || isOneMoveFromSolvedCube4State(state);
31
+ }
32
+ export function isAllowedRandomCube4State(state) {
33
+ return validateCube4State(state).valid && !isTrivialCube4State(state);
34
+ }
35
+ function validatePermutation(label, permutation, length) {
36
+ const errors = [];
37
+ const seen = new Set();
38
+ if (permutation.length !== length) {
39
+ errors.push(`${label} permutation must contain ${length} values.`);
40
+ }
41
+ for (const value of permutation) {
42
+ if (!Number.isInteger(value) || value < 0 || value >= length) {
43
+ errors.push(`${label} permutation contains out-of-range value: ${value}.`);
44
+ continue;
45
+ }
46
+ if (seen.has(value)) {
47
+ errors.push(`${label} permutation contains duplicate value: ${value}.`);
48
+ }
49
+ seen.add(value);
50
+ }
51
+ return errors;
52
+ }
53
+ function validateOrientations(label, orientations, length, modulo) {
54
+ const errors = [];
55
+ if (orientations.length !== length) {
56
+ errors.push(`${label} orientation must contain ${length} values.`);
57
+ }
58
+ for (const value of orientations) {
59
+ if (!Number.isInteger(value) || value < 0 || value >= modulo) {
60
+ errors.push(`${label} orientation contains out-of-range value: ${value}.`);
61
+ }
62
+ }
63
+ return errors;
64
+ }
65
+ function validateCenters(centers) {
66
+ const errors = [];
67
+ if (centers.length !== CENTER_COUNT) {
68
+ errors.push(`centers must contain ${CENTER_COUNT} values.`);
69
+ }
70
+ const counts = new Uint8Array(FACE_COUNT);
71
+ for (const value of centers) {
72
+ if (!Number.isInteger(value) || value < 0 || value >= FACE_COUNT) {
73
+ errors.push(`center contains out-of-range color: ${value}.`);
74
+ continue;
75
+ }
76
+ counts[value] = counts[value] + 1;
77
+ }
78
+ for (let face = 0; face < FACE_COUNT; face += 1) {
79
+ if (counts[face] !== CENTERS_PER_FACE) {
80
+ errors.push(`center color ${face} must appear exactly ${CENTERS_PER_FACE} times.`);
81
+ }
82
+ }
83
+ return errors;
84
+ }
85
+ function sum(values) {
86
+ let total = 0;
87
+ for (const value of values) {
88
+ total += value;
89
+ }
90
+ return total;
91
+ }
@@ -0,0 +1,53 @@
1
+ /**
2
+ * Combinatorics and coordinate packing/unpacking for FTO (Face-Turning Octahedron).
3
+ *
4
+ * Implements exact bijections for:
5
+ * - Even corner permutations (A_6, 360 states)
6
+ * - Corner orientations (Z_2^5 with even sum, 32 states)
7
+ * - Even edge permutations (A_12, 239,500,800 states)
8
+ * - Center orbit arrangements (C(12,3)*C(9,3)*C(6,3) = 369,600 states per orbit)
9
+ */
10
+ /**
11
+ * Binomial coefficient nCr = n! / (k! * (n-k)!).
12
+ */
13
+ export declare function nCr(n: number, k: number): number;
14
+ /**
15
+ * Compute the permutation parity (number of inversions mod 2).
16
+ * Returns true if odd, false if even.
17
+ */
18
+ export declare function getPermutationParity(perm: readonly number[]): boolean;
19
+ /**
20
+ * Pack a sorted k-subset of {0, ..., n-1} into an integer in [0, nCr(n, k) - 1].
21
+ * Uses standard combinatorial number system ranking: sum_{i=0}^{k-1} nCr(s_i, i + 1).
22
+ */
23
+ export declare function packSubset(subset: readonly number[]): number;
24
+ /**
25
+ * Unpack an integer index in [0, nCr(n, k) - 1] into a sorted k-subset.
26
+ */
27
+ export declare function unpackSubset(target: number[], k: number, index: number): void;
28
+ /**
29
+ * Pack an even permutation of length n into its rank in A_n: [0, n!/2 - 1].
30
+ */
31
+ export declare function packEvenPerm(perm: readonly number[]): number;
32
+ /**
33
+ * Unpack an integer rank in [0, n!/2 - 1] into an even permutation of length n.
34
+ */
35
+ export declare function unpackEvenPerm(n: number, rank: number, target?: number[]): number[];
36
+ /**
37
+ * Pack 6 corner orientations (each in {0, 1} with even sum) into [0, 31].
38
+ */
39
+ export declare function packCornerOrientation(co: readonly number[]): number;
40
+ /**
41
+ * Unpack an orientation rank in [0, 31] into 6 corner orientations with sum = 0 mod 2.
42
+ */
43
+ export declare function unpackCornerOrientation(rank: number, target?: number[]): number[];
44
+ /**
45
+ * Pack a center orbit (12 pieces, 3 of each of 4 colors) into [0, 369599].
46
+ * Pieces 0..2 are color 0, 3..5 are color 1, 6..8 are color 2, 9..11 are color 3.
47
+ */
48
+ export declare function packCenterOrbit(centers: readonly number[]): number;
49
+ /**
50
+ * Unpack a center orbit rank in [0, 369599] into 12 piece indices (0..11).
51
+ */
52
+ export declare function unpackCenterOrbit(rank: number, target?: number[]): number[];
53
+ //# sourceMappingURL=coordinates.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"coordinates.d.ts","sourceRoot":"","sources":["../../../src/puzzles/fto/coordinates.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAeH;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAShD;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAWrE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAM5D;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAc7E;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAoB5D;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CA+BnF;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,EAAE,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAMnE;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAYjF;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAiClE;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAmD3E"}
@@ -0,0 +1,228 @@
1
+ /**
2
+ * Combinatorics and coordinate packing/unpacking for FTO (Face-Turning Octahedron).
3
+ *
4
+ * Implements exact bijections for:
5
+ * - Even corner permutations (A_6, 360 states)
6
+ * - Corner orientations (Z_2^5 with even sum, 32 states)
7
+ * - Even edge permutations (A_12, 239,500,800 states)
8
+ * - Center orbit arrangements (C(12,3)*C(9,3)*C(6,3) = 369,600 states per orbit)
9
+ */
10
+ import { FTO_CORNER_COUNT } from "./types.js";
11
+ const FACTORIAL = [
12
+ 1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600
13
+ ];
14
+ /**
15
+ * Binomial coefficient nCr = n! / (k! * (n-k)!).
16
+ */
17
+ export function nCr(n, k) {
18
+ if (k < 0 || k > n)
19
+ return 0;
20
+ if (k === 0 || k === n)
21
+ return 1;
22
+ if (k > n - k)
23
+ k = n - k;
24
+ let res = 1;
25
+ for (let i = 1; i <= k; i++) {
26
+ res = (res * (n - i + 1)) / i;
27
+ }
28
+ return res;
29
+ }
30
+ /**
31
+ * Compute the permutation parity (number of inversions mod 2).
32
+ * Returns true if odd, false if even.
33
+ */
34
+ export function getPermutationParity(perm) {
35
+ let inversions = 0;
36
+ const n = perm.length;
37
+ for (let i = 0; i < n; i++) {
38
+ for (let j = i + 1; j < n; j++) {
39
+ if (perm[i] > perm[j]) {
40
+ inversions++;
41
+ }
42
+ }
43
+ }
44
+ return (inversions & 1) === 1;
45
+ }
46
+ /**
47
+ * Pack a sorted k-subset of {0, ..., n-1} into an integer in [0, nCr(n, k) - 1].
48
+ * Uses standard combinatorial number system ranking: sum_{i=0}^{k-1} nCr(s_i, i + 1).
49
+ */
50
+ export function packSubset(subset) {
51
+ let index = 0;
52
+ for (let i = subset.length - 1; i >= 0; i--) {
53
+ index += nCr(subset[i], i + 1);
54
+ }
55
+ return index;
56
+ }
57
+ /**
58
+ * Unpack an integer index in [0, nCr(n, k) - 1] into a sorted k-subset.
59
+ */
60
+ export function unpackSubset(target, k, index) {
61
+ target.length = k;
62
+ let remaining = index;
63
+ let currentK = k;
64
+ for (let pos = 0; pos < k; pos++) {
65
+ let c = currentK - 1;
66
+ while (nCr(c + 1, currentK) <= remaining) {
67
+ c++;
68
+ }
69
+ target[k - 1 - pos] = c;
70
+ remaining -= nCr(c, currentK);
71
+ currentK--;
72
+ }
73
+ }
74
+ /**
75
+ * Pack an even permutation of length n into its rank in A_n: [0, n!/2 - 1].
76
+ */
77
+ export function packEvenPerm(perm) {
78
+ const n = perm.length;
79
+ let rank = 0;
80
+ let used = 0;
81
+ for (let i = 0; i < n - 2; i++) {
82
+ const val = perm[i];
83
+ // Count how many smaller values haven't been used yet
84
+ let digit = 0;
85
+ for (let v = 0; v < val; v++) {
86
+ if ((used & (1 << v)) === 0) {
87
+ digit++;
88
+ }
89
+ }
90
+ used |= 1 << val;
91
+ const factor = FACTORIAL[n - 1 - i] / 2;
92
+ rank += digit * factor;
93
+ }
94
+ return rank;
95
+ }
96
+ /**
97
+ * Unpack an integer rank in [0, n!/2 - 1] into an even permutation of length n.
98
+ */
99
+ export function unpackEvenPerm(n, rank, target) {
100
+ const perm = target ? target : new Array(n);
101
+ perm.length = n;
102
+ const lehmer = new Array(n);
103
+ let remaining = rank;
104
+ let sumLehmer = 0;
105
+ for (let i = 0; i < n - 2; i++) {
106
+ const factor = FACTORIAL[n - 1 - i] / 2;
107
+ const digit = Math.floor(remaining / factor);
108
+ remaining %= factor;
109
+ lehmer[i] = digit;
110
+ sumLehmer += digit;
111
+ }
112
+ // The (n-2)-th digit is fixed by even-parity constraint:
113
+ lehmer[n - 2] = sumLehmer & 1;
114
+ lehmer[n - 1] = 0;
115
+ // Reconstruct permutation from Lehmer code
116
+ const available = new Array(n);
117
+ for (let i = 0; i < n; i++)
118
+ available[i] = i;
119
+ for (let i = 0; i < n; i++) {
120
+ const choice = lehmer[i];
121
+ perm[i] = available[choice];
122
+ available.splice(choice, 1);
123
+ }
124
+ return perm;
125
+ }
126
+ /**
127
+ * Pack 6 corner orientations (each in {0, 1} with even sum) into [0, 31].
128
+ */
129
+ export function packCornerOrientation(co) {
130
+ let rank = 0;
131
+ for (let i = 0; i < FTO_CORNER_COUNT - 1; i++) {
132
+ rank |= (co[i] & 1) << i;
133
+ }
134
+ return rank;
135
+ }
136
+ /**
137
+ * Unpack an orientation rank in [0, 31] into 6 corner orientations with sum = 0 mod 2.
138
+ */
139
+ export function unpackCornerOrientation(rank, target) {
140
+ const co = target ? target : new Array(FTO_CORNER_COUNT);
141
+ co.length = FTO_CORNER_COUNT;
142
+ let sum = 0;
143
+ for (let i = 0; i < FTO_CORNER_COUNT - 1; i++) {
144
+ const val = (rank >> i) & 1;
145
+ co[i] = val;
146
+ sum += val;
147
+ }
148
+ co[FTO_CORNER_COUNT - 1] = sum & 1;
149
+ return co;
150
+ }
151
+ /**
152
+ * Pack a center orbit (12 pieces, 3 of each of 4 colors) into [0, 369599].
153
+ * Pieces 0..2 are color 0, 3..5 are color 1, 6..8 are color 2, 9..11 are color 3.
154
+ */
155
+ export function packCenterOrbit(centers) {
156
+ const positions = [[], [], [], []];
157
+ for (let i = 0; i < 12; i++) {
158
+ const color = Math.floor(centers[i] / 3);
159
+ positions[color].push(i);
160
+ }
161
+ // 1. Color 0 positions in 0..11 (size 3)
162
+ const d0 = packSubset(positions[0]);
163
+ // Remaining 9 positions
164
+ const p1 = [];
165
+ const used0 = new Set(positions[0]);
166
+ for (let i = 0; i < 12; i++) {
167
+ if (!used0.has(i))
168
+ p1.push(i);
169
+ }
170
+ // 2. Color 1 positions mapped into p1 index space (0..8)
171
+ const s1 = positions[1].map((pos) => p1.indexOf(pos)).sort((a, b) => a - b);
172
+ const d1 = packSubset(s1);
173
+ // Remaining 6 positions
174
+ const p2 = [];
175
+ const used1 = new Set(positions[1]);
176
+ for (let i = 0; i < p1.length; i++) {
177
+ if (!used1.has(p1[i]))
178
+ p2.push(p1[i]);
179
+ }
180
+ // 3. Color 2 positions mapped into p2 index space (0..5)
181
+ const s2 = positions[2].map((pos) => p2.indexOf(pos)).sort((a, b) => a - b);
182
+ const d2 = packSubset(s2);
183
+ return d0 * (nCr(9, 3) * nCr(6, 3)) + d1 * nCr(6, 3) + d2;
184
+ }
185
+ /**
186
+ * Unpack a center orbit rank in [0, 369599] into 12 piece indices (0..11).
187
+ */
188
+ export function unpackCenterOrbit(rank, target) {
189
+ const centers = target ? target : new Array(12);
190
+ centers.length = 12;
191
+ const C93_C63 = nCr(9, 3) * nCr(6, 3); // 84 * 20 = 1680
192
+ const C63 = nCr(6, 3); // 20
193
+ const d0 = Math.floor(rank / C93_C63);
194
+ let rem = rank % C93_C63;
195
+ const d1 = Math.floor(rem / C63);
196
+ const d2 = rem % C63;
197
+ const s0 = [];
198
+ unpackSubset(s0, 3, d0);
199
+ const s1 = [];
200
+ unpackSubset(s1, 3, d1);
201
+ const s2 = [];
202
+ unpackSubset(s2, 3, d2);
203
+ // Available positions pool
204
+ const pool = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11];
205
+ // Assign color 0 (piece indices 0, 1, 2)
206
+ for (let i = 0; i < 3; i++) {
207
+ const pos = s0[i];
208
+ centers[pos] = i; // 0, 1, 2
209
+ }
210
+ const remaining1 = pool.filter((p) => !s0.includes(p));
211
+ // Assign color 1 (piece indices 3, 4, 5)
212
+ const pos1 = s1.map((idx) => remaining1[idx]);
213
+ for (let i = 0; i < 3; i++) {
214
+ centers[pos1[i]] = 3 + i; // 3, 4, 5
215
+ }
216
+ const remaining2 = remaining1.filter((p) => !pos1.includes(p));
217
+ // Assign color 2 (piece indices 6, 7, 8)
218
+ const pos2 = s2.map((idx) => remaining2[idx]);
219
+ for (let i = 0; i < 3; i++) {
220
+ centers[pos2[i]] = 6 + i; // 6, 7, 8
221
+ }
222
+ const remaining3 = remaining2.filter((p) => !pos2.includes(p));
223
+ // Assign color 3 (piece indices 9, 10, 11)
224
+ for (let i = 0; i < 3; i++) {
225
+ centers[remaining3[i]] = 9 + i; // 9, 10, 11
226
+ }
227
+ return centers;
228
+ }
@@ -0,0 +1,6 @@
1
+ import type { FtoFacelets } from "./types.js";
2
+ import { FtoCubie } from "./state.js";
3
+ export declare function toFaceCubeArray(state: FtoCubie): number[];
4
+ export declare function toFtoFacelets(state: FtoCubie): FtoFacelets;
5
+ export declare function formatFtoFacelets(facelets: FtoFacelets): string;
6
+ //# sourceMappingURL=facelets.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"facelets.d.ts","sourceRoot":"","sources":["../../../src/puzzles/fto/facelets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAqEtC,wBAAgB,eAAe,CAAC,KAAK,EAAE,QAAQ,GAAG,MAAM,EAAE,CAWzD;AAED,wBAAgB,aAAa,CAAC,KAAK,EAAE,QAAQ,GAAG,WAAW,CAsB1D;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAW/D"}
@@ -0,0 +1,99 @@
1
+ const FACE_NAMES = ["U", "F", "BR", "BL", "D", "B", "R", "L"];
2
+ const U = 0, F = 9, r = 18, l = 27, D = 36, B = 45, R = 54, L = 63;
3
+ const cornFacelets = [
4
+ [U + 0, R + 0, F + 0, L + 0],
5
+ [U + 4, B + 8, r + 4, R + 8],
6
+ [U + 8, L + 4, l + 8, B + 4],
7
+ [l + 0, D + 0, r + 0, B + 0],
8
+ [F + 4, D + 8, l + 4, L + 8],
9
+ [r + 8, D + 4, F + 8, R + 4]
10
+ ];
11
+ const edgeFacelets = [
12
+ [U + 1, R + 3],
13
+ [U + 3, L + 1],
14
+ [U + 6, B + 6],
15
+ [l + 1, D + 3],
16
+ [r + 3, D + 1],
17
+ [F + 6, D + 6],
18
+ [F + 3, R + 1],
19
+ [F + 1, L + 3],
20
+ [l + 6, L + 6],
21
+ [l + 3, B + 1],
22
+ [r + 1, B + 3],
23
+ [r + 6, R + 6]
24
+ ];
25
+ const ctufFacelets = [
26
+ U + 2, U + 5, U + 7,
27
+ F + 2, F + 5, F + 7,
28
+ r + 2, r + 5, r + 7,
29
+ l + 2, l + 5, l + 7
30
+ ];
31
+ const ctrlFacelets = [
32
+ D + 2, D + 5, D + 7,
33
+ B + 2, B + 5, B + 7,
34
+ L + 2, L + 5, L + 7,
35
+ R + 2, R + 5, R + 7
36
+ ];
37
+ function fillFacelet(faceletMap, f, perm, ori, divcol) {
38
+ for (let i = 0; i < faceletMap.length; i++) {
39
+ const cubie = faceletMap[i];
40
+ const p = perm[i] === undefined ? i : perm[i];
41
+ if (typeof cubie === "number") {
42
+ const src = faceletMap[p];
43
+ f[cubie] = Math.floor((typeof src === "number" ? src : src[0]) / divcol);
44
+ continue;
45
+ }
46
+ const o = ori ? (ori[i] || 0) : 0;
47
+ const src = faceletMap[p];
48
+ for (let j = 0; j < cubie.length; j++) {
49
+ const destIndex = cubie[(j + o) % cubie.length];
50
+ const srcIndex = typeof src === "number" ? src : src[j];
51
+ f[destIndex] = Math.floor(srcIndex / divcol);
52
+ }
53
+ }
54
+ }
55
+ export function toFaceCubeArray(state) {
56
+ const f = new Array(72);
57
+ const co = new Array(6);
58
+ for (let i = 0; i < 6; i++) {
59
+ co[i] = state.co[i] * 2;
60
+ }
61
+ fillFacelet(cornFacelets, f, state.cp, co, 9);
62
+ fillFacelet(edgeFacelets, f, state.ep, null, 9);
63
+ fillFacelet(ctufFacelets, f, state.uf, null, 9);
64
+ fillFacelet(ctrlFacelets, f, state.rl, null, 9);
65
+ return f;
66
+ }
67
+ export function toFtoFacelets(state) {
68
+ const faceArray = toFaceCubeArray(state);
69
+ const getFaceStickers = (offset) => {
70
+ const stickers = new Array(9);
71
+ for (let i = 0; i < 9; i++) {
72
+ const colorVal = faceArray[offset + i];
73
+ stickers[i] = FACE_NAMES[colorVal] ?? "U";
74
+ }
75
+ return stickers;
76
+ };
77
+ return {
78
+ U: getFaceStickers(U),
79
+ F: getFaceStickers(F),
80
+ BR: getFaceStickers(r),
81
+ BL: getFaceStickers(l),
82
+ D: getFaceStickers(D),
83
+ B: getFaceStickers(B),
84
+ R: getFaceStickers(R),
85
+ L: getFaceStickers(L)
86
+ };
87
+ }
88
+ export function formatFtoFacelets(facelets) {
89
+ return [
90
+ facelets.U.join(""),
91
+ facelets.D.join(""),
92
+ facelets.F.join(""),
93
+ facelets.B.join(""),
94
+ facelets.L.join(""),
95
+ facelets.BR.join(""),
96
+ facelets.R.join(""),
97
+ facelets.BL.join("")
98
+ ].join(" ");
99
+ }
@@ -0,0 +1,12 @@
1
+ export type { FtoFace, FtoMove, FtoFacelets, FtoRandomStateOptions, FtoValidationResult } from "./types.js";
2
+ export { FTO_FACES, FTO_ALL_MOVES, FTO_AXIS_MAP, SCRAMBLE_LENGTH, FTO_CORNER_COUNT, FTO_EDGE_COUNT, FTO_CENTER_ORBIT_COUNT, FTO_CORNER_PERM_STATES, FTO_CORNER_ORI_STATES, FTO_EDGE_PERM_STATES, FTO_CENTER_ORBIT_STATES } from "./types.js";
3
+ export { FtoCubie, createSolvedFtoState, cloneFtoState, statesEqual, isSolvedFtoState } from "./state.js";
4
+ export { FTO_MOVE_MAP, getFtoMoveFace, invertFtoMove, invertFtoAlgorithm, parseFtoAlgorithm, formatFtoAlgorithm, applyFtoMove, applyFtoAlgorithm, isRedundantFtoMove } from "./moves.js";
5
+ export { toFaceCubeArray, toFtoFacelets, formatFtoFacelets } from "./facelets.js";
6
+ export { nCr, getPermutationParity, packSubset, unpackSubset, packEvenPerm, unpackEvenPerm, packCornerOrientation, unpackCornerOrientation, packCenterOrbit, unpackCenterOrbit } from "./coordinates.js";
7
+ export { validateFtoState, isTrivialFtoState } from "./validation.js";
8
+ export { generateRandomFtoState } from "./random-state.js";
9
+ export { solveFto, initFtoSolver, isFtoSolverInitialized } from "./solver/index.js";
10
+ export { ftoScrambleGenerator, generateFtoScramble } from "./scrambler.js";
11
+ export { generateScramble, generateScrambles, getEventInfo, getSupportedEvents, initializeScrambler } from "../../core/index.js";
12
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/puzzles/fto/index.ts"],"names":[],"mappings":"AAKA,YAAY,EACV,OAAO,EACP,OAAO,EACP,WAAW,EACX,qBAAqB,EACrB,mBAAmB,EACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,SAAS,EACT,aAAa,EACb,YAAY,EACZ,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,sBAAsB,EACtB,sBAAsB,EACtB,qBAAqB,EACrB,oBAAoB,EACpB,uBAAuB,EACxB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,QAAQ,EACR,oBAAoB,EACpB,aAAa,EACb,WAAW,EACX,gBAAgB,EACjB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,kBAAkB,EAClB,iBAAiB,EACjB,kBAAkB,EAClB,YAAY,EACZ,iBAAiB,EACjB,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,eAAe,EACf,aAAa,EACb,iBAAiB,EAClB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,GAAG,EACH,oBAAoB,EACpB,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,qBAAqB,EACrB,uBAAuB,EACvB,eAAe,EACf,iBAAiB,EAClB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EACL,sBAAsB,EACvB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,QAAQ,EACR,aAAa,EACb,sBAAsB,EACvB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EACL,gBAAgB,EAChB,iBAAiB,EACjB,YAAY,EACZ,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { registerScrambleGenerator } from "../../core/index.js";
2
+ import { ftoScrambleGenerator } from "./scrambler.js";
3
+ registerScrambleGenerator(ftoScrambleGenerator);
4
+ export { FTO_FACES, FTO_ALL_MOVES, FTO_AXIS_MAP, SCRAMBLE_LENGTH, FTO_CORNER_COUNT, FTO_EDGE_COUNT, FTO_CENTER_ORBIT_COUNT, FTO_CORNER_PERM_STATES, FTO_CORNER_ORI_STATES, FTO_EDGE_PERM_STATES, FTO_CENTER_ORBIT_STATES } from "./types.js";
5
+ export { FtoCubie, createSolvedFtoState, cloneFtoState, statesEqual, isSolvedFtoState } from "./state.js";
6
+ export { FTO_MOVE_MAP, getFtoMoveFace, invertFtoMove, invertFtoAlgorithm, parseFtoAlgorithm, formatFtoAlgorithm, applyFtoMove, applyFtoAlgorithm, isRedundantFtoMove } from "./moves.js";
7
+ export { toFaceCubeArray, toFtoFacelets, formatFtoFacelets } from "./facelets.js";
8
+ export { nCr, getPermutationParity, packSubset, unpackSubset, packEvenPerm, unpackEvenPerm, packCornerOrientation, unpackCornerOrientation, packCenterOrbit, unpackCenterOrbit } from "./coordinates.js";
9
+ export { validateFtoState, isTrivialFtoState } from "./validation.js";
10
+ export { generateRandomFtoState } from "./random-state.js";
11
+ export { solveFto, initFtoSolver, isFtoSolverInitialized } from "./solver/index.js";
12
+ export { ftoScrambleGenerator, generateFtoScramble } from "./scrambler.js";
13
+ export { generateScramble, generateScrambles, getEventInfo, getSupportedEvents, initializeScrambler } from "../../core/index.js";
@@ -0,0 +1,12 @@
1
+ import type { FtoFace, FtoMove } from "./types.js";
2
+ import { FtoCubie } from "./state.js";
3
+ export declare const FTO_MOVE_MAP: Record<FtoMove, FtoCubie>;
4
+ export declare function getFtoMoveFace(move: FtoMove | string): FtoFace;
5
+ export declare function invertFtoMove(move: FtoMove): FtoMove;
6
+ export declare function invertFtoAlgorithm(moves: readonly FtoMove[]): FtoMove[];
7
+ export declare function parseFtoAlgorithm(algorithm: string): FtoMove[];
8
+ export declare function formatFtoAlgorithm(moves: readonly FtoMove[]): string;
9
+ export declare function applyFtoMove(state: FtoCubie, move: FtoMove | string): FtoCubie;
10
+ export declare function applyFtoAlgorithm(state: FtoCubie, algorithm: readonly (FtoMove | string)[] | string): FtoCubie;
11
+ export declare function isRedundantFtoMove(moves: readonly FtoMove[], newMove: FtoMove): boolean;
12
+ //# sourceMappingURL=moves.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"moves.d.ts","sourceRoot":"","sources":["../../../src/puzzles/fto/moves.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAEnD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAkEtC,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,OAAO,EAAE,QAAQ,CAiBlD,CAAC;AAEF,wBAAgB,cAAc,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,OAAO,CAG9D;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAKpD;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,EAAE,CAMvE;AAED,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,EAAE,CAW9D;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,SAAS,OAAO,EAAE,GAAG,MAAM,CAEpE;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,QAAQ,CAM9E;AAED,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,QAAQ,EACf,SAAS,EAAE,SAAS,CAAC,OAAO,GAAG,MAAM,CAAC,EAAE,GAAG,MAAM,GAChD,QAAQ,CAQV;AAaD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,SAAS,OAAO,EAAE,EACzB,OAAO,EAAE,OAAO,GACf,OAAO,CA+BT"}