Solve this Alcazar for me

39

6

Recently I've been playing a game called Alcazar. It is a board puzzle game where your goal is to enter from one door, pass through all squares, and exit through another door. The only rules are:

  • Enter once, leave once;
  • Pass through all squares;
  • Do not pass through a square more than once

The image below shows an example of an Alcazar board and, at its right, the solved puzzle (of course this is an easy one):

Sample Alcazar Puzzle

You can find more puzzles at http://www.theincrediblecompany.com/try-alcazar and download the game at PlayStore (P.S.: Not an advertisement).

My problem is that I almost finished the game, except for one level. I simply cannot find a way to solve it. So the challenge I propose is: create an algorithm that solves any normal1 solvable2 Alcazar level.

Of course, I'm not asking for anyone to build an image interpreter to read the image and solve the puzzle (or am I?). So I redrew the above puzzle using box drawing characters. The puzzle and its solution would be like this:

╔═══════╗         ╔═══════╗
║▒ ▒ ▒ ▒║         ║┌─┐ ┌─┐║
║     ║ ║         ║│ │ │║│║
╣▒ ▒ ▒║▒╠         ╣│ └─┘║└╠
║ ══╦═╩═╣         ║│══╦═╩═╣
║▒ ▒║▒ ▒║         ║└─┐║┌─┐║
║   ║   ║   ==>   ║  │║│ │║
╣▒ ▒║▒ ▒║         ╣┐ │║│ │║
║ ║ ║   ║         ║│║│║│ │║
╣▒║▒ ▒ ▒║         ╣│║└─┘ │║
║ ║     ║         ║│║    │║
║▒ ▒ ▒ ▒║         ║└─────┘║
╚═══════╝         ╚═══════╝

In the board above, are the cells to be filled.

One can observe that there is a vertical and horizontal gab between the cells. This is because I had to insert a space between cells to add the walls. This means that the only important cells are the ones above, below, to the left, and to the right of each cell. The diagonals could be removed without information loss. For example, in the board below, both represent the same puzzle:

╔════╩╗         ═ ═ ╩ 
║▒ ▒ ▒║        ║▒ ▒ ▒║
║ ═══ ║           ═   
║▒ ▒ ▒║   ==   ║▒ ▒ ▒║
║     ║               
║▒ ▒ ▒║        ║▒ ▒ ▒║
╚╦════╝         ╦═ ══ 

This is also valid for the solutions. That is, it is not required to connect the cells:

╔════╩╗        ╔════╩╗        ╔════╩╗
║▒ ▒ ▒║        ║┌───┘║        ║┌ ─ ┘║
║ ═══ ║        ║│═══ ║        ║ ═══ ║
║▒ ▒ ▒║   ==   ║└───┐║   =>   ║└ ─ ┐║
║     ║        ║    │║        ║     ║
║▒ ▒ ▒║        ║┌───┘║        ║┌ ─ ┘║
╚╦════╝        ╚╦════╝        ╚╦════╝

In the example above, both solutions mean the same.

Yes, the test cases. Here they are:

Puzzle 1

╔════╩╗        ╔════╩╗
║▒ ▒ ▒║        ║┌ ─ ┘║
║ ═══ ║        ║ ═══ ║
║▒ ▒ ▒║   =>   ║└ ─ ┐║
║     ║        ║     ║
║▒ ▒ ▒║        ║┌ ─ ┘║
╚╦════╝        ╚╦════╝

Puzzle 2

╔═════╗        ╔═════╗
║▒ ▒ ▒║        ║┌ ─ ┐║
║   ║ ║        ║   ║ ║
╣▒ ▒║▒║        ╣└ ┐║│║
║ ║ ║ ║   =>   ║ ║ ║ ║
╣▒║▒ ▒╠        ╣┐║│ │╠
║ ║   ║        ║ ║   ║
║▒ ▒ ▒║        ║└ ┘ │║
╚════╦╝        ╚════╦╝

Puzzle 3

