4 ms·
Solver in 0 clicks: [...document.querySelectorAll("#game > div > div")].forEach(e => e.style.transform="rotate(0deg)") It doesn't win the game, but can at
by bambax 4y ago
Solver in 0 clicks:
[...document.querySelectorAll("#game > div > div")].forEach(e => e.style.transform="rotate(0deg)")
It doesn't win the game, but can at least save the "preview" clicks.
- kidsil 4y agoJust wondering - why are you spreading the result to an array? document.querySelectorAll("#game > div > div").forEach(e => e.style.transform="rotate(0deg)") Works too.
- bambax 4y agoYou're right! (But since querySelectorAll returns a NodeList and not a regular array, some methods are unavailable, so I just have this habit of making it an array. But for iteration that's indeed not needed.)
- bambax 4y agoActual solver that does win the game: document.querySelectorAll("#game > div > div").forEach(e => { const rotation = e.style.transform.match(/(\d+)/)[0]; const clicks = 4-(rotation/90)%4; [...Array(clicks)].forEach(i=>e.click()); }); It could be optimized to change the rotation direction depending on whether the current rotation is smaller or larger than 180deg, but that's not really necessary since running the script only counts as one click, and generates negative "overspin" numbers ;-)
- prox 4y agoWhat does […Array mean in this context? Does it create an array?
- bambax 4y agoYes it creates an array of length 'clicks'; so for example [...Array(2)] creates the array [undefined, undefined]. It's just a way to do a loop without writing a for loop and use forEach instead.
- monkpit 4y agoProbably a shortcut for Array(n).fill()
- manbash 4y agoThe "..." is called a spread operator in javascript. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... (In python there is the "*" operator which should be equivalent: [1, 2, *arr]. Array(clicks) instantiate an array of length 'clicks', with its elements undefined. Then "[...Array(clicks)]" takes the above array instance and spreads it as content in another array. Seems redundant and they could've just used Array(clicks).
- tuukkah 4y ago> Array(clicks) instantiate an array of length 'clicks', with its elements undefined. Not undefined elements but no elements, or "empty" elements. > they could've just used Array(clicks). No, because the following forEach call does nothing for such an array. You need to fill the array first with Array(clicks).fill() or shorter, [...Array(clicks)]
- tuukkah 4y ago... is the spread syntax, which is a neat way to use the entries of an existing array or object in an argument list or within an array or object literal. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe... Array(length) creates an array that has a length but no elements (or weird, "empty" elements). The square brackets create a new array [...Array(length)] which will have undefined elements instead, as trying to access an "empty" element returns undefined. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Indexed_collections#sparse_arrays https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guid...
- prox 4y agoThat is neat! Thanks!
- mahathu 4y agoInstead of the array spread syntax, why not: for(let i=0; i<clicks; i++){ e.click() };
- bambax 4y agoSure, it's the same. For some reason I don't like the 'for' syntax much, or having curly brackets on the same line. But to each their own.
- eutectic 4y agoAn actual solver in Python: import numpy as np from mip import Model, xsum, minimize, BINARY def solve(tiles): rotations = [[[] for _ in row] for row in tiles] rot_vars = [[[] for _ in row] for row in tiles] model = Model("rotaboxes") for i, row in enumerate(tiles): for j, tile in enumerate(row): for _ in range(3): tile = tile.transpose((1, 0, 2))[::-1] rotations[i][j].append(tile) rot_vars[i][j].append(model.add_var(var_type=BINARY)) model += (xsum(rot_vars[i][j]) == 1) costs = [] for i, row in enumerate(tiles): for j, tile in enumerate(row): for (di, dj) in [(0, 1), (1, 0)]: if (i + di >= len(tiles)) or (j + dj >= len(tiles[0])): continue for r0, t0 in enumerate(rotations[i][j]): for r1, t1 in enumerate(rotations[i + di][j + dj]): if di: a, b = t0[-1], t1[0] else: a, b = t0[:,-1], t1[:,0] n = np.square(a - b).mean() d = np.square(a[1:] - a[:1]).mean() + np.square(b[1:] - b[:1]).mean() e = 2. * n / (d + 0.01) v = model.add_var(var_type=BINARY) model += (v >= rot_vars[i][j][r0] + rot_vars[i + di][j + dj][r1] - 1) costs.append(e * v) model.objective = minimize(xsum(costs)) model.optimize() solution = [[[r for v, r in zip(vs, rs) if v.x >= 0.99][0] for vs, rs in zip(row0, row1)] for row0, row1 in zip(rot_vars, rotations)] return solution
- ComodoHacker 4y agoNow you should count keystrokes for your type of solution.