From c5fa224f56fea458b1e8145fb024eb8c4aaa481a Mon Sep 17 00:00:00 2001 From: Lucas Garron Date: Sat, 10 Sep 2022 18:16:44 -0700 Subject: [PATCH] [rome] Re-enable `js/useBlockStatements` globally by default. Also ran: `npx rome check --apply-suggested ./script ./src; make format` --- rome.json | 3 +- .../vendor/min2phase/3x3x3-min2phase.js | 7 +- src/cubing/vendor/sq12phase/sq1-solver.js | 22 +- .../vendor/xyzzy/fto-solver-original.js | 111 ++++++--- src/cubing/vendor/xyzzy/fto-solver.js | 111 ++++++--- src/cubing/vendor/xyzzy/kilosolver.js | 173 +++++++------- .../vendor/xyzzy/master_tetraminx-solver.js | 116 +++++++--- src/cubing/vendor/xyzzy/redi_cube.js | 217 +++++++++++++----- 8 files changed, 523 insertions(+), 237 deletions(-) diff --git a/rome.json b/rome.json index 815d80a95..6504570c5 100644 --- a/rome.json +++ b/rome.json @@ -17,8 +17,7 @@ "noUnusedTemplateLiteral": "off", "useTemplate": "off", "useSimplifiedLogicExpression": "off", - "useSingleVarDeclarator": "off", - "useBlockStatements": "off" + "useSingleVarDeclarator": "off" }, "ts": { "recommended": true, diff --git a/src/cubing/vendor/min2phase/3x3x3-min2phase.js b/src/cubing/vendor/min2phase/3x3x3-min2phase.js index 7d97435ab..482e9c86c 100644 --- a/src/cubing/vendor/min2phase/3x3x3-min2phase.js +++ b/src/cubing/vendor/min2phase/3x3x3-min2phase.js @@ -1729,7 +1729,9 @@ function $initPhase2Pre(this$static) { ); if (ret === 0 || ret > 2) { break; - } else ret === 2 && (p2switchMask &= 4 << p2switch); + } else { + ret === 2 && (p2switchMask &= 4 << p2switch); + } } if (p2switchMask === 0) { break; @@ -2432,8 +2434,9 @@ function toCubieCube(f, ccRet) { } for (i2 = 0; i2 < 8; i2++) { for (ori = 0; ori < 3; ori++) { - if (f[cornerFacelet[i2][ori]] === 0 || f[cornerFacelet[i2][ori]] === 3) + if (f[cornerFacelet[i2][ori]] === 0 || f[cornerFacelet[i2][ori]] === 3) { break; + } } col1 = f[cornerFacelet[i2][(ori + 1) % 3]]; col2 = f[cornerFacelet[i2][(ori + 2) % 3]]; diff --git a/src/cubing/vendor/sq12phase/sq1-solver.js b/src/cubing/vendor/sq12phase/sq1-solver.js index 5db827ed1..44bdda84f 100644 --- a/src/cubing/vendor/sq12phase/sq1-solver.js +++ b/src/cubing/vendor/sq12phase/sq1-solver.js @@ -101,12 +101,14 @@ function FullCube_getSquare(obj, sq) { sq.cornperm = get8Perm(obj.prm); sq.topEdgeFirst = FullCube_pieceAt(obj, 0) === FullCube_pieceAt(obj, 1); a = sq.topEdgeFirst ? 2 : 0; - for (b = 0; b < 4; a += 3, ++b) + for (b = 0; b < 4; a += 3, ++b) { obj.prm[b] = ~~((~~FullCube_pieceAt(obj, a) >> 1) << 24) >> 24; + } sq.botEdgeFirst = FullCube_pieceAt(obj, 12) === FullCube_pieceAt(obj, 13); a = sq.botEdgeFirst ? 14 : 12; - for (; b < 8; a += 3, ++b) + for (; b < 8; a += 3, ++b) { obj.prm[b] = ~~((~~FullCube_pieceAt(obj, a) >> 1) << 24) >> 24; + } sq.edgeperm = get8Perm(obj.prm); sq.ml = obj.ml; } @@ -656,7 +658,9 @@ function Square_$clinit() { Square_BottomMove = []; fact = [1, 1, 2, 6, 24, 120, 720, 5040]; Cnk = []; - for (var i = 0; i < 12; ++i) Cnk[i] = []; + for (var i = 0; i < 12; ++i) { + Cnk[i] = []; + } Square_init(); } @@ -728,7 +732,9 @@ function Square_init() { if (SquarePrun[idxx] === check) { ++done; SquarePrun[inv ? i : idxx] = ~~(depth << 24) >> 24; - if (inv) continue OUT; + if (inv) { + continue OUT; + } } idxx = idx; for (m = 0; m < 4; ++m) { @@ -736,7 +742,9 @@ function Square_init() { if (SquarePrun[(idxx << 1) | ml] === check) { ++done; SquarePrun[inv ? i : (idxx << 1) | ml] = ~~(depth << 24) >> 24; - if (inv) continue OUT; + if (inv) { + continue OUT; + } } } for (m = 0; m < 4; ++m) { @@ -744,7 +752,9 @@ function Square_init() { if (SquarePrun[(idxx << 1) | ml] === check) { ++done; SquarePrun[inv ? i : (idxx << 1) | ml] = ~~(depth << 24) >> 24; - if (inv) continue OUT; + if (inv) { + continue OUT; + } } } } diff --git a/src/cubing/vendor/xyzzy/fto-solver-original.js b/src/cubing/vendor/xyzzy/fto-solver-original.js index 2f1ba976f..2cfe6afff 100644 --- a/src/cubing/vendor/xyzzy/fto-solver-original.js +++ b/src/cubing/vendor/xyzzy/fto-solver-original.js @@ -18,7 +18,9 @@ JavaScript engines. Recent Chrome / Node releases should also work, but are not function counter(A) { let counts = []; - for (let a of A) counts[a] = (counts[a] || 0) + 1; + for (let a of A) { + counts[a] = (counts[a] || 0) + 1; + } return counts; } @@ -79,15 +81,23 @@ Note: SAFETY_MARGIN must be at most 2**20. /* Combinatoric functions */ function factorial(n) { - if (n < 2) return n; + if (n < 2) { + return n; + } let f = 1; - for (let i = 2; i <= n; i++) f *= i; + for (let i = 2; i <= n; i++) { + f *= i; + } return f; } function C(n, k) { - if (k < 0 || k > n) return 0; - if (k === 0 || k === n) return 1; + if (k < 0 || k > n) { + return 0; + } + if (k === 0 || k === n) { + return 1; + } let c = 1; for (let i = 0; i < k; i++) { c = ((c * (n - i)) / (i + 1)) | 0; @@ -140,7 +150,9 @@ function permutation_parity(A) { let parity = 0; for (let i = 0; i < n - 1; i++) { for (let j = i; j < n; j++) { - if (A[i] > A[j]) parity ^= 1; + if (A[i] > A[j]) { + parity ^= 1; + } } } return parity; @@ -158,11 +170,16 @@ function index_to_evenpermutation(ind, n) { perm[n - 1] = 0; for (let i = n - 2; i >= 0; i--) { for (let j = i + 1; j < n; j++) { - if (perm[j] >= perm[i]) perm[j]++; - else parity ^= 1; + if (perm[j] >= perm[i]) { + perm[j]++; + } else { + parity ^= 1; + } } } - if (parity === 1) [perm[n - 2], perm[n - 1]] = [perm[n - 1], perm[n - 2]]; + if (parity === 1) { + [perm[n - 2], perm[n - 1]] = [perm[n - 1], perm[n - 2]]; + } return perm; } @@ -241,9 +258,13 @@ function random_even_permutation(n) { function comb_to_index(l) { let bits = l.length; let ones = 0; - for (let i = 0; i < bits; i++) ones += +(l[i] === 1); + for (let i = 0; i < bits; i++) { + ones += +(l[i] === 1); + } let zeros = bits - ones; - if (zeros === 0 || ones === 0 || bits === 1) return 0; + if (zeros === 0 || ones === 0 || bits === 1) { + return 0; + } let b = C(bits - 1, ones); let ind = 0; for (let i = 0; zeros > 0 && ones > 0 && bits > 1; i++) { @@ -373,13 +394,17 @@ function generate_comb4_lookup_tables(n, k0, k1, k2, k3) { function compose(A, B) { let C = []; - for (let i = 0; i < B.length; i++) C[i] = A[B[i]]; + for (let i = 0; i < B.length; i++) { + C[i] = A[B[i]]; + } return C; } function compose3(A, B, C) { let D = []; - for (let i = 0; i < C.length; i++) D[i] = A[B[C[i]]]; + for (let i = 0; i < C.length; i++) { + D[i] = A[B[C[i]]]; + } return D; } @@ -1138,8 +1163,9 @@ function bfs(mtable, goal_states) { function* ida_solve_gen(indices, mtables, ptables, moves_left, commute) { let ncoords = indices.length; let bound = 0; - for (let i = 0; i < ncoords; i++) + for (let i = 0; i < ncoords; i++) { bound = Math.max(bound, ptables[i][indices[i]]); + } while (bound <= moves_left) { //console.log(`searching depth ${bound}`); yield* ida_search_gen(indices, mtables, ptables, bound, -1, commute); @@ -1151,20 +1177,30 @@ function* ida_search_gen(indices, mtables, ptables, bound, last, commute) { let ncoords = indices.length; let nmoves = mtables[0].length; let heuristic = 0; - for (let i = 0; i < ncoords; i++) + for (let i = 0; i < ncoords; i++) { heuristic = Math.max(heuristic, ptables[i][indices[i]]); - if (heuristic > bound) return; + } + if (heuristic > bound) { + return; + } if (bound === 0) { yield []; return; } - if (heuristic === 0 && bound === 1) return; + if (heuristic === 0 && bound === 1) { + return; + } for (let m = 0; m < nmoves; m++) { - if (m === last) continue; - if (m < last && commute[m][last]) continue; + if (m === last) { + continue; + } + if (m < last && commute[m][last]) { + continue; + } let new_indices = indices.slice(); - for (let c = 0; c < ncoords; c++) + for (let c = 0; c < ncoords; c++) { new_indices[c] = mtables[c][m][indices[c]]; + } let r = 1; while (indices.some((_, i) => indices[i] !== new_indices[i])) { let subpath_gen = ida_search_gen( @@ -1177,7 +1213,9 @@ function* ida_search_gen(indices, mtables, ptables, bound, last, commute) { ); while (true) { let { value: subpath, done } = subpath_gen.next(); - if (done) break; + if (done) { + break; + } yield [[m, r]].concat(subpath); } for (let c = 0; c < ncoords; c++) { @@ -1317,8 +1355,9 @@ function* solve_phase1_gen(facelets) { function* phase1_ida_solve_gen(indices, mtables, ptables, moves_left) { let ncoords = indices.length; let bound = 0; - for (let i = 0; i < ncoords; i++) + for (let i = 0; i < ncoords; i++) { bound = Math.max(bound, ptables[i][indices[i]]); + } while (bound <= moves_left) { //console.log(`searching depth ${bound}`); yield* phase1_ida_search_gen(indices, mtables, ptables, bound, -1); @@ -1335,15 +1374,23 @@ function* phase1_ida_search_gen(indices, mtables, ptables, bound, last) { ptables[2][indices[2]], ); //0; //for (let i = 0; i < ncoords; i++) heuristic = Math.max(heuristic, ptables[i][indices[i]]); - if (heuristic > bound) return; + if (heuristic > bound) { + return; + } if (bound === 0) { yield []; return; } - if (heuristic === 0 && bound === 1) return; + if (heuristic === 0 && bound === 1) { + return; + } for (let m = 0; m < nmoves; m++) { - if (m === last) continue; - if (m === last - 4) continue; + if (m === last) { + continue; + } + if (m === last - 4) { + continue; + } let new_indices = []; new_indices[0] = mtables[0][m][indices[0]]; new_indices[1] = mtables[1][m][indices[1]]; @@ -1359,7 +1406,9 @@ function* phase1_ida_search_gen(indices, mtables, ptables, bound, last) { ); while (true) { let { value: subpath, done } = subpath_gen.next(); - if (done) break; + if (done) { + break; + } yield [[m, r]].concat(subpath); } new_indices[0] = mtables[0][m][new_indices[0]]; @@ -1724,7 +1773,9 @@ function* phase2_ida_search_gen( return; } for (let m = 0; m < 4; m++) { - if (m === last) continue; + if (m === last) { + continue; + } let new_a = a, new_b = b, new_ce = ce; @@ -1746,7 +1797,9 @@ function* phase2_ida_search_gen( ); while (true) { let { value: subpath, done } = subpath_gen.next(); - if (done) break; + if (done) { + break; + } yield [[m, r]].concat(subpath); } } diff --git a/src/cubing/vendor/xyzzy/fto-solver.js b/src/cubing/vendor/xyzzy/fto-solver.js index faa87c7d9..340968d17 100644 --- a/src/cubing/vendor/xyzzy/fto-solver.js +++ b/src/cubing/vendor/xyzzy/fto-solver.js @@ -18,22 +18,32 @@ import { randomUIntBelowFactory } from "../random-uint-below"; function counter(A) { let counts = []; - for (let a of A) counts[a] = (counts[a] || 0) + 1; + for (let a of A) { + counts[a] = (counts[a] || 0) + 1; + } return counts; } /* Combinatoric functions */ function factorial(n) { - if (n < 2) return n; + if (n < 2) { + return n; + } let f = 1; - for (let i = 2; i <= n; i++) f *= i; + for (let i = 2; i <= n; i++) { + f *= i; + } return f; } function C(n, k) { - if (k < 0 || k > n) return 0; - if (k === 0 || k === n) return 1; + if (k < 0 || k > n) { + return 0; + } + if (k === 0 || k === n) { + return 1; + } let c = 1; for (let i = 0; i < k; i++) { c = ((c * (n - i)) / (i + 1)) | 0; @@ -86,7 +96,9 @@ function permutation_parity(A) { let parity = 0; for (let i = 0; i < n - 1; i++) { for (let j = i; j < n; j++) { - if (A[i] > A[j]) parity ^= 1; + if (A[i] > A[j]) { + parity ^= 1; + } } } return parity; @@ -104,11 +116,16 @@ function index_to_evenpermutation(ind, n) { perm[n - 1] = 0; for (let i = n - 2; i >= 0; i--) { for (let j = i + 1; j < n; j++) { - if (perm[j] >= perm[i]) perm[j]++; - else parity ^= 1; + if (perm[j] >= perm[i]) { + perm[j]++; + } else { + parity ^= 1; + } } } - if (parity === 1) [perm[n - 2], perm[n - 1]] = [perm[n - 1], perm[n - 2]]; + if (parity === 1) { + [perm[n - 2], perm[n - 1]] = [perm[n - 1], perm[n - 2]]; + } return perm; } @@ -187,9 +204,13 @@ function random_even_permutation(n, randomUintBelow) { function comb_to_index(l) { let bits = l.length; let ones = 0; - for (let i = 0; i < bits; i++) ones += +(l[i] === 1); + for (let i = 0; i < bits; i++) { + ones += +(l[i] === 1); + } let zeros = bits - ones; - if (zeros === 0 || ones === 0 || bits === 1) return 0; + if (zeros === 0 || ones === 0 || bits === 1) { + return 0; + } let b = C(bits - 1, ones); let ind = 0; for (let i = 0; zeros > 0 && ones > 0 && bits > 1; i++) { @@ -319,13 +340,17 @@ function generate_comb4_lookup_tables(n, k0, k1, k2, k3) { function compose(A, B) { let C = []; - for (let i = 0; i < B.length; i++) C[i] = A[B[i]]; + for (let i = 0; i < B.length; i++) { + C[i] = A[B[i]]; + } return C; } function compose3(A, B, C) { let D = []; - for (let i = 0; i < C.length; i++) D[i] = A[B[C[i]]]; + for (let i = 0; i < C.length; i++) { + D[i] = A[B[C[i]]]; + } return D; } @@ -1093,8 +1118,9 @@ function bfs(mtable, goal_states) { function* ida_solve_gen(indices, mtables, ptables, moves_left, commute) { let ncoords = indices.length; let bound = 0; - for (let i = 0; i < ncoords; i++) + for (let i = 0; i < ncoords; i++) { bound = Math.max(bound, ptables[i][indices[i]]); + } while (bound <= moves_left) { //console.log(`searching depth ${bound}`); yield* ida_search_gen(indices, mtables, ptables, bound, -1, commute); @@ -1106,20 +1132,30 @@ function* ida_search_gen(indices, mtables, ptables, bound, last, commute) { let ncoords = indices.length; let nmoves = mtables[0].length; let heuristic = 0; - for (let i = 0; i < ncoords; i++) + for (let i = 0; i < ncoords; i++) { heuristic = Math.max(heuristic, ptables[i][indices[i]]); - if (heuristic > bound) return; + } + if (heuristic > bound) { + return; + } if (bound === 0) { yield []; return; } - if (heuristic === 0 && bound === 1) return; + if (heuristic === 0 && bound === 1) { + return; + } for (let m = 0; m < nmoves; m++) { - if (m === last) continue; - if (m < last && commute[m][last]) continue; + if (m === last) { + continue; + } + if (m < last && commute[m][last]) { + continue; + } let new_indices = indices.slice(); - for (let c = 0; c < ncoords; c++) + for (let c = 0; c < ncoords; c++) { new_indices[c] = mtables[c][m][indices[c]]; + } let r = 1; while (indices.some((_, i) => indices[i] !== new_indices[i])) { let subpath_gen = ida_search_gen( @@ -1132,7 +1168,9 @@ function* ida_search_gen(indices, mtables, ptables, bound, last, commute) { ); while (true) { let { value: subpath, done } = subpath_gen.next(); - if (done) break; + if (done) { + break; + } yield [[m, r]].concat(subpath); } for (let c = 0; c < ncoords; c++) { @@ -1272,8 +1310,9 @@ function* solve_phase1_gen(facelets) { function* phase1_ida_solve_gen(indices, mtables, ptables, moves_left) { let ncoords = indices.length; let bound = 0; - for (let i = 0; i < ncoords; i++) + for (let i = 0; i < ncoords; i++) { bound = Math.max(bound, ptables[i][indices[i]]); + } while (bound <= moves_left) { //console.log(`searching depth ${bound}`); yield* phase1_ida_search_gen(indices, mtables, ptables, bound, -1); @@ -1290,15 +1329,23 @@ function* phase1_ida_search_gen(indices, mtables, ptables, bound, last) { ptables[2][indices[2]], ); //0; //for (let i = 0; i < ncoords; i++) heuristic = Math.max(heuristic, ptables[i][indices[i]]); - if (heuristic > bound) return; + if (heuristic > bound) { + return; + } if (bound === 0) { yield []; return; } - if (heuristic === 0 && bound === 1) return; + if (heuristic === 0 && bound === 1) { + return; + } for (let m = 0; m < nmoves; m++) { - if (m === last) continue; - if (m === last - 4) continue; + if (m === last) { + continue; + } + if (m === last - 4) { + continue; + } let new_indices = []; new_indices[0] = mtables[0][m][indices[0]]; new_indices[1] = mtables[1][m][indices[1]]; @@ -1314,7 +1361,9 @@ function* phase1_ida_search_gen(indices, mtables, ptables, bound, last) { ); while (true) { let { value: subpath, done } = subpath_gen.next(); - if (done) break; + if (done) { + break; + } yield [[m, r]].concat(subpath); } new_indices[0] = mtables[0][m][new_indices[0]]; @@ -1679,7 +1728,9 @@ function* phase2_ida_search_gen( return; } for (let m = 0; m < 4; m++) { - if (m === last) continue; + if (m === last) { + continue; + } let new_a = a, new_b = b, new_ce = ce; @@ -1701,7 +1752,9 @@ function* phase2_ida_search_gen( ); while (true) { let { value: subpath, done } = subpath_gen.next(); - if (done) break; + if (done) { + break; + } yield [[m, r]].concat(subpath); } } diff --git a/src/cubing/vendor/xyzzy/kilosolver.js b/src/cubing/vendor/xyzzy/kilosolver.js index daff1f416..ae70c518f 100644 --- a/src/cubing/vendor/xyzzy/kilosolver.js +++ b/src/cubing/vendor/xyzzy/kilosolver.js @@ -62,22 +62,22 @@ let PHASE4_THRESHOLD = 7; function counter(A) { let counts = []; - for (let a of A) counts[a] = (counts[a] || 0) + 1; + for (let a of A) { counts[a] = (counts[a] || 0) + 1; } return counts; } /* Combinatoric functions */ function factorial(n) { - if (n < 2) return n; + if (n < 2) { return n; } let f = 1; - for (let i = 2; i <= n; i++) f *= i; + for (let i = 2; i <= n; i++) { f *= i; } return f; } function C(n, k) { - if (k < 0 || k > n) return 0; - if (k === 0 || k === n) return 1; + if (k < 0 || k > n) { return 0; } + if (k === 0 || k === n) { return 1; } let c = 1; for (let i = 0; i < k; i++) { c = ((c * (n - i)) / (i + 1)) | 0; @@ -126,7 +126,7 @@ function permutation_parity(A) { let parity = 0; for (let i = 0; i < n - 1; i++) { for (let j = i; j < n; j++) { - if (A[i] > A[j]) parity ^= 1; + if (A[i] > A[j]) { parity ^= 1; } } } return parity; @@ -144,11 +144,11 @@ function index_to_evenpermutation(ind, n) { perm[n - 1] = 0; for (let i = n - 2; i >= 0; i--) { for (let j = i + 1; j < n; j++) { - if (perm[j] >= perm[i]) perm[j]++; - else parity ^= 1; + if (perm[j] >= perm[i]) { perm[j]++; } + else { parity ^= 1; } } } - if (parity === 1) [perm[n - 2], perm[n - 1]] = [perm[n - 1], perm[n - 2]]; + if (parity === 1) { [perm[n - 2], perm[n - 1]] = [perm[n - 1], perm[n - 2]]; } return perm; } @@ -209,9 +209,9 @@ let [evenpermutation10_to_index, index_to_evenpermutation10] = (() => { function comb_to_index(l) { let bits = l.length; let ones = 0; - for (let i = 0; i < bits; i++) ones += +(l[i] === 1); + for (let i = 0; i < bits; i++) { ones += +(l[i] === 1); } let zeros = bits - ones; - if (zeros === 0 || ones === 0 || bits === 1) return 0; + if (zeros === 0 || ones === 0 || bits === 1) { return 0; } let b = C(bits - 1, ones); let ind = 0; for (let i = 0; zeros > 0 && ones > 0 && bits > 1; i++) { @@ -249,7 +249,7 @@ function index_to_comb(ind, ones, bits) { function compose(A, B) { let C = []; - for (let i = 0; i < B.length; i++) C[i] = A[B[i]]; + for (let i = 0; i < B.length; i++) { C[i] = A[B[i]]; } return C; } @@ -267,7 +267,7 @@ function compose_o(A, B) { function permutation_from_cycle(cycle, n) { let perm = []; - for (let i = 0; i < n; i++) perm[i] = i; + for (let i = 0; i < n; i++) { perm[i] = i; } for (let i = 0; i < cycle.length; i++) { perm[cycle[i]] = cycle[(i + 1) % cycle.length]; } @@ -276,7 +276,7 @@ function permutation_from_cycle(cycle, n) { function unsparsify_list(d, n) { let l = Array(n).fill(0); - for (let k in d) l[k] = d[k]; + for (let k in d) { l[k] = d[k]; } return l; } @@ -327,8 +327,9 @@ let id = compose_o(move_x2, move_x2); let moves_full = []; for (let i = 0; i < moves.length; i++) { moves_full[i] = [id]; - for (let j = 1; j < 5; j++) + for (let j = 1; j < 5; j++) { moves_full[i][j] = compose_o(moves_full[i][j - 1], moves[i]); + } } function random_state(randomUintBelow) { @@ -338,7 +339,7 @@ function random_state(randomUintBelow) { p[i] = p[r]; p[r] = i; } - if (permutation_parity(p) === 1) [p[0], p[1]] = [p[1], p[0]]; + if (permutation_parity(p) === 1) { [p[0], p[1]] = [p[1], p[0]]; } let o = Array(20).fill(0); for (let i = 0; i < 19; i++) { o[i] = randomUintBelow(3); @@ -362,7 +363,7 @@ function print_move_sequence(move_sequence) { function apply_move_sequence(state, move_sequence) { for (let [m, r] of move_sequence) { - for (let i = 0; i < r; i++) state = compose_o(state, moves[m]); + for (let i = 0; i < r; i++) { state = compose_o(state, moves[m]); } } return state; } @@ -384,13 +385,14 @@ function generate_random_move_scramble(M, N) { while (true) { m = Math.floor(Math.random() * 6); // don't output stuff like U2 U - if (m === last) continue; + if (m === last) { continue; } // U move never commutes with the others - else if (m === 0) break; + else if (m === 0) { break; } // don't output stuff like L R L because L and R commute - else if (m === lastlast && ((m - last) * (m - last)) % 5 === 4) + else if (m === lastlast && ((m - last) * (m - last)) % 5 === 4) { continue; - else break; + } + else { break; } } // make 144-deg moves twice as likely as 72-deg moves move_sequence.push([m, 1 + Math.round(Math.random() * 3)]); @@ -398,7 +400,7 @@ function generate_random_move_scramble(M, N) { } // flip after every set of moves on the hemisphere except the last because that would be // kind of pointless - if (i < M) move_sequence.push([6, 1]); + if (i < M) { move_sequence.push([6, 1]); } } return move_sequence; } @@ -642,7 +644,7 @@ function create_svg_template(state, colour_scheme) { function draw_state(svgel, state, colour_scheme) { colour_scheme = colour_scheme || default_colour_scheme; - if (!svgel) return create_svg_template(state, colour_scheme); + if (!svgel) { return create_svg_template(state, colour_scheme); } for (let i = 0; i < 20; i++) { for (let j = 0; j < 3; j++) { let el = svgel.querySelector(".loc" + i + "_" + j); @@ -707,8 +709,8 @@ function solve_phase1(state) { // we don't care about orientation. let p = state[0]; // x < 15 tests if a piece is non-grey. - if (p.slice(15, 20).every((x) => x < 15)) return []; - if (p.slice(0, 5).every((x) => x < 15)) return [[6, 1]]; + if (p.slice(15, 20).every((x) => x < 15)) { return []; } + if (p.slice(0, 5).every((x) => x < 15)) { return [[6, 1]]; } let flags = p.map((x) => x >= 15); let depth = 0, sol; @@ -722,15 +724,15 @@ function solve_phase1(state) { function search_phase1(flags, depth, last) { if (depth === 0) { - if (flags.slice(0, 5).some((x) => x)) return; + if (flags.slice(0, 5).some((x) => x)) { return; } return []; } for (let move_index = 0; move_index < 6; move_index++) { - if (move_index === last) continue; + if (move_index === last) { continue; } for (let r = 1; r < 5; r++) { let new_flags = compose(flags, moves_full[move_index][r][0]); let sol = search_phase1(new_flags, depth - 1, move_index); - if (sol !== undefined) return [[move_index, r]].concat(sol); + if (sol !== undefined) { return [[move_index, r]].concat(sol); } } } return; @@ -742,7 +744,7 @@ function index_phase2(state) { let index_c = comb_to_index(p.map((x) => +(x >= 15))); let index_o = 243 * index_c; for (let i = 0, j = 0; i < 15; i++) { - if (p[i] < 15) continue; + if (p[i] < 15) { continue; } index_o += o[i] * Math.pow(3, j); // as it so happens, my JS shell is too outdated and doesn't support ** j++; @@ -773,7 +775,7 @@ function index_phase3(state) { let index_c = comb_to_index(p.map((x) => +(pieces.indexOf(x) !== -1))); let index_o = 243 * index_c; for (let i = 0, j = 0; i < 15; i++) { - if (pieces.indexOf(p[i]) === -1) continue; + if (pieces.indexOf(p[i]) === -1) { continue; } index_o += o[i] * Math.pow(3, j); j++; } @@ -803,7 +805,7 @@ function index_phase4(state) { perm = []; let j = 0; for (let i of [0, 1, 2, 3, 4, 9, 10, 11, 12, 13]) { - if (i !== 13) index_o += o[i] * Math.pow(3, j); + if (i !== 13) { index_o += o[i] * Math.pow(3, j); } perm[j] = p[i] < 5 ? p[i] : p[i] - 4; j++; } @@ -868,7 +870,7 @@ function cn_solve(state) { const tables = {}; function generate_phase23_orientation_mtable() { - if (tables.phase23om) return tables.phase23om; + if (tables.phase23om) { return tables.phase23om; } const C15_5 = C(15, 5), THREE = [1, 3, 9, 27, 81, 243]; let phase23om = Array(C(15, 5) * THREE[5]); @@ -887,8 +889,8 @@ function generate_phase23_orientation_mtable() { if (comb[k] === 1) { orient_full[k] = ((j / THREE[l]) | 0) % 3; l++; - } else - orient_full[k] = 99; // some irrelevant garbage value + } else { + orient_full[k] = 99; // some irrelevant garbage value } } for (let move_index = 0; move_index < 6; move_index++) { let move = moves[move_index]; @@ -910,19 +912,19 @@ function generate_phase23_orientation_mtable() { } function generate_phase2_orientation_ptable() { - if (tables.phase2op) return tables.phase2op; + if (tables.phase2op) { return tables.phase2op; } let mtable = generate_phase23_orientation_mtable(); return (tables.phase2op = bfs(mtable, [243 * 3002])); } function generate_phase3_orientation_ptable() { - if (tables.phase3op) return tables.phase3op; + if (tables.phase3op) { return tables.phase3op; } let mtable = generate_phase23_orientation_mtable(); return (tables.phase3op = bfs(mtable, [243 * 246])); } function generate_phase23_permutation_mtable() { - if (tables.phase23pm) return tables.phase23pm; + if (tables.phase23pm) { return tables.phase23pm; } const FIFTEEN = [ 1, 15, @@ -961,19 +963,19 @@ function generate_phase23_permutation_mtable() { } function generate_phase2_permutation_ptable() { - if (tables.phase2pp) return tables.phase2pp; + if (tables.phase2pp) { return tables.phase2pp; } let mtable = generate_phase23_permutation_mtable(); return (tables.phase2pp = bfs(mtable, [213090])); } function generate_phase3_permutation_ptable() { - if (tables.phase3pp) return tables.phase3pp; + if (tables.phase3pp) { return tables.phase3pp; } let mtable = generate_phase23_permutation_mtable(); return (tables.phase3pp = bfs(mtable, [737420])); } function generate_phase4_orientation_mtable() { - if (tables.phase4om) return tables.phase4om; + if (tables.phase4om) { return tables.phase4om; } const THREE = [1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049]; let mtable = Array(THREE[9]); for (let i = 0; i < THREE[9]; i++) { @@ -991,7 +993,7 @@ function generate_phase4_orientation_mtable() { (i) => o[move[0][i]] + move[1][i], ); let new_i = 0; - for (let j = 0; j < 9; j++) new_i += (new_o[j] % 3) * THREE[j]; + for (let j = 0; j < 9; j++) { new_i += (new_o[j] % 3) * THREE[j]; } mtable[i][move_index] = new_i; } } @@ -999,7 +1001,7 @@ function generate_phase4_orientation_mtable() { } function generate_phase4_permutation_mtable() { - if (tables.phase4pm) return tables.phase4pm; + if (tables.phase4pm) { return tables.phase4pm; } const HALFFACT10 = factorial(10) / 2, n = 10; let pre = [0, 1, 2, 3, 4, -1, -1, -1, -1, 5, 6, 7, 8, 9]; @@ -1023,20 +1025,21 @@ function generate_phase4_permutation_mtable() { } function generate_phase4_orientation_ptable() { - if (tables.phase4op) return tables.phase4op; + if (tables.phase4op) { return tables.phase4op; } let mtable = generate_phase4_orientation_mtable(); return (tables.phase4op = bfs(mtable, [0])); } function generate_phase4_permutation_ptable() { - if (tables.phase4pp) return tables.phase4pp; + if (tables.phase4pp) { return tables.phase4pp; } let mtable = generate_phase4_permutation_mtable(); return (tables.phase4pp = bfs(mtable, [0])); } function generate_phase4_near_ptable_list(threshold) { - if (tables.phase4np_list && tables.phase4np_list.threshold === threshold) + if (tables.phase4np_list && tables.phase4np_list.threshold === threshold) { return tables.phase4np_list; + } let mtables = [ generate_phase4_orientation_mtable(), generate_phase4_permutation_mtable(), @@ -1046,10 +1049,10 @@ function generate_phase4_near_ptable_list(threshold) { populate(threshold, [0, 0], -1); function populate(depth, state, last) { states.push(state[0] + base * state[1]); - if (depth === 0) return; + if (depth === 0) { return; } let new_state = []; for (let move_index = 0; move_index < 3; move_index++) { - if (move_index === last) continue; + if (move_index === last) { continue; } new_state[0] = state[0]; new_state[1] = state[1]; for (let r = 1; r < 5; r++) { @@ -1063,8 +1066,9 @@ function generate_phase4_near_ptable_list(threshold) { states.sort((x, y) => x - y); let unique_states = [], last = -1; - for (let state of states) - if (state !== last) unique_states.push((last = state)); + for (let state of states) { + if (state !== last) { unique_states.push((last = state)); } + } unique_states.threshold = threshold; return (tables.phase4np_list = unique_states); } @@ -1075,8 +1079,8 @@ function binary_search(A, x) { while (hi - lo > 1) { // invariants: hi - lo >= 2; x > A[lo-1]; x < A[hi+1] let mid = (lo + hi) >> 1; // lo < mid < hi - if (x > A[mid]) lo = mid + 1; - else hi = mid; + if (x > A[mid]) { lo = mid + 1; } + else { hi = mid; } } return x === A[lo] || x === A[hi]; } @@ -1189,11 +1193,12 @@ function bfs(mtable, goal_states) { function ida_solve(indices, mtables, ptables) { let ncoords = indices.length; let bound = 0; - for (let i = 0; i < ncoords; i++) + for (let i = 0; i < ncoords; i++) { bound = Math.max(bound, ptables[i][indices[i]]); + } while (true) { let path = ida_search(indices, mtables, ptables, bound, -1); - if (path !== undefined) return path; + if (path !== undefined) { return path; } bound++; } } @@ -1202,19 +1207,21 @@ function ida_search(indices, mtables, ptables, bound, last) { let ncoords = indices.length; let nmoves = mtables[0][0].length; let heuristic = 0; - for (let i = 0; i < ncoords; i++) + for (let i = 0; i < ncoords; i++) { heuristic = Math.max(heuristic, ptables[i][indices[i]]); - if (heuristic > bound) return; - if (bound === 0 || heuristic === 0) return []; + } + if (heuristic > bound) { return; } + if (bound === 0 || heuristic === 0) { return []; } for (let m = 0; m < nmoves; m++) { - if (m === last) continue; + if (m === last) { continue; } let new_indices = indices.slice(); - for (let c = 0; c < ncoords; c++) + for (let c = 0; c < ncoords; c++) { new_indices[c] = mtables[c][indices[c]][m]; + } let r = 1; while (indices.some((_, i) => indices[i] !== new_indices[i])) { let subpath = ida_search(new_indices, mtables, ptables, bound - 1, m); - if (subpath !== undefined) return [[m, r]].concat(subpath); + if (subpath !== undefined) { return [[m, r]].concat(subpath); } for (let c = 0; c < ncoords; c++) { new_indices[c] = mtables[c][new_indices[c]][m]; } @@ -1242,7 +1249,7 @@ function phase4_ida_solve(indices) { ptable_p, ptable_n, ); - if (path !== undefined) return path; + if (path !== undefined) { return path; } bound++; } } @@ -1258,16 +1265,17 @@ function phase4_ida_search( ptable_n, ) { let heuristic = Math.max(ptable_o[indices[0]], ptable_p[indices[1]]); - if (heuristic > bound) return; + if (heuristic > bound) { return; } if ( heuristic <= PHASE4_THRESHOLD && !binary_search(ptable_n, indices[0] + 19683 * indices[1]) - ) + ) { heuristic = PHASE4_THRESHOLD + 1; - if (heuristic > bound) return; - if (bound === 0 || heuristic === 0) return []; + } + if (heuristic > bound) { return; } + if (bound === 0 || heuristic === 0) { return []; } for (let m = 0; m < 3; m++) { - if (m === last) continue; + if (m === last) { continue; } let new_indices = indices.slice(); for (let r = 1; r < 5; r++) { new_indices[0] = mtable_o[new_indices[0]][m]; @@ -1282,7 +1290,7 @@ function phase4_ida_search( ptable_p, ptable_n, ); - if (subpath !== undefined) return [[m, r]].concat(subpath); + if (subpath !== undefined) { return [[m, r]].concat(subpath); } } } return; @@ -1321,16 +1329,17 @@ function* phase4_ida_search_gen( ptable_n, ) { let heuristic = Math.max(ptable_o[indices[0]], ptable_p[indices[1]]); - if (heuristic > bound) return; + if (heuristic > bound) { return; } if ( heuristic <= PHASE4_THRESHOLD && !binary_search(ptable_n, indices[0] + 19683 * indices[1]) - ) + ) { heuristic = PHASE4_THRESHOLD + 1; - if (heuristic > bound) return; - if (bound === 0 || heuristic === 0) yield []; + } + if (heuristic > bound) { return; } + if (bound === 0 || heuristic === 0) { yield []; } for (let m = 0; m < 3; m++) { - if (m === last) continue; + if (m === last) { continue; } let new_indices = indices.slice(); for (let r = 1; r < 5; r++) { new_indices[0] = mtable_o[new_indices[0]][m]; @@ -1347,7 +1356,7 @@ function* phase4_ida_search_gen( ); while (true) { let { value: subpath, done } = subpath_gen.next(); - if (done) break; + if (done) { break; } yield [[m, r]].concat(subpath); } } @@ -1368,7 +1377,7 @@ for all intents and purposes, this should be as good as a random-state scramble. */ function generate_hs_mtable() { - if (tables.hsm) return tables.hsm; + if (tables.hsm) { return tables.hsm; } const C20_5 = C(20, 5); // = 15504 let mtable = Array(C20_5); for (let i = 0; i < C20_5; i++) { @@ -1383,13 +1392,13 @@ function generate_hs_mtable() { } function generate_hs_u_ptable() { - if (tables.hsup) return tables.hsup; + if (tables.hsup) { return tables.hsup; } let mtable = generate_hs_mtable(); return (tables.hsup = bfs(mtable, [15503])); } function generate_hs_d_ptable() { - if (tables.hsdp) return tables.hsdp; + if (tables.hsdp) { return tables.hsdp; } let mtable = generate_hs_mtable(); return (tables.hsdp = bfs(mtable, [0])); } @@ -1441,7 +1450,7 @@ function generate_hybrid_scramble() { } function generate_fullseparate_mtable() { - if (tables.fsm) return tables.fsm; + if (tables.fsm) { return tables.fsm; } const C20_10 = C(20, 10); // = 184756 const C19_9 = C(19, 9); // = 92378 let moves12 = moves.slice(0, 6); @@ -1460,8 +1469,8 @@ function generate_fullseparate_mtable() { let comb = index_to_comb(i, 10, 20); let perm = []; for (let j = 0, k = 0; j < 20; j++) { - if (comb[j] === 0) perm[j] = -1; - else perm[j] = k++; + if (comb[j] === 0) { perm[j] = -1; } + else { perm[j] = k++; } } for (let m = 0; m < 15; m++) { let new_perm = compose(perm, moves15[m][0]); @@ -1482,7 +1491,7 @@ function generate_fullseparate_mtable() { } function generate_fullseparate_ptable() { - if (tables.fsp) return tables.fsp; + if (tables.fsp) { return tables.fsp; } let mtable = generate_fullseparate_mtable(); /* let separations = [ @@ -1510,7 +1519,7 @@ function generate_fullseparate_ptable() { } } } - if (goal_states.length === l) break; + if (goal_states.length === l) { break; } l = goal_states.length; } print(goal_states.toSource()); @@ -1527,12 +1536,12 @@ function bfs5(mtable, goal_states) { while (queue.length > 0) { new_queue.length = 0; for (let state of queue) { - if (ptable[state] !== -1) continue; + if (ptable[state] !== -1) { continue; } ptable[state] = depth; for (let move_index = 0; move_index < nmoves; move_index++) { let new_state = mtable[state][move_index]; for (let r = 1; r <= 4; r++) { - if (r === 1 || r === 4) new_queue.push(new_state); + if (r === 1 || r === 4) { new_queue.push(new_state); } new_state = mtable[new_state][move_index]; } } diff --git a/src/cubing/vendor/xyzzy/master_tetraminx-solver.js b/src/cubing/vendor/xyzzy/master_tetraminx-solver.js index b83ab5362..6124bcc17 100644 --- a/src/cubing/vendor/xyzzy/master_tetraminx-solver.js +++ b/src/cubing/vendor/xyzzy/master_tetraminx-solver.js @@ -9,16 +9,22 @@ import { randomUIntBelowFactory } from "../random-uint-below"; function counter(A) { let counts = []; - for (let a of A) counts[a] = (counts[a] || 0) + 1; + for (let a of A) { + counts[a] = (counts[a] || 0) + 1; + } return counts; } /* Combinatoric functions */ function factorial(n) { - if (n < 2) return n; + if (n < 2) { + return n; + } let f = 1; - for (let i = 2; i <= n; i++) f *= i; + for (let i = 2; i <= n; i++) { + f *= i; + } return f; } @@ -71,7 +77,9 @@ function permutation_parity(A) { let parity = 0; for (let i = 0; i < n - 1; i++) { for (let j = i; j < n; j++) { - if (A[i] > A[j]) parity ^= 1; + if (A[i] > A[j]) { + parity ^= 1; + } } } return parity; @@ -89,11 +97,16 @@ function index_to_evenpermutation(ind, n) { perm[n - 1] = 0; for (let i = n - 2; i >= 0; i--) { for (let j = i + 1; j < n; j++) { - if (perm[j] >= perm[i]) perm[j]++; - else parity ^= 1; + if (perm[j] >= perm[i]) { + perm[j]++; + } else { + parity ^= 1; + } } } - if (parity === 1) [perm[n - 2], perm[n - 1]] = [perm[n - 1], perm[n - 2]]; + if (parity === 1) { + [perm[n - 2], perm[n - 1]] = [perm[n - 1], perm[n - 2]]; + } return perm; } @@ -155,7 +168,9 @@ let [evenpermutation12_to_index, index_to_evenpermutation12] = (() => { function compose(A, B) { let C = []; - for (let i = 0; i < B.length; i++) C[i] = A[B[i]]; + for (let i = 0; i < B.length; i++) { + C[i] = A[B[i]]; + } return C; } @@ -177,7 +192,9 @@ function invert(perm) { function permutation_from_cycle(cycle, n) { let perm = []; - for (let i = 0; i < n; i++) perm[i] = i; + for (let i = 0; i < n; i++) { + perm[i] = i; + } for (let i = 0; i < cycle.length; i++) { perm[cycle[i]] = cycle[(i + 1) % cycle.length]; } @@ -569,7 +586,9 @@ function moves_commute(i, j) { function apply_move_sequence(state, move_sequence) { for (let [m, r] of move_sequence) { - for (let i = 0; i < r; i++) state = compose_state(state, moves[m]); + for (let i = 0; i < r; i++) { + state = compose_state(state, moves[m]); + } } return state; } @@ -679,14 +698,17 @@ function solve(state) { let { value: sol1, done } = phase1gen.next(); let new_state = state; for (let [m, r] of sol1) { - for (let i = 0; i < r; i++) + for (let i = 0; i < r; i++) { new_state = compose_state(new_state, moves[m]); + } } let stringified_state = JSON.stringify(new_state); if (intermediate_states.has(stringified_state)) { // console.log("skip"); continue; - } else intermediate_states.add(stringified_state); + } else { + intermediate_states.add(stringified_state); + } let phase2_indices = index_phase2(new_state); //let sol2 = []; let moves_left = best ? best.length - sol1.length - 1 : 999999; @@ -709,7 +731,9 @@ function solve(state) { best = sol1.concat(sol2); } // bail if we've spent too much time - if (performance.now() - start_time > 300) break; + if (performance.now() - start_time > 300) { + break; + } } return best; } @@ -785,8 +809,8 @@ for (let i = 0; i < 25; i++) { phase1_score_ptable_condensed[i + 30] = phase1_score_ptable[1][i]; } let phase1_coord_to_score = new Int8Array(6 * 12 * 12 * 3); -for (let i = 0; i < 6; i++) - for (let j = 0; j < 12; j++) +for (let i = 0; i < 6; i++) { + for (let j = 0; j < 12; j++) { for (let k = 0; k < 12; k++) { let index = i + 6 * j + 72 * k; let score = 2; @@ -805,6 +829,8 @@ for (let i = 0; i < 6; i++) index + 2 * 6 * 12 * 12 ] = score + 5; } + } +} function phase1_benchmark() { /* some 13-move phase 1 states*/ @@ -875,15 +901,23 @@ function* phase1_ida_search_gen(a, b, c, d, e, f, mtable, ptable, bound, last) { ptable[(d % 864) + f * 864], phase1_score_ptable_condensed[score], ); - if (heuristic > bound) return; + if (heuristic > bound) { + return; + } if (bound === 0) { yield []; return; } - if (heuristic === 0 && bound === 1) return; + if (heuristic === 0 && bound === 1) { + return; + } for (let m = 0; m < nmoves; m++) { - if (m === last) continue; - if (m < last && moves_commute(m, last)) continue; + if (m === last) { + continue; + } + if (m < last && moves_commute(m, last)) { + continue; + } let A = a, B = b, C = c, @@ -911,7 +945,9 @@ function* phase1_ida_search_gen(a, b, c, d, e, f, mtable, ptable, bound, last) { ); while (true) { let { value: subpath, done } = subpath_gen.next(); - if (done) break; + if (done) { + break; + } yield [[m, r]].concat(subpath); } } @@ -992,11 +1028,14 @@ function generate_phase1_pairing2c_ptable() { let ptable = new Int8Array((6 * 12 * 12) ** 2 * 3); ptable.fill(-1); let g = [0, 1, 2, 3, 4, 5].map((x) => x + 6 * x + 72 * (x + 6)); - for (let i = 0; i < 6; i++) + for (let i = 0; i < 6; i++) { for (let j = 0; j < 6; j++) { - if (i === j) continue; + if (i === j) { + continue; + } ptable[g[i] + 864 * g[j]] = 0; } + } let dist = 0; while (true) { let changed = false; @@ -1180,7 +1219,9 @@ function bfs(mtable, goal_states) { while (queue.length > 0) { new_queue.length = 0; for (let state of queue) { - if (ptable[state] !== -1) continue; + if (ptable[state] !== -1) { + continue; + } ptable[state] = depth; for (let move_index = 0; move_index < nmoves; move_index++) { let new_state = mtable[state][move_index]; @@ -1199,8 +1240,9 @@ function bfs(mtable, goal_states) { function* ida_solve_gen(indices, mtables, ptables, moves_left) { let ncoords = indices.length; let bound = 0; - for (let i = 0; i < ncoords; i++) + for (let i = 0; i < ncoords; i++) { bound = Math.max(bound, ptables[i][indices[i]]); + } while (bound <= moves_left) { yield* ida_search_gen(indices, mtables, ptables, bound, -1); bound++; @@ -1211,20 +1253,30 @@ function* ida_search_gen(indices, mtables, ptables, bound, last) { let ncoords = indices.length; let nmoves = mtables[0][0].length; let heuristic = 0; - for (let i = 0; i < ncoords; i++) + for (let i = 0; i < ncoords; i++) { heuristic = Math.max(heuristic, ptables[i][indices[i]]); - if (heuristic > bound) return; + } + if (heuristic > bound) { + return; + } if (bound === 0) { yield []; return; } - if (heuristic === 0 && bound === 1) return; + if (heuristic === 0 && bound === 1) { + return; + } for (let m = 0; m < nmoves; m++) { - if (m === last) continue; - if (m < last && moves_commute(m, last)) continue; + if (m === last) { + continue; + } + if (m < last && moves_commute(m, last)) { + continue; + } let new_indices = indices.slice(); - for (let c = 0; c < ncoords; c++) + for (let c = 0; c < ncoords; c++) { new_indices[c] = mtables[c][indices[c]][m]; + } let r = 1; while (indices.some((_, i) => indices[i] !== new_indices[i])) { let subpath_gen = ida_search_gen( @@ -1236,7 +1288,9 @@ function* ida_search_gen(indices, mtables, ptables, bound, last) { ); while (true) { let { value: subpath, done } = subpath_gen.next(); - if (done) break; + if (done) { + break; + } yield [[m, r]].concat(subpath); } for (let c = 0; c < ncoords; c++) { diff --git a/src/cubing/vendor/xyzzy/redi_cube.js b/src/cubing/vendor/xyzzy/redi_cube.js index 1aa67b07a..f2e1fe389 100644 --- a/src/cubing/vendor/xyzzy/redi_cube.js +++ b/src/cubing/vendor/xyzzy/redi_cube.js @@ -10,22 +10,32 @@ import { randomUIntBelowFactory } from "../random-uint-below"; function counter(A) { let counts = []; - for (let a of A) counts[a] = (counts[a] || 0) + 1; + for (let a of A) { + counts[a] = (counts[a] || 0) + 1; + } return counts; } /* Combinatoric functions */ function factorial(n) { - if (n < 2) return n; + if (n < 2) { + return n; + } let f = 1; - for (let i = 2; i <= n; i++) f *= i; + for (let i = 2; i <= n; i++) { + f *= i; + } return f; } function C(n, k) { - if (k < 0 || k > n) return 0; - if (k === 0 || k === n) return 1; + if (k < 0 || k > n) { + return 0; + } + if (k === 0 || k === n) { + return 1; + } let c = 1; for (let i = 0; i < k; i++) { c = ((c * (n - i)) / (i + 1)) | 0; @@ -76,7 +86,9 @@ function permutation_parity(A) { // again, there is a linearithmic algorithm to count inversions, but >lazy for (let i = 0; i < n - 1; i++) { for (let j = i; j < n; j++) { - if (A[i] > A[j]) parity ^= 1; + if (A[i] > A[j]) { + parity ^= 1; + } } } return parity; @@ -94,11 +106,16 @@ function index_to_evenpermutation(ind, n) { perm[n - 1] = 0; for (let i = n - 2; i >= 0; i--) { for (let j = i + 1; j < n; j++) { - if (perm[j] >= perm[i]) perm[j]++; - else parity ^= 1; + if (perm[j] >= perm[i]) { + perm[j]++; + } else { + parity ^= 1; + } } } - if (parity === 1) [perm[n - 2], perm[n - 1]] = [perm[n - 1], perm[n - 2]]; + if (parity === 1) { + [perm[n - 2], perm[n - 1]] = [perm[n - 1], perm[n - 2]]; + } return perm; } @@ -109,9 +126,13 @@ function evenpermutation_to_index(perm) { function comb_to_index(l) { let bits = l.length; let ones = 0; - for (let i = 0; i < bits; i++) ones += +(l[i] === 1); + for (let i = 0; i < bits; i++) { + ones += +(l[i] === 1); + } let zeros = bits - ones; - if (zeros === 0 || ones === 0 || bits === 1) return 0; + if (zeros === 0 || ones === 0 || bits === 1) { + return 0; + } let b = C(bits - 1, ones); let ind = 0; for (let i = 0; zeros > 0 && ones > 0 && bits > 1; i++) { @@ -149,13 +170,17 @@ function index_to_comb(ind, ones, bits) { function compose(A, B) { let C = []; - for (let i = 0; i < B.length; i++) C[i] = A[B[i]]; + for (let i = 0; i < B.length; i++) { + C[i] = A[B[i]]; + } return C; } function permutation_from_cycle(cycle, n) { let perm = []; - for (let i = 0; i < n; i++) perm[i] = i; + for (let i = 0; i < n; i++) { + perm[i] = i; + } for (let i = 0; i < cycle.length; i++) { perm[cycle[i]] = cycle[(i + 1) % cycle.length]; } @@ -164,13 +189,17 @@ function permutation_from_cycle(cycle, n) { function unsparsify_list(d, n) { let l = Array(n).fill(0); - for (let k in d) l[k] = d[k]; + for (let k in d) { + l[k] = d[k]; + } return l; } function compose_state(state1, state2) { let o = Array(8).fill(0); - for (let i = 0; i < 8; i++) o[i] = (state1[1][i] + state2[1][i]) % 3; + for (let i = 0; i < 8; i++) { + o[i] = (state1[1][i] + state2[1][i]) % 3; + } return [compose(state1[0], state2[0]), o]; } @@ -215,7 +244,9 @@ let tetrad = [0, 1, 0, 1, 1, 0, 1, 0]; function apply_move_sequence(state, move_sequence) { for (let [m, r] of move_sequence) { - for (let i = 0; i < r; i++) state = compose_state(state, moves[m]); + for (let i = 0; i < r; i++) { + state = compose_state(state, moves[m]); + } } return state; } @@ -236,7 +267,9 @@ function generate_random_state(randomUintBelow) { 12, ); let o = Array(8); - for (let i = 0; i < 8; i++) o[i] = randomUintBelow(3); + for (let i = 0; i < 8; i++) { + o[i] = randomUintBelow(3); + } return [p, o]; } @@ -275,16 +308,21 @@ function solve(state) { let { value: sol1, done } = phase1gen.next(); let new_state = state; for (let [m, r] of sol1) { - for (let i = 0; i < r; i++) + for (let i = 0; i < r; i++) { new_state = compose_state(new_state, moves[m]); + } } if (intermediate_states.has(new_state.toString())) { // console.log("skip"); continue; - } else intermediate_states.add(new_state.toString()); + } else { + intermediate_states.add(new_state.toString()); + } let edge_ind = evenpermutation_to_index(new_state[0].slice(0, 8)); let corner_ind = 0; - for (let i = 0; i < 4; i++) corner_ind += new_state[1][i] * 3 ** i; + for (let i = 0; i < 4; i++) { + corner_ind += new_state[1][i] * 3 ** i; + } let phase2_indices = [edge_ind, corner_ind]; //let sol2 = []; let moves_left = best ? best.length - sol1.length - 1 : 999999; @@ -307,16 +345,22 @@ function solve(state) { best = sol1.concat(sol2); } // bail if we've spent too much time - if (new Date() - start_time > 300) break; + if (new Date() - start_time > 300) { + break; + } } return best; } function index_phase1(state) { let edge_ind = 0; - for (let i = 0; i < 4; i++) edge_ind += state[0].indexOf(i + 8) * 12 ** i; + for (let i = 0; i < 4; i++) { + edge_ind += state[0].indexOf(i + 8) * 12 ** i; + } let corner_ind = 0; - for (let i = 0; i < 4; i++) corner_ind += state[1][i + 4] * 3 ** i; + for (let i = 0; i < 4; i++) { + corner_ind += state[1][i + 4] * 3 ** i; + } let filtered = state[0].map((x) => Math.max(-1, x - 8)); let separate_ind = comb_to_index(filtered.map((x) => +(x >= 0))) * 2 + @@ -327,7 +371,9 @@ function index_phase1(state) { let tables = {}; function generate_phase1_corner_mtable() { - if (tables.phase1cm) return tables.phase1cm; + if (tables.phase1cm) { + return tables.phase1cm; + } let mtable = []; for (let i = 0; i < 81; i++) { mtable[i] = Array(8); @@ -348,7 +394,9 @@ function generate_phase1_corner_mtable() { } function generate_phase1_corner_ptable() { - if (tables.phase1cp) return tables.phase1cp; + if (tables.phase1cp) { + return tables.phase1cp; + } let ptable = Array(81); for (let i = 0; i < 81; i++) { let o = [ @@ -363,7 +411,9 @@ function generate_phase1_corner_ptable() { } function generate_phase1_edge_mtable() { - if (tables.phase1em) return tables.phase1em; + if (tables.phase1em) { + return tables.phase1em; + } let mtable_single = []; for (let i = 0; i < 12; i++) { mtable_single[i] = []; @@ -386,14 +436,18 @@ function generate_phase1_edge_mtable() { } function generate_phase1_edge_ptable() { - if (tables.phase1ep) return tables.phase1ep; + if (tables.phase1ep) { + return tables.phase1ep; + } return (tables.phase1ep = bfs(generate_phase1_edge_mtable(), [ 8 + 12 * (9 + 12 * (10 + 12 * 11)), ])); } function generate_phase1_separate_mtable() { - if (tables.phase1sm) return tables.phase1sm; + if (tables.phase1sm) { + return tables.phase1sm; + } const C12_4 = C(12, 4); let mtable_c = []; for (let i = 0; i < C12_4; i++) { @@ -401,8 +455,11 @@ function generate_phase1_separate_mtable() { let comb = index_to_comb(i, 4, 12), perm = []; for (let j = 0, k = 0; j < 12; j++) { - if (comb[j] === 0) perm[j] = -1; - else perm[j] = k++; + if (comb[j] === 0) { + perm[j] = -1; + } else { + perm[j] = k++; + } } for (let m = 0; m < 8; m++) { let new_perm = compose(perm, moves[m][0]); @@ -427,12 +484,16 @@ function generate_phase1_separate_mtable() { } function generate_phase1_separate_ptable() { - if (tables.phase1sp) return tables.phase1sp; + if (tables.phase1sp) { + return tables.phase1sp; + } return (tables.phase1sp = bfs(generate_phase1_separate_mtable(), [0])); } function generate_phase2_corner_mtable() { - if (tables.phase2cm) return tables.phase2cm; + if (tables.phase2cm) { + return tables.phase2cm; + } let phase1_mtable = generate_phase1_corner_mtable(); let mtable = Array(81); for (let i = 0; i < 81; i++) { @@ -442,7 +503,9 @@ function generate_phase2_corner_mtable() { } function generate_phase2_edge_mtable() { - if (tables.phase2em) return tables.phase2em; + if (tables.phase2em) { + return tables.phase2em; + } const n = 8; const HALFFACT8 = factorial(n) / 2; let mtable = Array(HALFFACT8); @@ -455,14 +518,22 @@ function generate_phase2_edge_mtable() { mtable[i][m] = evenpermutation_to_index(new_perm); } - if (i === HALFFACT8 - 1) break; + if (i === HALFFACT8 - 1) { + break; + } // update perm to lex-next even permutation let parity = 0; do { for (let k = n - 2; k >= 0; k--) { - if (perm[k] > perm[k + 1]) continue; + if (perm[k] > perm[k + 1]) { + continue; + } let l = k + 1; - for (let L = l; L < n; L++) if (perm[L] > perm[k]) l = L; + for (let L = l; L < n; L++) { + if (perm[L] > perm[k]) { + l = L; + } + } [perm[k], perm[l]] = [perm[l], perm[k]]; parity ^= 1; for (let j = 0; k + 1 + j < n - 1 - j; j++, parity ^= 1) { @@ -479,7 +550,9 @@ function generate_phase2_edge_mtable() { } function generate_phase2_edge_ptable() { - if (tables.phase2ep) return tables.phase2ep; + if (tables.phase2ep) { + return tables.phase2ep; + } return (tables.phase2ep = bfs(generate_phase2_edge_mtable(), [0])); } @@ -493,7 +566,9 @@ function bfs(mtable, goal_states) { while (queue.length > 0) { new_queue.length = 0; for (let state of queue) { - if (ptable[state] !== -1) continue; + if (ptable[state] !== -1) { + continue; + } ptable[state] = depth; for (let move_index = 0; move_index < nmoves; move_index++) { let new_state = mtable[state][move_index]; @@ -513,11 +588,14 @@ function ida_solve(indices, mtables, ptables, max_bound) { max_bound = max_bound || 999999; let ncoords = indices.length; let bound = 0; - for (let i = 0; i < ncoords; i++) + for (let i = 0; i < ncoords; i++) { bound = Math.max(bound, ptables[i][indices[i]]); + } while (bound <= max_bound) { let path = ida_search(indices, mtables, ptables, bound, -1); - if (path !== undefined) return path; + if (path !== undefined) { + return path; + } bound++; } } @@ -526,21 +604,35 @@ function ida_search(indices, mtables, ptables, bound, last) { let ncoords = indices.length; let nmoves = mtables[0][0].length; let heuristic = 0; - for (let i = 0; i < ncoords; i++) + for (let i = 0; i < ncoords; i++) { heuristic = Math.max(heuristic, ptables[i][indices[i]]); - if (heuristic > bound) return; - if (bound === 0) return []; - if (heuristic === 0 && bound === 1) return; + } + if (heuristic > bound) { + return; + } + if (bound === 0) { + return []; + } + if (heuristic === 0 && bound === 1) { + return; + } for (let m = 0; m < nmoves; m++) { - if (m === last) continue; - if (m < last && tetrad[m] === tetrad[last]) continue; + if (m === last) { + continue; + } + if (m < last && tetrad[m] === tetrad[last]) { + continue; + } let new_indices = indices.slice(); - for (let c = 0; c < ncoords; c++) + for (let c = 0; c < ncoords; c++) { new_indices[c] = mtables[c][indices[c]][m]; + } let r = 1; while (indices.some((_, i) => indices[i] !== new_indices[i])) { let subpath = ida_search(new_indices, mtables, ptables, bound - 1, m); - if (subpath !== undefined) return [[m, r]].concat(subpath); + if (subpath !== undefined) { + return [[m, r]].concat(subpath); + } for (let c = 0; c < ncoords; c++) { new_indices[c] = mtables[c][new_indices[c]][m]; } @@ -553,8 +645,9 @@ function ida_search(indices, mtables, ptables, bound, last) { function* ida_solve_gen(indices, mtables, ptables) { let ncoords = indices.length; let bound = 0; - for (let i = 0; i < ncoords; i++) + for (let i = 0; i < ncoords; i++) { bound = Math.max(bound, ptables[i][indices[i]]); + } while (true) { yield* ida_search_gen(indices, mtables, ptables, bound, -1); bound++; @@ -565,20 +658,30 @@ function* ida_search_gen(indices, mtables, ptables, bound, last) { let ncoords = indices.length; let nmoves = mtables[0][0].length; let heuristic = 0; - for (let i = 0; i < ncoords; i++) + for (let i = 0; i < ncoords; i++) { heuristic = Math.max(heuristic, ptables[i][indices[i]]); - if (heuristic > bound) return; + } + if (heuristic > bound) { + return; + } if (bound === 0) { yield []; return; } - if (heuristic === 0 && bound === 1) return; + if (heuristic === 0 && bound === 1) { + return; + } for (let m = 0; m < nmoves; m++) { - if (m === last) continue; - if (m < last && tetrad[m] === tetrad[last]) continue; + if (m === last) { + continue; + } + if (m < last && tetrad[m] === tetrad[last]) { + continue; + } let new_indices = indices.slice(); - for (let c = 0; c < ncoords; c++) + for (let c = 0; c < ncoords; c++) { new_indices[c] = mtables[c][indices[c]][m]; + } let r = 1; while (indices.some((_, i) => indices[i] !== new_indices[i])) { let subpath_gen = ida_search_gen( @@ -590,7 +693,9 @@ function* ida_search_gen(indices, mtables, ptables, bound, last) { ); while (true) { let { value: subpath, done } = subpath_gen.next(); - if (done) break; + if (done) { + break; + } yield [[m, r]].concat(subpath); } for (let c = 0; c < ncoords; c++) {