╔════╩══╗        ╔════╩══╗
║▒ ▒ ▒ ▒║        ║┌ ┐ └ ┐║
║ ║   ║ ║        ║ ║   ║ ║
╣▒║▒ ▒║▒╠        ╣┘║└ ┐║│╠
║ ╚══ ║ ║        ║ ╚══ ║ ║
║▒ ▒ ▒ ▒╠   =>   ║┌ ─ ┘ │╠
║   ═══ ║        ║   ═══ ║
║▒ ▒ ▒ ▒║        ║│ ┌ ┐ │║
║   ║   ║        ║   ║   ║
║▒ ▒║▒ ▒║        ║└ ┘║└ ┘║
╚═══╩═══╝        ╚═══╩═══╝

puzzle 4

╔═══════╗        ╔═══════╗
║▒ ▒ ▒ ▒║        ║┌ ┐ ┌ ┐║
║     ║ ║        ║     ║ ║
╣▒ ▒ ▒║▒╠        ╣│ └ ┘║└╠
║ ══╦═╩═╣        ║ ══╦═╩═╣
║▒ ▒║▒ ▒║        ║└ ┐║┌ ┐║
║   ║   ║   =>   ║   ║   ║
╣▒ ▒║▒ ▒║        ╣┐ │║│ │║
║ ║ ║   ║        ║ ║ ║   ║
╣▒║▒ ▒ ▒║        ╣│║└ ┘ │║
║ ║     ║        ║ ║     ║
║▒ ▒ ▒ ▒║        ║└ ─ ─ ┘║
╚═══════╝        ╚═══════╝

Puzzle 5

╔══╩══════╗        ╔══╩══════╗
║▒ ▒ ▒ ▒ ▒║        ║┌ ─ ┐ ┌ ┐║
║   ║     ║        ║   ║     ║
║▒ ▒║▒ ▒ ▒╠        ║└ ┐║└ ┘ │╠
║   ╠════ ║        ║   ╠════ ║
║▒ ▒║▒ ▒ ▒║   =>   ║┌ ┘║┌ ─ ┘║
║   ║     ║        ║   ║     ║
║▒ ▒║▒ ▒ ▒╠        ║└ ┐║└ ─ ─╠
║   ╠═════╣        ║   ╠═════╣
║▒ ▒║▒ ▒ ▒║        ║┌ ┘║┌ ─ ┐║
║   ║     ║        ║   ║     ║
║▒ ▒ ▒ ▒ ▒║        ║└ ─ ┘ ┌ ┘║
╚══╦═══╦══╝        ╚══╦═══╦══╝

Puzzle 6

╔═══════════╗        ╔═══════════╗
║▒ ▒ ▒ ▒ ▒ ▒║        ║┌ ┐ ┌ ┐ ┌ ┐║
║           ║        ║           ║
║▒ ▒ ▒ ▒ ▒ ▒║        ║│ └ ┘ └ ┘ │║
║       ═══ ║        ║       ═══ ║
║▒ ▒ ▒ ▒ ▒ ▒║        ║└ ┐ ┌ ─ ─ ┘║
║     ═══   ║        ║     ═══   ║
╣▒ ▒ ▒ ▒ ▒ ▒╠   =>   ╣┐ │ │ ┌ ┐ ┌╠
║           ║        ║           ║
║▒ ▒ ▒ ▒ ▒ ▒║        ║│ │ │ │ │ │║
║   ║   ║   ║        ║   ║   ║   ║
║▒ ▒║▒ ▒║▒ ▒║        ║│ │║│ │║│ │║
║   ║   ║   ║        ║   ║   ║   ║
║▒ ▒ ▒ ▒ ▒ ▒║        ║└ ┘ └ ┘ └ ┘║
╚═══════════╝        ╚═══════════╝

Puzzle 7

