Sudoku: Difference between revisions
Content deleted Content added
m →{{header|Phix}}: syntax coloured, made p2js compatible |
|||
Line 8,154: | Line 8,154: | ||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
Simple brute force solution. Generally quite good but will struggle on some puzzles (eg see "the beast" below) |
Simple brute force solution. Generally quite good but will struggle on some puzzles (eg see "the beast" below) |
||
<lang Phix> |
<!--<lang Phix>(phixonline)--> |
||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
|||
.......39 |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">board</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">split</span><span style="color: #0000FF;">(</span><span style="color: #008000;">""" |
|||
.....1..5 |
|||
.. |
.......39 |
||
.. |
.....1..5 |
||
. |
..3.5.8.. |
||
..8.9...6 |
|||
.. |
.7...2... |
||
. |
1..4..... |
||
..9.8..5. |
|||
.2....6.. |
|||
4..7....."""</span><span style="color: #0000FF;">,</span><span style="color: #008000;">'\n'</span><span style="color: #0000FF;">)</span> |
|||
function valid_move(integer y, integer x, integer ch) |
|||
for i=1 to 9 do |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">valid_move</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span> |
|||
if ch=board[i][x] then return 0 end if |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> |
|||
if ch=board[y][i] then return 0 end if |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">=</span><span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
end for |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">=</span><span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
y -= mod(y-1,3) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
x -= mod(x-1,3) |
|||
<span style="color: #000000;">y</span> <span style="color: #0000FF;">-=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span> |
|||
for ys=y to y+2 do |
|||
<span style="color: #000000;">x</span> <span style="color: #0000FF;">-=</span> <span style="color: #7060A8;">mod</span><span style="color: #0000FF;">(</span><span style="color: #000000;">x</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span> |
|||
for xs=x to x+2 do |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">ys</span><span style="color: #0000FF;">=</span><span style="color: #000000;">y</span> <span style="color: #008080;">to</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span> <span style="color: #008080;">do</span> |
|||
if ch=board[ys][xs] then return 0 end if |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">xs</span><span style="color: #0000FF;">=</span><span style="color: #000000;">x</span> <span style="color: #008080;">to</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span> <span style="color: #008080;">do</span> |
|||
end for |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">=</span><span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ys</span><span style="color: #0000FF;">][</span><span style="color: #000000;">xs</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
end for |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
return 1 |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end function |
|||
<span style="color: #008080;">return</span> <span style="color: #004600;">true</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
sequence solution = {} |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">solution</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> |
|||
procedure brute_solve() |
|||
for y=1 to 9 do |
|||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">brute_solve</span><span style="color: #0000FF;">()</span> |
|||
for x=1 to 9 do |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> |
|||
if board[y][x]<='0' then |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> |
|||
for ch='1' to '9' do |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">][</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]<=</span><span style="color: #008000;">'0'</span> <span style="color: #008080;">then</span> |
|||
if valid_move(y,x,ch) then |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'1'</span> <span style="color: #008080;">to</span> <span style="color: #008000;">'9'</span> <span style="color: #008080;">do</span> |
|||
board[y][x] = ch |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">valid_move</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">,</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
brute_solve() |
|||
<span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">][</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ch</span> |
|||
board[y][x] = ' ' |
|||
<span style="color: #000000;">brute_solve</span><span style="color: #0000FF;">()</span> |
|||
<span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">][</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">' '</span> |
|||
end if |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
end for |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
return |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end if |
|||
<span style="color: #008080;">return</span> |
|||
end for |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
end for |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
solution = board -- (already solved case) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end procedure |
|||
<span style="color: #000000;">solution</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (already solved case)</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
atom t0 = time() |
|||
brute_solve() |
|||
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span> |
|||
printf(1,"%s\n(solved in %3.2fs)\n",{join(solution,"\n"),time()-t0})</lang> |
|||
<span style="color: #000000;">brute_solve</span><span style="color: #0000FF;">()</span> |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s\n(solved in %3.2fs)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">),</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">})</span> |
|||
<!--</lang>--> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 8,221: | Line 8,224: | ||
contains 339 puzzles, can be run as a command-line or gui program, check for multiple solutions, and produce |
contains 339 puzzles, can be run as a command-line or gui program, check for multiple solutions, and produce |
||
a more readable single-puzzle output (example below). |
a more readable single-puzzle output (example below). |
||
<!--<lang Phix>(phixonline)--> |
|||
<lang Phix>-- Working directly on 81-character strings ultimately proves easier: Originally I |
|||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
|||
-- just wanted to simplify the final display, but later I realised that a 9x9 grid |
|||
<span style="color: #000080;font-style:italic;">-- Working directly on 81-character strings ultimately proves easier: Originally I |
|||
-- encourages laborious indexing/looping everwhere whereas using a flat 81-element |
|||
-- just wanted to simplify the final display, but later I realised that a 9x9 grid |
|||
-- approach encourages precomputation of index sets, and once you commit to that, |
|||
-- encourages laborious indexing/looping everwhere whereas using a flat 81-element |
|||
-- the rest of the code starts to get a whole lot cleaner. Below we create 27+18 |
|||
-- approach encourages precomputation of index sets, and once you commit to that, |
|||
-- sets and 5 tables of lookup indexes to locate them quickly. |
|||
-- the rest of the code starts to get a whole lot cleaner. Below we create 27+18 |
|||
-- sets and 5 tables of lookup indexes to locate them quickly.</span> |
|||
sequence nines = {}, -- will be 27 in total |
|||
cols = repeat(0,9*9), -- remainder(i-1,9)+1 |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">nines</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000080;font-style:italic;">-- will be 27 in total</span> |
|||
rows = repeat(0,9*9), -- floor((i-1)/9)+10 |
|||
<span style="color: #000000;">cols</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- remainder(i-1,9)+1</span> |
|||
squares = repeat(0,9*9), |
|||
<span style="color: #000000;">rows</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- floor((i-1)/9)+10</span> |
|||
sixes = {}, -- will be 18 in total |
|||
<span style="color: #000000;">squares</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">),</span> |
|||
dotcol = repeat(0,9*9), -- same col, diff square |
|||
<span style="color: #000000;">sixes</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{},</span> <span style="color: #000080;font-style:italic;">-- will be 18 in total</span> |
|||
dotrow = repeat(0,9*9) -- same row, diff square |
|||
<span style="color: #000000;">dotcol</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- same col, diff square</span> |
|||
<span style="color: #000000;">dotrow</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- same row, diff square</span> |
|||
procedure set_nines() |
|||
sequence nine, six |
|||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">set_nines</span><span style="color: #0000FF;">()</span> |
|||
integer idx, ndx |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">nine</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">six</span> |
|||
for x=0 to 8 do -- columns |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">idx</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ndx</span> |
|||
nine = {} |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- columns</span> |
|||
ndx = length(nines)+1 |
|||
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> |
|||
for y=1 to 81 by 9 do |
|||
<span style="color: #000000;">ndx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span> |
|||
idx = y+x |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">81</span> <span style="color: #008080;">by</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> |
|||
nine = append(nine,idx) |
|||
<span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">x</span> |
|||
cols[idx] = ndx |
|||
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">,</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">)</span> |
|||
end for |
|||
<span style="color: #000000;">cols</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ndx</span> |
|||
nines = append(nines,nine) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end for |
|||
<span style="color: #000000;">nines</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">)</span> |
|||
for y=1 to 81 by 9 do -- rows |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
nine = {} |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">81</span> <span style="color: #008080;">by</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- rows</span> |
|||
ndx = length(nines)+1 |
|||
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> |
|||
for x=0 to 8 do |
|||
<span style="color: #000000;">ndx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span> |
|||
idx = y+x |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span> |
|||
nine = append(nine,idx) |
|||
<span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">x</span> |
|||
rows[idx] = ndx |
|||
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">,</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">)</span> |
|||
end for |
|||
<span style="color: #000000;">rows</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ndx</span> |
|||
nines = append(nines,nine) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end for |
|||
<span style="color: #000000;">nines</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">)</span> |
|||
if length(nines)!=18 then ?9/0 end if |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
for y=0 to 8 by 3 do -- small squares [19..27] |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">18</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
for x=0 to 8 by 3 do |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">by</span> <span style="color: #000000;">3</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- small squares [19..27]</span> |
|||
nine = {} |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">by</span> <span style="color: #000000;">3</span> <span style="color: #008080;">do</span> |
|||
ndx = length(nines)+1 |
|||
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> |
|||
for sy=y*9 to y*9+18 by 9 do |
|||
<span style="color: #000000;">ndx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">)+</span><span style="color: #000000;">1</span> |
|||
for sx=x to x+2 do |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">sy</span><span style="color: #0000FF;">=</span><span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span> <span style="color: #008080;">to</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">+</span><span style="color: #000000;">18</span> <span style="color: #008080;">by</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> |
|||
idx = sy+sx+1 |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">sx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">x</span> <span style="color: #008080;">to</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span> <span style="color: #008080;">do</span> |
|||
nine = append(nine,idx) |
|||
<span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sy</span><span style="color: #0000FF;">+</span><span style="color: #000000;">sx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span> |
|||
squares[idx] = ndx |
|||
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">,</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">)</span> |
|||
end for |
|||
<span style="color: #000000;">squares</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ndx</span> |
|||
end for |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
nines = append(nines,nine) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end for |
|||
<span style="color: #000000;">nines</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">)</span> |
|||
end for |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
if length(nines)!=27 then ?9/0 end if |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
for i=1 to 9*9 do |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">27</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
six = {} |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span> <span style="color: #008080;">do</span> |
|||
nine = nines[cols[i]] -- dotcol |
|||
<span style="color: #000000;">six</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> |
|||
for j=1 to length(nine) do |
|||
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">cols</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]</span> <span style="color: #000080;font-style:italic;">-- dotcol</span> |
|||
if squares[i]!=squares[nine[j]] then |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
six = append(six,nine[j]) |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">squares</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">squares</span><span style="color: #0000FF;">[</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]]</span> <span style="color: #008080;">then</span> |
|||
end if |
|||
<span style="color: #000000;">six</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">six</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span> |
|||
end for |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
ndx = find(six,sixes) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
if ndx=0 then |
|||
<span style="color: #000000;">ndx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">six</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sixes</span><span style="color: #0000FF;">)</span> |
|||
sixes = append(sixes,six) |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">ndx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
ndx = length(sixes) |
|||
<span style="color: #000000;">sixes</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sixes</span><span style="color: #0000FF;">,</span><span style="color: #000000;">six</span><span style="color: #0000FF;">)</span> |
|||
end if |
|||
<span style="color: #000000;">ndx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sixes</span><span style="color: #0000FF;">)</span> |
|||
dotcol[i] = ndx |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
six = {} |
|||
<span style="color: #000000;">dotcol</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ndx</span> |
|||
nine = nines[rows[i]] -- dotrow |
|||
<span style="color: #000000;">six</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> |
|||
for j=1 to length(nine) do |
|||
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">rows</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]</span> <span style="color: #000080;font-style:italic;">-- dotrow</span> |
|||
if squares[i]!=squares[nine[j]] then |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
six = append(six,nine[j]) |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">squares</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]!=</span><span style="color: #000000;">squares</span><span style="color: #0000FF;">[</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]]</span> <span style="color: #008080;">then</span> |
|||
end if |
|||
<span style="color: #000000;">six</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">six</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nine</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">])</span> |
|||
end for |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
ndx = find(six,sixes) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
if ndx=0 then |
|||
<span style="color: #000000;">ndx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">six</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sixes</span><span style="color: #0000FF;">)</span> |
|||
sixes = append(sixes,six) |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">ndx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
ndx = length(sixes) |
|||
<span style="color: #000000;">sixes</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sixes</span><span style="color: #0000FF;">,</span><span style="color: #000000;">six</span><span style="color: #0000FF;">)</span> |
|||
end if |
|||
<span style="color: #000000;">ndx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sixes</span><span style="color: #0000FF;">)</span> |
|||
dotrow[i] = ndx |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
end for |
|||
<span style="color: #000000;">dotrow</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ndx</span> |
|||
end procedure |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
set_nines() |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
<span style="color: #000000;">set_nines</span><span style="color: #0000FF;">()</span> |
|||
integer improved = 0 |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">improved</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> |
|||
function eliminate_in(sequence valid, sequence set, integer ch) |
|||
for i=1 to length(set) do |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">eliminate_in</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">set</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span> |
|||
integer idx = set[i] |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">set</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
if string(valid[idx]) then |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">set</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
integer k = find(ch,valid[idx]) |
|||
<span style="color: #008080;">if</span> <span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span> |
|||
if k!=0 then |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">])</span> |
|||
valid[idx][k..k] = "" |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
improved = 1 |
|||
<span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">][</span><span style="color: #000000;">k</span><span style="color: #0000FF;">..</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span> |
|||
end if |
|||
<span style="color: #000000;">improved</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> |
|||
end if |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
end for |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
return valid |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end function |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">valid</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
function test_comb(sequence chosen, sequence pool, sequence valid) |
|||
-- |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">test_comb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">chosen</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">pool</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">)</span> |
|||
-- (see deep_logic()/set elimination) |
|||
<span style="color: #000080;font-style:italic;">-- |
|||
-- chosen is a sequence of length 2..4 of integers 1..9: ordered elements of pool. |
|||
-- (see deep_logic()/set elimination) |
|||
-- pool is a set of elements of the sequence valid, each of which is a sequence. |
|||
-- chosen is a sequence of length 2..4 of integers 1..9: ordered elements of pool. |
|||
-- (note that elements of valid in pool not in chosen are not necessarily sequences) |
|||
-- pool is a set of elements of the sequence valid, each of which is a sequence. |
|||
-- |
|||
-- (note that elements of valid in pool not in chosen are not necessarily sequences) |
|||
sequence contains = repeat(0,9) |
|||
--</span> |
|||
integer ccount = 0, ch |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">contains</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span> |
|||
object set |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">ccount</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ch</span> |
|||
<span style="color: #004080;">object</span> <span style="color: #000000;">set</span> |
|||
for i=1 to length(chosen) do |
|||
set = valid[pool[chosen[i]]] |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
for j=1 to length(set) do |
|||
<span style="color: #000000;">set</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">[</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]]</span> |
|||
ch = set[j]-'0' |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">set</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
if contains[ch]=0 then |
|||
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">set</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span> |
|||
contains[ch] = 1 |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">contains</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
ccount += 1 |
|||
<span style="color: #000000;">contains</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> |
|||
end if |
|||
<span style="color: #000000;">ccount</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span> |
|||
end for |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
end for |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
if ccount=length(chosen) then |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
for i=1 to length(pool) do |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">ccount</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
if find(i,chosen)=0 then |
|||
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">)</span> |
|||
set = valid[pool[i]] |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
if sequence(set) then |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
-- (reverse order so deletions don't foul indexes) |
|||
<span style="color: #000000;">set</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]</span> |
|||
for j=length(set) to 1 by -1 do |
|||
<span style="color: #008080;">if</span> <span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">set</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
ch = set[j]-'0' |
|||
<span style="color: #000080;font-style:italic;">-- (reverse order so deletions don't foul indexes)</span> |
|||
if contains[ch] then |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">set</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">to</span> <span style="color: #000000;">1</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span> |
|||
valid[pool[i]][j..j] = "" |
|||
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">set</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span> |
|||
improved = 1 |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">contains</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span> |
|||
end if |
|||
<span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">..</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">""</span> |
|||
end for |
|||
<span style="color: #000000;">improved</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> |
|||
end if |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
end if |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end for |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
end if |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
return valid |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end function |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">valid</span> |
|||
-- from [[Combinations#Phix|Combinations]] |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
-- from http://rosettacode.org/wiki/Combinations#Phix |
|||
function comb(sequence pool, valid, integer needed, done=0, sequence chosen={}) |
|||
<span style="color: #000080;font-style:italic;">-- from [[Combinations#Phix|Combinations]] |
|||
-- (used by deep_logic()/set elimination) |
|||
-- from http://rosettacode.org/wiki/Combinations#Phix</span> |
|||
if needed=0 then -- got a full set |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">comb</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">pool</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">needed</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">done</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">chosen</span><span style="color: #0000FF;">={})</span> |
|||
return test_comb(chosen,pool,valid) |
|||
<span style="color: #000080;font-style:italic;">-- (used by deep_logic()/set elimination)</span> |
|||
end if |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">needed</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000080;font-style:italic;">-- got a full set</span> |
|||
if done+needed>length(pool) then return valid end if -- cannot fulfil |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">test_comb</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">)</span> |
|||
-- get all combinations with and without the next item: |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
done += 1 |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">done</span><span style="color: #0000FF;">+</span><span style="color: #000000;">needed</span><span style="color: #0000FF;">></span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">valid</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- cannot fulfil |
|||
if sequence(valid[pool[done]]) then |
|||
-- get all combinations with and without the next item:</span> |
|||
valid = comb(pool,valid,needed-1,done,append(chosen,done)) |
|||
<span style="color: #000000;">done</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span> |
|||
end if |
|||
<span style="color: #008080;">if</span> <span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">[</span><span style="color: #000000;">done</span><span style="color: #0000FF;">]])</span> <span style="color: #008080;">then</span> |
|||
return comb(pool,valid,needed,done,chosen) |
|||
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">comb</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">needed</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">done</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">),</span><span style="color: #000000;">done</span><span style="color: #0000FF;">))</span> |
|||
end function |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">comb</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pool</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">needed</span><span style="color: #0000FF;">,</span><span style="color: #000000;">done</span><span style="color: #0000FF;">,</span><span style="color: #000000;">chosen</span><span style="color: #0000FF;">)</span> |
|||
function deep_logic(string board, sequence valid) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
-- |
|||
-- Create a grid of valid moves. Note this does not modify board, but instead creates |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">deep_logic</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">)</span> |
|||
-- sets of permitted values for each cell, which can also be and are used for hints. |
|||
<span style="color: #000080;font-style:italic;">-- |
|||
-- Apply standard eliminations of known cells, then try some more advanced tactics: |
|||
-- Create a grid of valid moves. Note this does not modify board, but instead creates |
|||
-- |
|||
-- sets of permitted values for each cell, which can also be and are used for hints. |
|||
-- 1) row/col elimination |
|||
-- Apply standard eliminations of known cells, then try some more advanced tactics: |
|||
-- If in any of the 9 small squares a number can only occur in one row or column, |
|||
-- |
|||
-- then that number cannot occur in that row or column in two other corresponding |
|||
-- 1) row/col elimination |
|||
-- small squares. Example (this one with significant practical benefit): |
|||
-- If in any of the 9 small squares a number can only occur in one row or column, |
|||
-- 000|000|036 |
|||
-- then that number cannot occur in that row or column in two other corresponding |
|||
-- 840|000|000 |
|||
-- small squares. Example (this one with significant practical benefit): |
|||
-- 000|000|020 |
|||
-- |
-- 000|000|036 |
||
-- |
-- 840|000|000 |
||
-- |
-- 000|000|020 |
||
-- |
-- ---+---+--- |
||
-- |
-- 000|203|000 |
||
-- |
-- 010|000|700 |
||
-- |
-- 000|600|400 |
||
-- |
-- ---+---+--- |
||
-- |
-- 000|410|050 |
||
-- 003|000|200 |
|||
-- Naively, the br can contain a 3 in the four corners, but looking at mid-right and |
|||
-- 600|000|000 <-- 3 |
|||
-- mid-bottom leads us to eliminating 3s in column 9 and row 9, leaving 7,7 as the |
|||
-- |
-- ^-- 3 |
||
-- |
-- Naively, the br can contain a 3 in the four corners, but looking at mid-right and |
||
-- mid-bottom leads us to eliminating 3s in column 9 and row 9, leaving 7,7 as the |
|||
-- |
|||
-- only square in the br that can be a 3. Uses dotcol and dotrow. |
|||
-- 2) set elimination |
|||
-- Without this, brute force on the above takes ~8s, but with it ~0s |
|||
-- If in any 9-set there is a set of n blank squares that can only contain n digits, |
|||
-- |
|||
-- then no other squares can contain those digits. Example (with some benefit): |
|||
-- 2) set elimination |
|||
-- 75.|.9.|.46 |
|||
-- If in any 9-set there is a set of n blank squares that can only contain n digits, |
|||
-- 961|...|352 |
|||
-- then no other squares can contain those digits. Example (with some benefit): |
|||
-- 4..|...|79. |
|||
-- |
-- 75.|.9.|.46 |
||
-- |
-- 961|...|352 |
||
-- . |
-- 4..|...|79. |
||
-- |
-- ---+---+--- |
||
-- |
-- 2..|6.1|..7 |
||
-- . |
-- .8.|...|.2. |
||
-- |
-- 1..|328|.65 |
||
-- |
-- ---+---+--- |
||
-- |
-- ...|...|... <-- [7,8] is {1,3,8}, [7,9] is {1,3,8} |
||
-- |
-- 3.9|...|2.4 <-- [8,8] is {1,8} |
||
-- 84.|.3.|.79 |
|||
-- (Relies on plain_logic to spot that "must be a 1", and serves as a clear example |
|||
-- |
-- The three cells above the br 479 can only contain {1,3,8}, so the .. of the .2. |
||
-- |
-- in column 7 of that square are {5,6} (not 1) and hence [9,4] must be a 1. |
||
-- ( |
-- (Relies on plain_logic to spot that "must be a 1", and serves as a clear example |
||
-- |
-- of why this routine should not bother to attempt updating the board itself - as |
||
-- it spends almost all of its time looking in a completely different place.) |
|||
-- strategy. However I think that would be harder to code and cannot imagine a case |
|||
-- |
-- (One could argue that [7,7] and [9,7] are the only places that can hold {5,6} and |
||
-- therefore we should eliminate all non-{5,6} from those squares, as an alternative |
|||
-- |
|||
-- strategy. However I think that would be harder to code and cannot imagine a case |
|||
-- 3) x-wings |
|||
-- said complementary logic covers, that the above does not, cmiiw.) |
|||
-- If a pair of rows or columns can only contain a given number in two matching places, |
|||
-- |
|||
-- then once filled they will occupy opposite diagonal corners, hence that said number |
|||
-- 3) x-wings |
|||
-- cannot occur elsewhere in those two columns/rows. Example (with a benefit): |
|||
-- |
-- If a pair of rows or columns can only contain a given number in two matching places, |
||
-- then once filled they will occupy opposite diagonal corners, hence that said number |
|||
-- 6..|425|... |
|||
-- cannot occur elsewhere in those two columns/rows. Example (with a benefit): |
|||
-- 2..|..1|.94 |
|||
-- -- |
-- .43|98.|25. <-- 6 in [1,{6,9}] |
||
-- |
-- 6..|425|... |
||
-- |
-- 2..|..1|.94 |
||
-- |
-- ---+---+--- |
||
-- -- |
-- 9..|..4|.7. <-- hence 6 not in [4,9] |
||
-- |
-- 3..|6.8|... |
||
-- |
-- 41.|2.9|..3 |
||
-- |
-- ---+---+--- |
||
-- |
-- 82.|5..|... <-- hence 6 not in [7,6],[7,9] |
||
-- ...|.4.|..5 <-- hence 6 not in [8,6] |
|||
-- (we also eliminate 6 from [4,9], [7,6] and [8,6] to no great use) |
|||
-- |
-- 534|89.|71. <-- 6 in [9,{6,9}] |
||
-- |
-- A 6 must be in [1,6] or [1,9] and [9,6] or [9,9], hence [7,9] is not 6 and must be 9. |
||
-- (we also eliminate 6 from [4,9], [7,6] and [8,6] to no great use) |
|||
-- |
|||
-- In practice this offers little benefit over a single trial-and-error step, as |
|||
-- 4) swordfish (not attempted) |
|||
-- obviously trying either 6 in row 1 or 9 immediately pinpoints that 9 anyway. |
|||
-- There is an extension to x-wings known as swordfish: three (or more) pairs form |
|||
-- |
|||
-- a staggered pair (or more) of rectangles that exhibit similar properties, eg: |
|||
-- 4) swordfish (not attempted) |
|||
-- 8-1|-5-|-3- |
|||
-- There is an extension to x-wings known as swordfish: three (or more) pairs form |
|||
-- 953|-68|--- |
|||
-- a staggered pair (or more) of rectangles that exhibit similar properties, eg: |
|||
-- -4-|-*3|5*8 |
|||
-- --- |
-- 8-1|-5-|-3- |
||
-- |
-- 953|-68|--- |
||
-- - |
-- -4-|-*3|5*8 |
||
-- |
-- ---+---+--- |
||
-- --- |
-- 6--|9-2|--- |
||
-- |
-- -8-|-3-|-4- |
||
-- - |
-- 3*-|5-1|-*7 <-- hence [6,3] is not 9, must be 4 |
||
-- - |
-- ---+---+--- |
||
-- |
-- 5*2|-*-|-8- |
||
-- --8|37-|--9 |
|||
-- It is not a swordfish if the 3 pairs are on >3 rows, I trust that is obvious. |
|||
-- -3-|82-|1-- |
|||
-- Logically you can extend this to N pairs on N rows, however I cannot imagine a |
|||
-- ^---^---^-- 3 pairs of 9s (marked with *) on 3 rows (only) |
|||
-- case where this is not immediately solved by a single trial-step being invalid. |
|||
-- |
-- It is not a swordfish if the 3 pairs are on >3 rows, I trust that is obvious. |
||
-- Logically you can extend this to N pairs on N rows, however I cannot imagine a |
|||
-- goes for [6,8]:=9 and [7,2]:=9, since they are all entirely inter-dependent.) |
|||
-- |
-- case where this is not immediately solved by a single trial-step being invalid. |
||
-- (eg above if you try [3,5]:=9 it is quickly proved to be invalid, and the same |
|||
-- Likewise there are "Alternate Pairs" and "Hook or X-Y wing" strategies, which |
|||
-- goes for [6,8]:=9 and [7,2]:=9, since they are all entirely inter-dependent.) |
|||
-- are easily solved with a single trial-and-error step, and of course the brute |
|||
-- |
-- Obviously where I have said rows, the same concept can be applied to columns. |
||
-- Likewise there are "Alternate Pairs" and "Hook or X-Y wing" strategies, which |
|||
-- it selects shortest - I've noted the possible improvement below.] |
|||
-- are easily solved with a single trial-and-error step, and of course the brute |
|||
-- |
|||
-- force algorithm is going to select pairs first anyway. [Erm, no it doesn't, |
|||
integer col, row |
|||
-- it selects shortest - I've noted the possible improvement below.] |
|||
sequence c, r |
|||
--</span> |
|||
sequence nine, prevsets, set |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">k</span> <span style="color: #000080;font-style:italic;">-- (scratch)</span> |
|||
object vj |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
integer ch, k, idx, sx, sy, count |
|||
<span style="color: #000080;font-style:italic;">-- initialise/start again from scratch</span> |
|||
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"123456789"</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span> |
|||
if length(valid)=0 then |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
-- initialise/start again from scratch |
|||
<span style="color: #000080;font-style:italic;">-- |
|||
valid = repeat("123456789",9*9) |
|||
-- First perform standard eliminations of any known cells: |
|||
end if |
|||
-- (repeated every time so plain_logic() does not have to worry about it) |
|||
-- |
|||
--</span> |
|||
-- First perform standard eliminations of any known cells: |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span> <span style="color: #008080;">do</span> |
|||
-- (repeated every time so plain_logic() does not have to worry about it) |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
-- |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">></span><span style="color: #008000;">'0'</span> |
|||
for i=1 to 9*9 do |
|||
<span style="color: #008080;">and</span> <span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span> |
|||
ch = board[i] |
|||
<span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ch</span> |
|||
if ch>'0' |
|||
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">eliminate_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">cols</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]],</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span> |
|||
and string(valid[i]) then |
|||
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">eliminate_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">rows</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]],</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span> |
|||
valid[i] = ch |
|||
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">eliminate_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">squares</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]],</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span> |
|||
valid = eliminate_in(valid,nines[cols[i]],ch) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
valid = eliminate_in(valid,nines[rows[i]],ch) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
valid = eliminate_in(valid,nines[squares[i]],ch) |
|||
<span style="color: #000080;font-style:italic;">-- |
|||
end if |
|||
-- 1) row/col elimination |
|||
end for |
|||
-- |
--</span> |
||
<span style="color: #008080;">for</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">=</span><span style="color: #000000;">19</span> <span style="color: #008080;">to</span> <span style="color: #000000;">27</span> <span style="color: #008080;">do</span> |
|||
-- 1) row/col elimination |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- 0 = none seen, 1..9 this col only, -1: >1 col</span> |
|||
-- |
|||
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">),</span> <span style="color: #000080;font-style:italic;">-- "" row row</span> |
|||
for s=19 to 27 do |
|||
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">s</span><span style="color: #0000FF;">]</span> |
|||
c = repeat(0,9) -- 0 = none seen, 1..9 this col only, -1: >1 col |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">row</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">col</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">ch</span> |
|||
r = repeat(0,9) -- "" row row |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> |
|||
nine = nines[s] |
|||
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nine</span><span style="color: #0000FF;">[</span><span style="color: #000000;">n</span><span style="color: #0000FF;">]</span> |
|||
for n=1 to 9 do |
|||
<span style="color: #004080;">object</span> <span style="color: #000000;">vk</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> |
|||
k = nine[n] |
|||
<span style="color: #008080;">if</span> <span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vk</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
vj = valid[k] |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vk</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
if string(vj) then |
|||
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">vk</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span> |
|||
for i=1 to length(vj) do |
|||
<span style="color: #000000;">col</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dotcol</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> |
|||
ch = vj[i]-'0' |
|||
<span style="color: #000000;">row</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dotrow</span><span style="color: #0000FF;">[</span><span style="color: #000000;">k</span><span style="color: #0000FF;">]</span> |
|||
col = dotcol[k] |
|||
<span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">],{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">col</span><span style="color: #0000FF;">})!=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">?</span><span style="color: #000000;">col</span><span style="color: #0000FF;">:-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> |
|||
row = dotrow[k] |
|||
<span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">],{</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">row</span><span style="color: #0000FF;">})!=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">?</span><span style="color: #000000;">row</span><span style="color: #0000FF;">:-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span> |
|||
c[ch] = iff(find(c[ch],{0,col})!=0?col:-1) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
r[ch] = iff(find(r[ch],{0,row})!=0?row:-1) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end if |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> |
|||
end for |
|||
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #008000;">'0'</span> |
|||
for i=1 to 9 do |
|||
<span style="color: #000000;">col</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
ch = i+'0' |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">col</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
col = c[i] |
|||
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">eliminate_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sixes</span><span style="color: #0000FF;">[</span><span style="color: #000000;">col</span><span style="color: #0000FF;">],</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span> |
|||
if col>0 then |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
valid = eliminate_in(valid,sixes[col],ch) |
|||
<span style="color: #000000;">row</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">r</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
end if |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">row</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
row = r[i] |
|||
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">eliminate_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">sixes</span><span style="color: #0000FF;">[</span><span style="color: #000000;">row</span><span style="color: #0000FF;">],</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span> |
|||
if row>0 then |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
valid = eliminate_in(valid,sixes[row],ch) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end if |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end for |
|||
<span style="color: #000080;font-style:italic;">-- |
|||
end for |
|||
-- |
-- 2) set elimination |
||
-- |
--</span> |
||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
-- |
|||
<span style="color: #000080;font-style:italic;">-- |
|||
for i=1 to length(nines) do |
|||
-- Practical note: Meticulously counting empties to eliminate larger set sizes |
|||
-- |
|||
-- would at best reduce 6642 tests to 972, not deemed worth it. |
|||
-- Practical note: Meticulously counting empties to eliminate larger set sizes |
|||
--</span> |
|||
-- would at best reduce 6642 tests to 972, not deemed worth it. |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">set_size</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #000000;">4</span> <span style="color: #008080;">do</span> |
|||
-- |
|||
<span style="color: #000080;font-style:italic;">--if floor(count_empties(nines[i])/2)>=set_size then -- (untested)</span> |
|||
for set_size=2 to 4 do |
|||
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">comb</span><span style="color: #0000FF;">(</span><span style="color: #000000;">nines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">set_size</span><span style="color: #0000FF;">)</span> |
|||
--if floor(count_empties(nines[i])/2)>=set_size then -- (untested) |
|||
<span style="color: #000080;font-style:italic;">--end if</span> |
|||
valid = comb(nines[i],valid,set_size) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
--end if |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end for |
|||
<span style="color: #000080;font-style:italic;">-- |
|||
end for |
|||
-- |
-- 3) x-wings |
||
-- |
--</span> |
||
<span style="color: #008080;">for</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'1'</span> <span style="color: #008080;">to</span> <span style="color: #008000;">'9'</span> <span style="color: #008080;">do</span> |
|||
-- |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">prevsets</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">set</span> |
|||
for ch='1' to '9' do |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">count</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">idx</span> |
|||
prevsets = repeat(0,9) |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> |
|||
for x=1 to 9 do |
|||
<span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> |
|||
count = 0 |
|||
<span style="color: #000000;">set</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span> |
|||
set = repeat(0,9) |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span> |
|||
for y=0 to 8 do |
|||
<span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">+</span><span style="color: #000000;">x</span> |
|||
idx = y*9+x |
|||
<span style="color: #008080;">if</span> <span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span> |
|||
if sequence(valid[idx]) and find(ch,valid[idx]) then |
|||
<span style="color: #000000;">set</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> |
|||
set[y+1] = 1 |
|||
count += 1 |
<span style="color: #000000;">count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span> |
||
end if |
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
||
end for |
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
||
<span style="color: #008080;">if</span> <span style="color: #000000;">count</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span> |
|||
if count=2 then |
|||
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">set</span><span style="color: #0000FF;">,</span><span style="color: #000000;">prevsets</span><span style="color: #0000FF;">)</span> |
|||
k = find(set,prevsets) |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
if k!=0 then |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span> |
|||
for y=0 to 8 do |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">set</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> |
|||
if set[y+1]=1 then |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">sx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> |
|||
for sx=1 to 9 do |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">sx</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">k</span> <span style="color: #008080;">and</span> <span style="color: #000000;">sx</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">x</span> <span style="color: #008080;">then</span> |
|||
if sx!=k and sx!=x then |
|||
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">eliminate_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">+</span><span style="color: #000000;">sx</span><span style="color: #0000FF;">},</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span> |
|||
valid = eliminate_in(valid,{y*9+sx},ch) |
|||
end if |
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
||
end for |
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
||
end if |
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
||
end for |
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
||
else |
<span style="color: #008080;">else</span> |
||
<span style="color: #000000;">prevsets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">set</span> |
|||
prevsets[x] = set |
|||
end if |
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
end if |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end for |
|||
<span style="color: #000000;">prevsets</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span> |
|||
prevsets = repeat(0,9) |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span> |
|||
for y=0 to 8 do |
|||
<span style="color: #000000;">count</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> |
|||
count = 0 |
|||
<span style="color: #000000;">set</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span> |
|||
set = repeat(0,9) |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> |
|||
for x=1 to 9 do |
|||
<span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">+</span><span style="color: #000000;">x</span> |
|||
idx = y*9+x |
|||
<span style="color: #008080;">if</span> <span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span> |
|||
if sequence(valid[idx]) and find(ch,valid[idx]) then |
|||
<span style="color: #000000;">set</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> |
|||
set[x] = 1 |
|||
count += 1 |
<span style="color: #000000;">count</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span> |
||
end if |
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
||
end for |
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
||
<span style="color: #008080;">if</span> <span style="color: #000000;">count</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">then</span> |
|||
if count=2 then |
|||
<span style="color: #000000;">k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">set</span><span style="color: #0000FF;">,</span><span style="color: #000000;">prevsets</span><span style="color: #0000FF;">)</span> |
|||
k = find(set,prevsets) |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">k</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
if k!=0 then |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> |
|||
for x=1 to 9 do |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">set</span><span style="color: #0000FF;">[</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> |
|||
if set[x]=1 then |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">sy</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span> |
|||
for sy=0 to 8 do |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">sy</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">k</span> <span style="color: #008080;">and</span> <span style="color: #000000;">sy</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">y</span> <span style="color: #008080;">then</span> |
|||
if sy+1!=k and sy!=y then |
|||
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">eliminate_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">sy</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">+</span><span style="color: #000000;">x</span><span style="color: #0000FF;">},</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span> |
|||
valid = eliminate_in(valid,{sy*9+x},ch) |
|||
end if |
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
||
end for |
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
||
end if |
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
||
end for |
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
||
else |
<span style="color: #008080;">else</span> |
||
<span style="color: #000000;">prevsets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">set</span> |
|||
prevsets[y+1] = set |
|||
end if |
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
end if |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end for |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end for |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">valid</span> |
|||
return valid |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
end function |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">permitted_in</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">sets</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span> |
|||
function permitted_in(string board, sequence sets, sequence valid, integer ch) |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> |
|||
sequence set |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">set</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">nines</span><span style="color: #0000FF;">[</span><span style="color: #000000;">sets</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]</span> |
|||
integer pos, idx, bch |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> |
|||
for i=1 to 9 do |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> |
|||
set = nines[sets[i]] |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">idx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">set</span><span style="color: #0000FF;">[</span><span style="color: #000000;">j</span><span style="color: #0000FF;">],</span> |
|||
pos = 0 |
|||
<span style="color: #000000;">bch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">]</span> |
|||
for j=1 to 9 do |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">bch</span><span style="color: #0000FF;">></span><span style="color: #008000;">'0'</span> <span style="color: #008080;">then</span> |
|||
idx = set[j] |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">bch</span><span style="color: #0000FF;">=</span><span style="color: #000000;">ch</span> <span style="color: #008080;">then</span> <span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
bch = board[idx] |
|||
<span style="color: #008080;">elsif</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">idx</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span> |
|||
if bch>'0' then |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">pos</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
if bch=ch then pos = -1 exit end if |
|||
<span style="color: #000000;">pos</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">idx</span> |
|||
elsif find(ch,valid[idx]) then |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
pos = idx |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">pos</span><span style="color: #0000FF;">></span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
end if |
|||
<span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">pos</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ch</span> |
|||
end for |
|||
<span style="color: #000000;">improved</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> |
|||
if pos>0 then |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
board[pos] = ch |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
improved = 1 |
|||
<span style="color: #008080;">return</span> <span style="color: #000000;">board</span> |
|||
end if |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
end for |
|||
return board |
|||
<span style="color: #008080;">enum</span> <span style="color: #000000;">INVALID</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">INCOMPLETE</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">SOLVED</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">MULTIPLE</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">BRUTE</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">3</span> |
|||
end function |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">plain_logic</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">)</span> |
|||
enum INVALID = -1, INCOMPLETE = 0, SOLVED = 1, MULTIPLE = 2, BRUTE = 3 |
|||
<span style="color: #000080;font-style:italic;">-- |
|||
-- Responsible for: |
|||
function plain_logic(string board) |
|||
-- 1) cells with only one option |
|||
-- |
|||
-- 2) numbers with only one home |
|||
-- Responsible for: |
|||
--</span> |
|||
-- 1) cells with only one option |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">solved</span> |
|||
-- 2) numbers with only one home |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> |
|||
-- |
|||
<span style="color: #008080;">while</span> <span style="color: #004600;">true</span> <span style="color: #008080;">do</span> |
|||
integer solved |
|||
<span style="color: #000000;">solved</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">SOLVED</span> |
|||
sequence valid = {} |
|||
<span style="color: #000000;">improved</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> |
|||
object vi |
|||
<span style="color: #000000;">valid</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">deep_logic</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">)</span> |
|||
while 1 do |
|||
<span style="color: #000080;font-style:italic;">-- 1) cells with only one option:</span> |
|||
solved = SOLVED |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span> |
|||
improved = 0 |
|||
<span style="color: #004080;">object</span> <span style="color: #000000;">vi</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
valid = deep_logic(board,valid) |
|||
<span style="color: #008080;">if</span> <span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vi</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vi</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,{},</span><span style="color: #000000;">INVALID</span><span style="color: #0000FF;">}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
-- 1) cells with only one option: |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vi</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> |
|||
for i=1 to length(valid) do |
|||
<span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">vi</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> |
|||
vi = valid[i] |
|||
<span style="color: #000000;">improved</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> |
|||
if string(vi) then |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
if length(vi)=1 then |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]<=</span><span style="color: #008000;">'0'</span> <span style="color: #008080;">then</span> |
|||
board[i] = vi[1] |
|||
<span style="color: #000000;">solved</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">INCOMPLETE</span> |
|||
improved = 1 |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end if |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">=</span><span style="color: #000000;">SOLVED</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,{},</span><span style="color: #000000;">SOLVED</span><span style="color: #0000FF;">}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
if board[i]<='0' then |
|||
solved = INCOMPLETE |
|||
<span style="color: #000080;font-style:italic;">-- 2) numbers with only one home</span> |
|||
end if |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">=</span><span style="color: #008000;">'1'</span> <span style="color: #008080;">to</span> <span style="color: #008000;">'9'</span> <span style="color: #008080;">do</span> |
|||
end for |
|||
<span style="color: #000000;">board</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">permitted_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cols</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span> |
|||
if solved=SOLVED then return {board,{},SOLVED} end if |
|||
<span style="color: #000000;">board</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">permitted_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,</span><span style="color: #000000;">rows</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #000000;">board</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">permitted_in</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,</span><span style="color: #000000;">squares</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">)</span> |
|||
-- 2) numbers with only one home |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
for ch='1' to '9' do |
|||
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">improved</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
board = permitted_in(board,cols,valid,ch) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span> |
|||
board = permitted_in(board,rows,valid,ch) |
|||
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,</span><span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solved</span><span style="color: #0000FF;">}</span> |
|||
board = permitted_in(board,squares,valid,ch) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
end for |
|||
if not improved then exit end if |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">validate</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">)</span> |
|||
end while |
|||
<span style="color: #000080;font-style:italic;">-- (sum9 should be sufficient - if you want, get rid of nine/nines)</span> |
|||
return {board,valid,solved} |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">sum9</span> |
|||
end function |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">nine</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">nines</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span> |
|||
function validate(string board) |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- columns</span> |
|||
-- (sum9 should be sufficient - if you want, get rid of nine/nines) |
|||
<span style="color: #000000;">sum9</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> |
|||
integer ch, sum9 |
|||
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span> |
|||
sequence nine, nines = tagset(9) |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">81</span> <span style="color: #008080;">by</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> |
|||
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span> |
|||
for x=0 to 8 do -- columns |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;"><</span><span style="color: #000000;">1</span> <span style="color: #008080;">or</span> <span style="color: #000000;">ch</span><span style="color: #0000FF;">></span><span style="color: #000000;">9</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
sum9 = 0 |
|||
<span style="color: #000000;">sum9</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">ch</span> |
|||
nine = repeat(0,9) |
|||
<span style="color: #000000;">nine</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ch</span> |
|||
for y=1 to 81 by 9 do |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
ch = board[y+x]-'0' |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">sum9</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">45</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
if ch<1 or ch>9 then return 0 end if |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">nine</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">nines</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
sum9 += ch |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
nine[ch] = ch |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">81</span> <span style="color: #008080;">by</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- rows</span> |
|||
end for |
|||
<span style="color: #000000;">sum9</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> |
|||
if sum9!=45 then return 0 end if |
|||
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span> |
|||
if nine!=nines then return 0 end if |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">do</span> |
|||
end for |
|||
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">y</span><span style="color: #0000FF;">+</span><span style="color: #000000;">x</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span> |
|||
for y=1 to 81 by 9 do -- rows |
|||
<span style="color: #000000;">sum9</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">ch</span> |
|||
sum9 = 0 |
|||
<span style="color: #000000;">nine</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ch</span> |
|||
nine = repeat(0,9) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
for x=0 to 8 do |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">sum9</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">45</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
ch = board[y+x]-'0' |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">nine</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">nines</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
sum9 += ch |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
nine[ch] = ch |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">by</span> <span style="color: #000000;">3</span> <span style="color: #008080;">do</span> <span style="color: #000080;font-style:italic;">-- small squares</span> |
|||
end for |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">to</span> <span style="color: #000000;">8</span> <span style="color: #008080;">by</span> <span style="color: #000000;">3</span> <span style="color: #008080;">do</span> |
|||
if sum9!=45 then return 0 end if |
|||
<span style="color: #000000;">sum9</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> |
|||
if nine!=nines then return 0 end if |
|||
<span style="color: #000000;">nine</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span> |
|||
end for |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">sy</span><span style="color: #0000FF;">=</span><span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span> <span style="color: #008080;">to</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span><span style="color: #0000FF;">+</span><span style="color: #000000;">18</span> <span style="color: #008080;">by</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span> |
|||
for y=0 to 8 by 3 do -- small squares |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">sx</span><span style="color: #0000FF;">=</span><span style="color: #000000;">x</span> <span style="color: #008080;">to</span> <span style="color: #000000;">x</span><span style="color: #0000FF;">+</span><span style="color: #000000;">2</span> <span style="color: #008080;">do</span> |
|||
for x=0 to 8 by 3 do |
|||
<span style="color: #000000;">ch</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">sy</span><span style="color: #0000FF;">+</span><span style="color: #000000;">sx</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]-</span><span style="color: #008000;">'0'</span> |
|||
sum9 = 0 |
|||
<span style="color: #000000;">sum9</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">ch</span> |
|||
nine = repeat(0,9) |
|||
<span style="color: #000000;">nine</span><span style="color: #0000FF;">[</span><span style="color: #000000;">ch</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ch</span> |
|||
for sy=y*9 to y*9+18 by 9 do |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
ch = board[sy+sx+1]-'0' |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">sum9</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">45</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
sum9 += ch |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">nine</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">nines</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #004600;">false</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
nine[ch] = ch |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end for |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
end for |
|||
<span style="color: #008080;">return</span> <span style="color: #004600;">true</span> |
|||
if sum9!=45 then return 0 end if |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
if nine!=nines then return 0 end if |
|||
end for |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">)</span> |
|||
end for |
|||
<span style="color: #0000FF;">{</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">solution</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">sequence</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">plain_logic</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">)</span> |
|||
return 1 |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">=</span><span style="color: #000000;">INVALID</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #0000FF;">{{},</span><span style="color: #000000;">INVALID</span><span style="color: #0000FF;">}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
end function |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">=</span><span style="color: #000000;">SOLVED</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">},</span><span style="color: #000000;">SOLVED</span><span style="color: #0000FF;">}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">=</span><span style="color: #000000;">BRUTE</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #0000FF;">{{</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">},</span><span style="color: #000000;">BRUTE</span><span style="color: #0000FF;">}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
function solve(string board, sequence valid={}) |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">INCOMPLETE</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
sequence solution, solutions |
|||
<span style="color: #000080;font-style:italic;">-- find the cell with the fewest options: |
|||
integer solved |
|||
-- (a possible improvement here would be to select the shortest |
|||
integer minopt, mindx |
|||
-- with the "most pairs" set, see swordfish etc above.)</span> |
|||
object vi |
|||
<span style="color: #004080;">integer</span> <span style="color: #000000;">minopt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">10</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">mindx</span> |
|||
{solution,valid,solved} = plain_logic(board) |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span><span style="color: #0000FF;">*</span><span style="color: #000000;">9</span> <span style="color: #008080;">do</span> |
|||
if solved=INVALID then return {{},INVALID} end if |
|||
<span style="color: #004080;">object</span> <span style="color: #000000;">vi</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
if solved=SOLVED then return {{solution},SOLVED} end if |
|||
<span style="color: #008080;">if</span> <span style="color: #004080;">string</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vi</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
if solved=BRUTE then return {{solution},BRUTE} end if |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vi</span><span style="color: #0000FF;">)<=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- should be caught above</span> |
|||
if solved!=INCOMPLETE then ?9/0 end if |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vi</span><span style="color: #0000FF;">)<</span><span style="color: #000000;">minopt</span> <span style="color: #008080;">then</span> |
|||
-- find the cell with the fewest options: |
|||
<span style="color: #000000;">minopt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">vi</span><span style="color: #0000FF;">)</span> |
|||
-- (a possible improvement here would be to select the shortest |
|||
<span style="color: #000000;">mindx</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span> |
|||
-- with the "most pairs" set, see swordfish etc above.) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
minopt = 10 |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
for i=1 to 9*9 do |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
vi = valid[i] |
|||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">solutions</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> |
|||
if string(vi) then |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">minopt</span> <span style="color: #008080;">do</span> |
|||
if length(vi)<=1 then ?9/0 end if -- should be caught above |
|||
<span style="color: #000000;">board</span><span style="color: #0000FF;">[</span><span style="color: #000000;">mindx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">valid</span><span style="color: #0000FF;">[</span><span style="color: #000000;">mindx</span><span style="color: #0000FF;">][</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
if length(vi)<minopt then |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solved</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">)</span> |
|||
minopt = length(vi) |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">=</span><span style="color: #000000;">MULTIPLE</span> <span style="color: #008080;">then</span> |
|||
mindx = i |
|||
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">,</span><span style="color: #000000;">MULTIPLE</span><span style="color: #0000FF;">}</span> |
|||
end if |
|||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">=</span><span style="color: #000000;">SOLVED</span> |
|||
end if |
|||
<span style="color: #008080;">or</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">=</span><span style="color: #000000;">BRUTE</span> <span style="color: #008080;">then</span> |
|||
end for |
|||
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #7060A8;">find</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">)</span> |
|||
solutions = {} |
|||
<span style="color: #008080;">and</span> <span style="color: #000000;">validate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">then</span> |
|||
for i=1 to minopt do |
|||
<span style="color: #000000;">solutions</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">])</span> |
|||
board[mindx] = valid[mindx][i] |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
{solution,solved} = solve(board,valid) |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">)></span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> |
|||
if solved=MULTIPLE then |
|||
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">,</span><span style="color: #000000;">MULTIPLE</span><span style="color: #0000FF;">}</span> |
|||
return {solution,MULTIPLE} |
|||
<span style="color: #008080;">elsif</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
elsif solved=SOLVED |
|||
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">,</span><span style="color: #000000;">BRUTE</span><span style="color: #0000FF;">}</span> |
|||
or solved=BRUTE then |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
if not find(solution[1],solutions) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
and validate(solution[1]) then |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
solutions = append(solutions,solution[1]) |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> |
|||
end if |
|||
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">,</span><span style="color: #000000;">BRUTE</span><span style="color: #0000FF;">}</span> |
|||
if length(solutions)>1 then |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
return {solutions,MULTIPLE} |
|||
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{{},</span><span style="color: #000000;">INVALID</span><span style="color: #0000FF;">}</span> |
|||
elsif length(solutions) then |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
return {solutions,BRUTE} |
|||
end if |
|||
<span style="color: #008080;">function</span> <span style="color: #000000;">test_one</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">)</span> |
|||
end if |
|||
<span style="color: #0000FF;">{</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">solutions</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">solve</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">)</span> |
|||
end for |
|||
<span style="color: #004080;">string</span> <span style="color: #000000;">solution</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">desc</span> |
|||
if length(solutions)=1 then |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">=</span><span style="color: #000000;">SOLVED</span> <span style="color: #008080;">then</span> |
|||
return {solutions,BRUTE} |
|||
<span style="color: #000000;">desc</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"(logic)"</span> |
|||
end if |
|||
<span style="color: #008080;">elsif</span> <span style="color: #000000;">solved</span><span style="color: #0000FF;">=</span><span style="color: #000000;">BRUTE</span> <span style="color: #008080;">then</span> |
|||
return {{},INVALID} |
|||
<span style="color: #000000;">desc</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"(brute force)"</span> |
|||
end function |
|||
<span style="color: #008080;">else</span> |
|||
<span style="color: #000000;">desc</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"???"</span> <span style="color: #000080;font-style:italic;">-- INVALID/INCOMPLETE/MULTIPLE</span> |
|||
function test_one(string board) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
sequence solutions |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
string solution, desc |
|||
<span style="color: #000000;">solution</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">board</span> |
|||
integer solved |
|||
<span style="color: #000000;">desc</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"*** NO SOLUTIONS ***"</span> |
|||
{solutions,solved} = solve(board) |
|||
<span style="color: #008080;">elsif</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solutions</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span> |
|||
if solved=SOLVED then |
|||
<span style="color: #000000;">solution</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">solutions</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> |
|||
desc = "(logic)" |
|||
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">validate</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> |
|||
elsif solved=BRUTE then |
|||
<span style="color: #000000;">desc</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"*** ERROR ***"</span> <span style="color: #000080;font-style:italic;">-- (should never happen)</span> |
|||
desc = "(brute force)" |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
else |
|||
<span style="color: #008080;">else</span> |
|||
desc = "???" -- INVALID/INCOMPLETE/MULTIPLE |
|||
<span style="color: #000000;">solution</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">board</span> |
|||
end if |
|||
<span style="color: #000000;">desc</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"*** MULTIPLE SOLUTIONS ***"</span> |
|||
if length(solutions)=0 then |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
solution = board |
|||
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">,</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">}</span> |
|||
desc = "*** NO SOLUTIONS ***" |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span> |
|||
elsif length(solutions)=1 then |
|||
solution = solutions[1] |
|||
<span style="color: #000080;font-style:italic;">--NB Blank cells can be represented by any character <'1'. Spaces are not recommended since |
|||
if not validate(solution) then |
|||
-- they can all too easily be converted to tabs by copy/paste/save. In particular, ? and |
|||
desc = "*** ERROR ***" -- (should never happen) |
|||
-- _ are NOT valid characters for representing a blank square. Use any of .0-* instead.</span> |
|||
end if |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">tests</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span> |
|||
solution = board |
|||
<span style="color: #008000;">"..............3.85..1.2.......5.7.....4...1...9.......5......73..2.1........4...9"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.01s, (logic)) |
|||
desc = "*** MULTIPLE SOLUTIONS ***" |
|||
-- row/col elimination (was 8s w/o logic first)</span> |
|||
end if |
|||
<span style="color: #008000;">"000000036840000000000000020000203000010000700000600400000410050003000200600000000"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.04s, (brute force))</span> |
|||
return {solution,desc} |
|||
<span style="color: #008000;">".......39.....1..5..3.5.8....8.9...6.7...2...1..4.......9.8..5..2....6..4..7....."</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (1.12s, (brute force))</span> |
|||
end function |
|||
<span style="color: #008000;">"000037600000600090008000004090000001600000009300000040700000800010009000002540000"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))</span> |
|||
<span style="color: #008000;">"....839..1......3...4....7..42.3....6.......4....7..1..2........8...92.....25...6"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.04s, (brute force))</span> |
|||
--NB Blank cells can be represented by any character <'1'. Spaces are not recommended since |
|||
<span style="color: #008000;">"..1..5.7.92.6.......8...6...9..2.4.1.........3.4.8..9...7...3.......7.69.1.8..7.."</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic)) |
|||
-- they can all too easily be converted to tabs by copy/paste/save. In particular, ? and |
|||
-- (the following takes ~8s when checking for multiple solutions)</span> |
|||
-- _ are NOT valid characters for representing a blank square. Use any of .0-* instead. |
|||
<span style="color: #008000;">"--3------4---8--36--8---1---4--6--73---9----------2--5--4-7--686--------7--6--5--"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.01s, (brute force))</span> |
|||
<span style="color: #008000;">"..3.2.6..9..3.5..1..18.64....81.29..7.......8..67.82....26.95..8..2.3..9..5.1.3.."</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))</span> |
|||
constant tests = { |
|||
<span style="color: #008000;">"--4-5--6--6-1--8-93----7----8----5-----4-3-----6----7----2----61-5--4-3--2--7-1--"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic)) |
|||
"..............3.85..1.2.......5.7.....4...1...9.......5......73..2.1........4...9", -- (0.01s, (logic)) |
|||
-- x-wings</span> |
|||
-- row/col elimination (was 8s w/o logic first) |
|||
<span style="color: #008000;">".4398.25.6..425...2....1.949....4.7.3..6.8...41.2.9..382.5.........4...553489.71."</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))</span> |
|||
"000000036840000000000000020000203000010000700000600400000410050003000200600000000", -- (0.04s, (brute force)) |
|||
"....... |
<span style="color: #008000;">".9...4..7.....79..8........4.58.....3.......2.....97.6........4..35.....2..6...8."</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic)) |
||
-- "AL Escargot", so-called "hardest sudoku"</span> |
|||
"000037600000600090008000004090000001600000009300000040700000800010009000002540000", -- (0.00s, (logic)) |
|||
".... |
<span style="color: #008000;">"1....7.9..3..2...8..96..5....53..9...1..8...26....4...3......1..4......7..7...3.."</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.26s, (brute force))</span> |
||
".. |
<span style="color: #008000;">"12.3....435....1....4........54..2..6...7.........8.9...31..5.......9.7.....6...8"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.48s, (brute force))</span> |
||
<span style="color: #008000;">"12.4..3..3...1..5...6...1..7...9.....4.6.3.....3..2...5...8.7....7.....5.......98"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (1.07s, (brute force))</span> |
|||
-- (the following takes ~8s when checking for multiple solutions) |
|||
<span style="color: #008000;">"394..267....3..4..5..69..2..45...9..6.......7..7...58..1..67..8..9..8....264..735"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))</span> |
|||
"--3------4---8--36--8---1---4--6--73---9----------2--5--4-7--686--------7--6--5--", -- (0.01s, (brute force)) |
|||
".. |
<span style="color: #008000;">"4......6.5...8.9..3....1....2.7....1.9.....4.8....3.5....2....7..6.5...8.1......6"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.01s, (brute force))</span> |
||
<span style="color: #008000;">"5...7....6..195....98....6.8...6...34..8.3..17...2...6.6....28....419..5....8..79"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))</span> |
|||
"--4-5--6--6-1--8-93----7----8----5-----4-3-----6----7----2----61-5--4-3--2--7-1--", -- (0.00s, (logic)) |
|||
<span style="color: #008000;">"503600009010002600900000080000700005006804100200003000030000008004300050800006702"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))</span> |
|||
-- x-wings |
|||
". |
<span style="color: #008000;">"53..247....2...8..1..7.39.2..8.72.49.2.98..7.79.....8.....3.5.696..1.3...5.69..1."</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))</span> |
||
<span style="color: #008000;">"530070000600195000098000060800060003400803001700020006060000280000419005000080079"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic)) |
|||
".9...4..7.....79..8........4.58.....3.......2.....97.6........4..35.....2..6...8.", -- (0.00s, (logic)) |
|||
-- set exclusion</span> |
|||
-- "AL Escargot", so-called "hardest sudoku" |
|||
" |
<span style="color: #008000;">"75..9..46961...3524.....79.2..6.1..7.8.....2.1..328.65.........3.9...2.484..3..79"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic)) |
||
-- Worlds hardest sudoku:</span> |
|||
"12.3....435....1....4........54..2..6...7.........8.9...31..5.......9.7.....6...8", -- (0.48s, (brute force)) |
|||
<span style="color: #008000;">"800000000003600000070090200050007000000045700000100030001000068008500010090000400"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.21s, (brute force))</span> |
|||
"12.4..3..3...1..5...6...1..7...9.....4.6.3.....3..2...5...8.7....7.....5.......98", -- (1.07s, (brute force)) |
|||
<span style="color: #008000;">"819--5-----2---75--371-4-6-4--59-1--7--3-8--2--3-62--7-5-7-921--64---9-----2--438"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic))</span> |
|||
"394..267....3..4..5..69..2..45...9..6.......7..7...58..1..67..8..9..8....264..735", -- (0.00s, (logic)) |
|||
" |
<span style="color: #008000;">"85...24..72......9..4.........1.7..23.5...9...4...........8..7..17..........36.4."</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.01s, (logic))</span> |
||
" |
<span style="color: #008000;">"9..2..5...4..6..3...3.....6...9..2......5..8...7..4..37.....1...5..2..4...1..6..9"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.17s, (brute force))</span> |
||
<span style="color: #008000;">"97.3...6..6.75.........8.5.......67.....3.....539..2..7...25.....2.1...8.4...73.."</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.00s, (logic)) |
|||
"503600009010002600900000080000700005006804100200003000030000008004300050800006702", -- (0.00s, (logic)) |
|||
-- "the beast" (an earlier algorithm took 318s (5min 18s) on this):</span> |
|||
"53..247....2...8..1..7.39.2..8.72.49.2.98..7.79.....8.....3.5.696..1.3...5.69..1.", -- (0.00s, (logic)) |
|||
<span style="color: #008000;">"000060080020000000001000000070000102500030000000000400004201000300700600000000050"</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (0.03s, (brute force))</span> |
|||
"530070000600195000098000060800060003400803001700020006060000280000419005000080079", -- (0.00s, (logic)) |
|||
<span style="color: #0000FF;">$},</span> |
|||
-- set exclusion |
|||
"75..9..46961...3524.....79.2..6.1..7.8.....2.1..328.65.........3.9...2.484..3..79", -- (0.00s, (logic)) |
|||
<span style="color: #000000;">lt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">tests</span><span style="color: #0000FF;">),</span> |
|||
-- Worlds hardest sudoku: |
|||
<span style="color: #000000;">run_one_test</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> |
|||
"800000000003600000070090200050007000000045700000100030001000068008500010090000400", -- (0.21s, (brute force)) |
|||
"819--5-----2---75--371-4-6-4--59-1--7--3-8--2--3-62--7-5-7-921--64---9-----2--438", -- (0.00s, (logic)) |
|||
<span style="color: #008080;">constant</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">" x x x | x x x | x x x "</span><span style="color: #0000FF;">,</span> |
|||
"85...24..72......9..4.........1.7..23.5...9...4...........8..7..17..........36.4.", -- (0.01s, (logic)) |
|||
<span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #008000;">"-------+-------+-------"</span><span style="color: #0000FF;">,</span> |
|||
"9..2..5...4..6..3...3.....6...9..2......5..8...7..4..37.....1...5..2..4...1..6..9", -- (0.17s, (brute force)) |
|||
<span style="color: #000000;">l3</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">join</span><span style="color: #0000FF;">({</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l</span><span style="color: #0000FF;">},</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">),</span> |
|||
"97.3...6..6.75.........8.5.......67.....3.....539..2..7...25.....2.1...8.4...73..", -- (0.00s, (logic)) |
|||
<span style="color: #000000;">fmt</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">substitute</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">({</span><span style="color: #000000;">l3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">l3</span><span style="color: #0000FF;">},</span><span style="color: #008000;">"\n"</span><span style="color: #0000FF;">),</span><span style="color: #008000;">"x"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%c"</span><span style="color: #0000FF;">)&</span><span style="color: #008000;">"\n"</span> |
|||
-- "the beast" (an earlier algorithm took 318s (5min 18s) on this): |
|||
"000060080020000000001000000070000102500030000000000400004201000300700600000000050", -- (0.03s, (brute force)) |
|||
<span style="color: #008080;">procedure</span> <span style="color: #000000;">test</span><span style="color: #0000FF;">()</span> |
|||
$}, |
|||
<span style="color: #004080;">string</span> <span style="color: #000000;">board</span><span style="color: #0000FF;">,</span> <span style="color: #000080;font-style:italic;">-- (81 characters)</span> |
|||
<span style="color: #000000;">solution</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">desc</span> |
|||
lt = length(tests), |
|||
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span> |
|||
run_one_test = 0 |
|||
<span style="color: #008080;">if</span> <span style="color: #000000;">run_one_test</span> <span style="color: #008080;">then</span> |
|||
<span style="color: #000000;">board</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">run_one_test</span><span style="color: #0000FF;">]</span> |
|||
constant l = " x x x | x x x | x x x ", |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">board</span><span style="color: #0000FF;">)</span> |
|||
s = "-------+-------+-------", |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">,</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">test_one</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">)</span> |
|||
l3 = join({l,l,l},"\n"), |
|||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">)!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> |
|||
fmt = substitute(join({l3,s,l3,s,l3},"\n"),"x","%c")&"\n" |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"solution:\n"</span><span style="color: #0000FF;">)</span> |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">fmt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">)</span> |
|||
procedure print_board(string board) |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
printf(1,fmt,board) |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s, %3.2fs\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">})</span> |
|||
end procedure |
|||
<span style="color: #008080;">else</span> |
|||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">lt</span> <span style="color: #008080;">do</span> |
|||
procedure test() |
|||
<span style="color: #004080;">atom</span> <span style="color: #000000;">t1</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span> |
|||
string board -- (81 characters) |
|||
<span style="color: #000000;">board</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tests</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> |
|||
string solution, desc |
|||
<span style="color: #0000FF;">{</span><span style="color: #000000;">solution</span><span style="color: #0000FF;">,</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">test_one</span><span style="color: #0000FF;">(</span><span style="color: #000000;">board</span><span style="color: #0000FF;">)</span> |
|||
atom t0 = time() |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">" \"%s\", -- (%3.2fs, %s)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">board</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">desc</span><span style="color: #0000FF;">})</span> |
|||
if run_one_test then |
|||
<span style="color: #000080;font-style:italic;">-- printf(1," \"%s\", -- (%3.2fs, %s)\n",{solution,time()-t1,desc})</span> |
|||
board = tests[run_one_test] |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
|||
print_board(board) |
|||
<span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span> |
|||
{solution,desc} = test_one(board) |
|||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d puzzles solved in %3.2fs (av %3.2fs)\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">lt</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">/</span><span style="color: #000000;">lt</span><span style="color: #0000FF;">})</span> |
|||
if length(solution)!=0 then |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span> |
|||
printf(1,"solution:\n") |
|||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span> |
|||
print_board(solution) |
|||
<span style="color: #000000;">test</span><span style="color: #0000FF;">()</span> |
|||
end if |
|||
<!--</lang>--> |
|||
printf(1,"%s, %3.2fs\n",{desc,time()-t0}) |
|||
else |
|||
for i=1 to lt do |
|||
atom t1 = time() |
|||
board = tests[i] |
|||
{solution,desc} = test_one(board) |
|||
printf(1," \"%s\", -- (%3.2fs, %s)\n",{board,time()-t1,desc}) |
|||
-- printf(1," \"%s\", -- (%3.2fs, %s)\n",{solution,time()-t1,desc}) |
|||
end for |
|||
t0 = time()-t0 |
|||
printf(1,"%d puzzles solved in %3.2fs (av %3.2fs)\n",{lt,t0,t0/lt}) |
|||
end if |
|||
end procedure |
|||
test()</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |