[Question]
  [
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](https://i.stack.imgur.com/3UUqp.jpg)](https://i.stack.imgur.com/3UUqp.jpg)
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 [code-golf](/questions/tagged/code-golf "show questions tagged 'code-golf'"), 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.
  
[Answer]
# [Python 3](https://docs.python.org/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](https://codegolf.stackexchange.com/users/66418/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!](https://tio.run/##pVZfS@NAEH/ufoolUNxNt2fTe8u5gv@gWh/6JOK6SGpTG6lpbFptEe8zeIc9QRAEQfBr9Yt4s0mTNm2iPa@km53ZHzO/nZnNjjfstTru9/fTTsPGHHc1TUPoxOs6bg/E4I0adjOckQE1Ue6s3albbVxDuRpABgB3XK@v4MEbRVLbuqg3LBNfvW9w2@1f2F2rZ6Ndtse18ehuPPqloU3etdwzG@3ztu2iKi8a6IgbrIQOeYkZaItXYX4A8yra4aE9bLE680xCCEyo4@IG1feJRzmv6C2qe7jTxRfWgIgdclmw2HUB0AURzamkTQBcsmsgi4fCkqIunebPIokRoPeoXmytg7BeXQP1WkUWhJCSogEPNkfoN99rOz2iHbsaRS2@TwaiJOnqahlVlBDMhlyImy12xA7Y4a3y6iifm6RFpZLOQ6lCJWpwIZE9sE/JSqPABcn7zAl4OsxSqA0wn/elMEyzLKnTxLtrljx2Q0R/ijDhAYB5DFFRdhxWolIne2t9xa6gFK2iEamqkgIwoBKGY4P0k0aw09Tyvsb5tTkUjhTnsshv8v7tD5AKitC5GkPdsbuil/OkxPRDpmmszKpsjx0q6YBVigaISmWotV2IiX7EtihFYVmpfO0QfZuJ7TA/2zhILH2PCjGsyLi0wopDQbH2bL93cmr5tg8LQunGo/ugwOLnbTx6QFBw4z@/8eQPktLgGIUnmhSM@mWtPo5Hr0lnT8CApdKIn3kyKc4mDl@SiGB8ThB/jXYI48uM3cRsYjkeZywv4qL/LDIreFnBSQQoNQZpYXqbCeZbMn9zY2peFyngzCBH1Ke/rLAsY@sxrqHJXiYWZwvgZS6d6V5md/OMpiwjT/fTal3gjJewPmsTJ@KQnsTs3X9m6SuskhF7SMQWf1y6S2Z8gfM/20sev6e5nd9nfk0@z/eUabT/tMrKyvzCEf0gY8n3MrW0DN@7BHf8XzX6nNhtxglAS1ZASp09zkfzE74feUo/qV89V4mP5uzdsjhPHdWHVSKkrtErdY1O70dhFg0JDVzQaaiGj6JceAHXYNaGdqUErYG6jD1hBD2KpwzUaMGgcf8SNGwBqEYBD0sS5cJOpKXW404P1sFXri1aAJMwGlKqHjHyqbcZ9m2Phz3UREnf/wI)
[Answer]
# [APL (Dyalog Classic)](https://www.dyalog.com/), 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!](https://tio.run/##jVRRa9pQFH7Pr7hwH0wwGpVBwRn7UnwY0qe@SYQQgyjFDqXCKB2jG04zU9o1XfswxuY2JqOwh7XsZWOg/@T8EXdOEs1NtGWKeM893/3O951zE/PpfqbxzNw/aGasfbPXa1kLOL1sHcDgLCfB8HVl0cLlLri3bfwH92c@3cHF/ErbpXjsFOa/wJ1i3qT49BLevLJpNTgH56WqHcnq8xTXUzB0EGbWZHDvYPwHiQoKDK/Ts2lhfoXRbhoTOm0biqYWVK2GsUEU/kLrsBbrHM@mhJC6WODIZk1m@ZrusGYDV2mtjZRZHWs1fRnjvyRtcCbD6KNm1WwDS34rlGE81BoYIaYDo08wmjSLTXC/tzWEN/Q87ueCfbuYw4BOOFojvSPUUIPUIW6psx95tEuubRT7lsA7SP/YCHpxEYgglE88IfnYWlumooeKbGXkDMo7NJT5laVbNXSN62IX4QQjn8e2nKMaSlsya/l02DMDiVJsexu8Mf5egHcG3g2uPPBOwHsP3jV4t@B9Ae93qlYA56uMHDI4Jy1FnU1n0yNw3qEbcEfgfqY@OpMOSvL9XNCU4rlW0P9HCg1zcNFFKIK6hmQuUCfdFnK2JzF/PihxNOn5A/pQxBxyqFi6R67wmqDyFC3xnrh3x@De0PlFRdqTKjp@6lsSzzL8cokzjBkXYvpEcbVPB55I0uqwvhUDcwSXKPJjHsaEKPtxjIyO90WyekTHQgImUHCfpEoKVzQBMYvpjsQsy/FVwXpSf7IkE1wsS6JMPFgSqCL6krDHV3s8ZoHFpFXDupGMelKIWEL0sHRb1iO//H/xgoFNeEEeTbm/1qekxKhfbI1GzMVHI@Yow1a9Fsf5EOeG0d6TY2s9T17f@nKzX49bi65wKCS8Fjy7GqQw4vC5Weu@aOl@W4mrF7amtHxQsvwezEM8S9URT6SaS2W/8QGimhgPX6uVeAtkNzyhrBKOcnN/RNXCo7CmuRrq2uQreF343/DF8Q8 "APL (Dyalog Classic) – Try It Online")
Input uses `=#F7LJ<>^v.` instead of `═║╔╗╚╝╣╠╩╦▒` in order to fit in the [classic charset](https://codegolf.meta.stackexchange.com/questions/9428/when-can-apl-characters-be-counted-as-1-byte-each/).
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.
[Answer]
# 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>
```
]