╔════╩════════╦╩╗        ╔════╩════════╦╩╗
║▒ ▒ ▒ ▒ ▒ ▒ ▒║▒║        ║┌ ─ ─ ─ ─ ─ ┐║│║
║ ║       ║   ║ ║        ║ ║       ║   ║ ║
║▒║▒ ▒ ▒ ▒║▒ ▒ ▒║        ║│║┌ ─ ─ ┐║┌ ┘ │║
║ ║ ║ ═══ ║     ║        ║ ║ ║ ═══ ║     ║
║▒ ▒║▒ ▒ ▒ ▒ ▒ ▒╠        ║│ │║┌ ─ ┘ └ ┐ │╠
║   ║           ║        ║   ║           ║
║▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒║        ║│ │ └ ┐ ┌ ┐ └ ┘║
║     ║ ║     ══╣        ║     ║ ║     ══╣
║▒ ▒ ▒║▒║▒ ▒ ▒ ▒║        ║│ └ ┐║│║│ └ ─ ┐║
║     ║ ║       ║        ║     ║ ║       ║
║▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒║        ║│ ┌ ┘ │ └ ┐ ┌ ┘║
║           ║ ══╣   =>   ║           ║ ══╣
║▒ ▒ ▒ ▒ ▒ ▒║▒ ▒║        ║└ ┘ ┌ ┘ ┌ ┘║└ ┐║
╠══       ║ ╚══ ║        ╠══       ║ ╚══ ║
║▒ ▒ ▒ ▒ ▒║▒ ▒ ▒║        ║┌ ┐ └ ┐ │║┌ ─ ┘║
║     ║ ║ ║     ║        ║     ║ ║ ║     ║
║▒ ▒ ▒║▒║▒ ▒ ▒ ▒║        ║│ └ ┐║│║│ └ ─ ┐║
║ ║   ║ ║ ╔══   ║        ║ ║   ║ ║ ╔══   ║
║▒║▒ ▒ ▒ ▒║▒ ▒ ▒║        ║│║┌ ┘ │ │║┌ ┐ │║
║ ║     ║ ║     ║        ║ ║     ║ ║     ║
║▒ ▒ ▒ ▒║▒ ▒ ▒ ▒║        ║│ └ ─ ┘║└ ┘ │ │║
║       ╚══     ║        ║       ╚══     ║
║▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒║        ║└ ─ ─ ─ ─ ─ ┘ │║
╚════╦═╦═╦═════╦╝        ╚════╦═╦═╦═════╦╝

Puzzle 8 (Sorry, I really don't have the solution to this one)

╔══╩╦══╩═══╩═╩═╩═══╩╗
║▒ ▒║▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒║
║   ║               ║
╣▒ ▒║▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒║
║   ╚══ ╔══     ╔═══╣
╣▒ ▒ ▒ ▒║▒ ▒ ▒ ▒║▒ ▒╠
║       ║   ╔══ ║   ║
╣▒ ▒ ▒ ▒ ▒ ▒║▒ ▒ ▒ ▒╠
║           ║       ║
║▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒╠
║           ║       ║
╣▒ ▒ ▒ ▒ ▒ ▒║▒ ▒ ▒ ▒╠
║   ╔═══╗   ╚══     ║
╣▒ ▒║▒ ▒║▒ ▒ ▒ ▒ ▒ ▒║
║   ║   ║           ║
╣▒ ▒║▒ ▒║▒ ▒ ▒ ▒ ▒ ▒╠
║ ══╝   ║       ╔══ ║
║▒ ▒ ▒ ▒║▒ ▒ ▒ ▒║▒ ▒║
║   ══╗ ╚══ ╔══ ║   ║
╣▒ ▒ ▒║▒ ▒ ▒║▒ ▒ ▒ ▒╠
║     ║     ║   ║   ║
╣▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒║▒ ▒║
║   ═══   ══╗   ║   ║
╣▒ ▒ ▒ ▒ ▒ ▒║▒ ▒ ▒ ▒╠
╠══ ║       ║   ╔══ ║
║▒ ▒║▒ ▒ ▒ ▒ ▒ ▒║▒ ▒╠
║   ╚══ ║   ║   ║   ║
╣▒ ▒ ▒ ▒║▒ ▒║▒ ▒ ▒ ▒╠
║       ║   ║       ║
║▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒ ▒║
╚══╦═══╦═══╦═╦═╦═╦═╦╝

Input

The input of your code can have any representation as long as it follow these rules:

  1. It must be a graphical input. So it is not possible to read a coordinate list, for example.

  2. Horizontal walls, vertical walls, and doors must be distinct, and they must be made of a visible character (no blank characters).

  3. The can be replaced by blanks. I just used a different character to highlight them.

Output

The output can also have any representation as long as it follows these rules:

  1. It must be a graphical output. That is, one can see the path by looking at it.

  2. Rule number one implies that the path characters be different. That is, there are going to be at least 6 path characters; horizontal, vertical, and corners.

  3. For the answer to be valid, the output must be the same board as the input (obviously) with all the cells (in my representation, the ) filled. Filling the gaps between the cells is optional.

Scoring

This is , so the shortest code in bytes wins.

1 There are some Alcazar levels that have optional cells and tunnels. These will not be considered.

2 There are some Alcazar boards that are impossible.

Phelype Oleinik

Posted 2017-09-11T23:23:57.200

Reputation: 1 110

2My program does not find a solution for puzzle 8. Are you sure it's solvable? Maybe some typo? – edc65 – 2017-09-17T18:33:27.263

1@edc65 same here - no solution for #8 – ngn – 2017-09-17T19:59:42.723

Answers

5

Python 3, 809 728 723 714 693 688 684 663 657 641 639 627 610 571 569 bytes

Edit: Saved 55 bytes thanks to @Felipe Nardi Batista

Does not run the last test case in 60 seconds on TIO, but should work correctly nonetheless. Returns a list of coordinates for the path. Some 400 of the bytes are used to get the data lists from the I/O.

A=enumerate
I,J="═║"
B=range
L=len
K=-1
Z=1,0
X=0,1
C=K,0
V=0,K
E=lambda a,b,p:(((a,b)in d)*L(p)==H*h)*p or max([E(q+a,w+b,p+[(q+a,w+b)])for q,w in y[a][b]if~-((q+a,w+b)in p)*-h>w+b>K<q+a<H]+[[]])
x=input().split("\n")
h=L(x[0])//2
H=L(x)//2
y=[[{C,Z,V,X}for i in B(h)]for j in B(H)]
d=[]
exec('d+=[(%s,i)for i,a in A(x[%s][1::2])if I<a]\nfor i,u in A(x[%s:%s:2]):\n d+=[(i,0)]*(J<u[0])+[(i,h-1)]*(J<u[K])\n for j,w in A(u[%s:%s:2]):\n  if"%s"==w:y[i][j]-={%s};y[i+%s][j+%s]-={%s}\n'*2%(0,*X,"",2,K,J,X,*X,V,H-1,K,2,K,1,"",I,Z,*Z,C))
print(max(E(*D,[D])for D in d))

Try it online!

Halvard Hummel

Posted 2017-09-11T23:23:57.200

Reputation: 3 131

@HalvardHummel Well, sorry for the bad formulation of the challenge. So I propose the following. The Score shall be calculated by multiplying the byte count by the run time, so both run time and byte count shall be rewarded. What do you think? – Phelype Oleinik – 2017-09-14T17:33:02.023

1@PhelypeOleinik I don't think that is a very good scoring system. Keeping it to coed golf is a better solution, but if you are really looking for a solution I'm sure that this can be modified to be more efficient. – caird coinheringaahing – 2017-09-14T20:13:59.297

@cairdcoinheringaahing I understand that the most elegant solution is to keep as it is. But an algorithm that takes "days or even months" to solve an 8x12 puzzle board is somehow inefficient, don't you think? The way I see it, an algorithm that solves the problem in less time should be rewarded, even if it is a little bit longer. – Phelype Oleinik – 2017-09-15T12:35:59.470

3@PhelypeOleinik The "efficiency" of the code is irrelevant. You have challenged us to write short code, and that is the basis of your challenge. Adding the speed at which the program runs to the mix only complicates things unnecessarily and can also be exploited for ridiculous scores. Custom scoring systems don't tend to work out. If you want short code, make a code-golf question. If you want fast code, make a fastest-code question. Trying to mix them together is not a good idea. – LyricLy – 2017-09-15T23:09:44.540

In your exec(...) string there are five new lines, represented as \n, 5*2 = 10 bytes. Using a triple-quoted string would add 4 bytes (...''...''...) but then remove 5 bytes, as actual new line characters could be used. In total this could save one byte. – Jonathan Frech – 2017-09-20T09:59:42.230

I think (((a,b)in d)*L(p)==H*h)*p or (28 bytes) is equivalent to p*(((a,b)in d)*L(p)==H*h)or (27 bytes). – Jonathan Frech – 2017-09-20T10:05:38.253

Congratulations for winning the bounty for the shortest Python answer! – HyperNeutrino – 2017-09-21T02:29:19.550

5

APL (Dyalog Classic), 319 bytes

i←N⍴j←⍳1+n←×/N←⌊2÷⍨⍴a←⎕⋄e←↑⊃,/{(,~'#='∊⍨a[(⍵⌽⍳2)∘+¨2×⍳N+⍵=⍳2])/,2,/[⍵]⊃,[⍵]/n i n}¨⍳2
r←{e g c←⍵⋄d←+/j∘.=∊g⋄e⌿⍨←(≠/c[e])∧2>⌈/d[e]⋄n≡≢g:g⍪j/⍨d=1⋄0≡≢e:0⋄2>⌊/d+D←+/j∘.=,e:0⋄u←,¯1↑e←e[⍒⌊/D[e];]⋄e↓⍨←¯1⋄0≢r←∇e(g⍪u)(c-(-/c[u])×c=c[⊃u]):r⋄∇e g c}e(0↑e)j
a[1+2×⍳N]←' ??┌?─┐┬?└│├┘┴┤┼'[2⊥(↑(⊂i),¨¨{⊖∘⍉⍣⍵⊢n⍪¯1↓⌽∘⍉⍣⍵⊢i}¨⍳4)∊↓r⍪⌽r]
a

Try it online!

Input uses =#F7LJ<>^v. instead of ═║╔╗╚╝╣╠╩╦▒ in order to fit in the classic charset.

All test cases except for the last one pass in a few seconds.

The last test takes 47 min on my computer and yields no solution.

When the resulting path uses a door near a corner it may be rendered incorrectly (it's as if the trail forks and passes through an extra imaginary door), but it's still discernable and unambiguous.

ngn

Posted 2017-09-11T23:23:57.200

Reputation: 11 449

Very good! If I may ask, what approach does your code use to solve? Exhaustive search or something more elegant? Also, as I said, I didn't solve the last puzzle by hand. It doesn't have a clear step-by-step solution and requires, even when solving by hand, a guesswork to find some answers. This puzzle is included in the original game, but it may not have a solution, so probably should not be taken into account. – Phelype Oleinik – 2017-09-18T11:19:26.950

1@PhelypeOleinik Yes, it's a rather unsophisticated exhastive search. The reason it finds existing solutions quickly is that it tries the more likely case first (with vs without a certain edge in the graph - my heuristic is the min of the degrees of the two vertices, lower is likelier). The reason it performs horribly in the last case is that it tests all possibilities anyway and prunes recursion only on obvious contradictions. There don't seem to be known good Hamiltonian-path algorithms, even for the special case of bounded-degree (≤4 neighbours) graphs. – ngn – 2017-09-18T14:50:27.453

3

JavaScript (ES6), 274 bytes

Input as a multiline string, each line terminated with a newline character. The doors are marked with character '2'

Output as a multiline string with the path marked by character '1', very easily discernable.

This is a Depth First Search, trying all paths and backtraking when stuck. It's not efficient at all, but can solve puzzles 1 .. 6 in a less than 1 minute.

z=>(w=z.search`
`+1,t=(w-2)*(z.length/w-1)/4,z=[...z],R=(p,l,q)=>[1,-1,w,-w].some(d=>l<t?z[q=p+d]<1&z[q+d]<1&&(R(q+d,++z[q]+l)||--z[q]):z[p+d]>1&&--z[p+d],++z[p])||--z[p],z.some((c,i)=>-c&&(x=i%w,R(i<w?i+w:x?x>w-3?i-1:i-w:i+1,--z[i])||++z[i]*0))&&z.join``.replace(/0/g,' '))

Less golfed

z => (
  w = z.search`\n`+1, // board width and offset to next row
  t = (w-2)*(z.length/w-1)/4, // total size of board, number of cells that must be filled
  z = [...z], // convert string to array
  d = [1, -1, w, -w], // delta to next position in all directions
  // recursive search
  // given a current position, try to move in all directions
  // if the board is not full, look for an emoty cell
  // if the board is full, look for a door
  R = (p, // current position
       l, // fill level
       q  // parameter used as a local variable
      ) => (
        ++z[p], // mark current position
        // .some will terminate early if the called function returns true
        // in case of return true the recursive function returns all way up leaving the path marked
        // in case of return false we need to unmark path and backtrack
        d.some( d => // for each direction, offset in d
          l < t // check if board is full
          ? z[q=p+d] < 1 & z[q+d] < 1 // not full, try to advance 
            && (++z[q], // mark intermediate cell
                R(q+d, 1+l) // recursive call incrementing fill level
                || --z[q] // if R return false, backtrack: unmark intermediate cell
               )
          : z[p+d] > 1 && --z[p+d]
        ) // full, ok only if I find a door nearby
        || --z[p], // if some returns false, unmark and backtrak
  // look for doors and for each door call R 
  // when R returns true, stop and return the marked board
  // if R returns false for each door, no solution, return false
  z.some((c,i) => 
   -c && // if numeric and != 0
    (x = i%w,
     z[i]=1, // marking starting position (door)
     R(i<w ? i+w : x ? x > w-3 ? i-1 : i-w : i+1, 1)
     || (z[i] = 2, false) // if R returned false, unmark a return false
    ) 
  ) && z.join``.replace(/0/g,' ') 
)

Inside the test snippet there is a solution using a DFS with some constraint that solves puzzle 7 in less than a minute (on my PC). Puzzle 8 has no solution. Constraints:

  • All empty cells must be reachable from the current cell - the empty space must not be split in two parts
  • There must be a reachable door
  • A configuration of cells cannot be explored more than one time
  • Cannot skip a cell that has only one empty adjacent cell

Test

Beware, puzzle 7 is well beyond the timeout for javascript execution in any browser (using the Short and Slow solver)

var Short=
z=>(w=z.search`
`+1,t=(w-2)*(z.length/w-1)/4,z=[...z],R=(p,l,q)=>[1,-1,w,-w].some(d=>l<t?z[q=p+d]<1&z[q+d]<1&&(R(q+d,++z[q]+l)||--z[q]):z[p+d]>1&&--z[p+d],++z[p])||--z[p],z.some((c,i)=>-c&&(x=i%w,R(i<w?i+w:x?x>w-3?i-1:i-w:i+1,--z[i])||++z[i]*0))&&z.join``.replace(/0/g,' '))

var Fast=
b=>{
N=0
console.clear()
    F=(b,p,n) => D.reduce((n,d) => b[p+d] < 1 && b[p+d+d] < 1? F(b, p+d+d, n) : n, n+1, b[p]=1)
    A=(s, f, o, q, k)=>{
        D.map(d => b[s[1] + d] == 2 && (++o, q = s[1] + d));

        ++b[s[0]];
        if (++f < t)
        {
            if (o < m && !K[k=b.reduce((k,c,i)=>c>3?k+' '+i:k,s[1])] && F(b.slice(), s[K[k] = 1], f) >= t
                && R(D.reduce((n,d) =>(b[s[1] + d] == 0 && b[s[1] + d + d ] == 0 && n.push([s[1] + d, s[1] + d + d ]),n),[]),f,o,b[s[1]]=4))
                return 1;
        }
        else
        {
            b[s[1]] = 4;
            if (q) return b[q]++;
        }
        --b[s[0]]
        b[s[1]]=0
    }

    R=(s, f, o)=>{
        if (!s[1]) return A(s[0], f, o);
        var e, n, z=[];
        if (s.some(s =>(
                n = D.reduce( (n,d) => b[s[1]+d]>1 || (b[s[1]+d]<1 && b[s[1]+d+d]<1) ? n+1 : n, 0),
                n>2 ? !z.push(s) 
                : n>1 ? !z.unshift(s) 
                : n>0 && (e||(e=s,0))
        ))) return 0
        if (e) return A(e, f, o);
        return z.some(s => A(s, f, o))
    }

    w = b.search`\n` + 1;
    h = b.length / w;
    t = (w - 2) * (h - 1) / 4;
    D = [ 1, -1, w, -w ];
    b = [...b];
    K = {};
    s = [];
    b.forEach( (c,i) => -c ?  
        m = s.push( [i,i < w ? i + w : (x = i % w) > w - 3 ? i - 1 : x ? i - w : i + 1]):0
    )
    R(s, 0, 0);
    return b.join``.replace(/\d/g, c => ' oXOo'[c])
}

Out=(e,s)=>e.textContent = s

function Test(num)
{  
  var puzzle = document.getElementById('Z'+num).textContent;
  var solver = MF.checked ? Fast : Short
  Out(S,'...wait...')
  Out(T,'');
  
  var t0=performance.now()
  setTimeout(_=>(
    Out(S,solver(puzzle)),Out(T,((performance.now()-t0)/1000).toFixed(3)+' sec')
  ),10)
}
td { border: 1px solid #000; font-family: helvetica; font-size:12px; vertical-align: top; }
pre { line-height: 13px; }
Short and slow <input type='radio' value='S' name='M' id='MS'>
Long and faster <input type='radio' checked value='F'name ='M' id='MF'>
<table >
<tr>
<td id=T>Solution</td>
<td>Puzzle 1<input type='radio' name='T' onclick="Test(1)"></td>
<td>Puzzle 2<input type='radio' name='T' onclick="Test(2)"></td>
<td>Puzzle 3<input type='radio' name='T' onclick="Test(3)"></td>
<td>Puzzle 4<input type='radio' name='T' onclick="Test(4)"></td>
<td>Puzzle 5<input type='radio' name='T' onclick="Test(5)"></td>
<td>Puzzle 6<input type='radio' name='T' onclick="Test(6)"></td>
<td>Puzzle 7<input type='radio' name='T' onclick="Test(7)"></td>
</tr>
<tr>
<td><pre id=S></pre></td>
<td><pre id='Z1'>╔════2╗
║     ║
║ ═══ ║
║     ║
║     ║
║     ║
╚2════╝
</pre></td>
<td><pre id='Z2'>╔═════╗
║     ║
║   ║ ║
2   ║ ║
║ ║ ║ ║
2 ║   2
║ ║   ║
║     ║
╚════2╝
</pre></td>
<td><pre id='Z3'>╔════2══╗
║       ║
║ ║   ║ ║
2 ║   ║ 2
║ ╚══ ║ ║
║       2
║   ═══ ║
║       ║
║   ║   ║
║   ║   ║
╚═══╩═══╝
</pre></td>
<td><pre id='Z4'>╔═══════╗
║       ║
║     ║ ║
2     ║ 2
║ ══╦═╩═╣
║   ║   ║
║   ║   ║
2   ║   ║
║ ║ ║   ║
2 ║     ║
║ ║     ║
║       ║
╚═══════╝
</pre></td>
<td><pre id='Z5'>╔══2══════╗
║         ║
║   ║     ║
║   ║     2
║   ╠════ ║
║   ║     ║
║   ║     ║
║   ║     2
║   ╠═════╣
║   ║     ║
║   ║     ║
║         ║
╚══2═══2══╝
</pre></td>
<td><pre id='Z6'>╔═══════════╗
║           ║
║           ║
║           ║
║       ═══ ║
║           ║
║     ═══   ║
2           2
║           ║
║           ║
║   ║   ║   ║
║   ║   ║   ║
║   ║   ║   ║
║           ║
╚═══════════╝
</pre></td>
<td><pre id='Z7'>╔════2════════╦2╗
║             ║ ║
║ ║       ║   ║ ║
║ ║       ║     ║
║ ║ ║ ═══ ║     ║
║   ║           2
║   ║           ║
║               ║
║     ║ ║     ══╣
║     ║ ║       ║
║     ║ ║       ║
║               ║
║           ║ ══╣
║           ║   ║
╠══       ║ ╚══ ║
║         ║     ║
║     ║ ║ ║     ║
║     ║ ║       ║
║ ║   ║ ║ ╔══   ║
║ ║       ║     ║
║ ║     ║ ║     ║
║       ║       ║
║       ╚══     ║
║               ║
╚════2═2═2═════2╝
</pre></td>
</tr>
</table>

edc65

Posted 2017-09-11T23:23:57.200

Reputation: 31 086