Solve a Hidato puzzle: Difference between revisions

Content added Content deleted
m (added whitespace before the TOC.)
m (→‎{{header|REXX}}: changed/added comments and whitespace, changed indentations.)
Line 2,800: Line 2,800:
<br>If ''any'' marker is negative, then it's assumed to be a Numbrix puzzle (and the absolute value is used).
<br>If ''any'' marker is negative, then it's assumed to be a Numbrix puzzle (and the absolute value is used).
<br>Over half of the REXX program deals with validating the input and displaying the puzzle.
<br>Over half of the REXX program deals with validating the input and displaying the puzzle.
<br><br>''Hidato'' and ''Numbrix'' are registered trademarks.
<lang rexx>/*REXX pgm solves a Hidato or Numbrix puzzle, displays puzzle & solution*/
maxr=0; maxc=0; maxx=0; minr=9e9; minc=9e9; minx=9e9; cells=0; @.=
parse arg xxx; PZ='Hidato puzzle' /*get cell definitions from C.L. */
xxx=translate(xxx, , "/\;:_", ',') /*also allow other chars as comma*/


''Hidato'' &nbsp; and &nbsp; ''Numbrix'' &nbsp; are registered trademarks.
do while xxx\=''; parse var xxx r c marks ',' xxx
<lang rexx>/*REXX program solves a Numbrix (R) puzzle, it also displays the puzzle and solution. */
do while marks\=''; _=@.r.c
maxR=0; maxC=0; maxX=0; minR=9e9; minC=9e9; minX=9e9; cells=0; @.=
parse arg xxx; PZ='Hidato puzzle' /*get the cell definitions from the CL.*/
xxx=translate(xxx, , "/\;:_", ',') /*also allow other characters as comma.*/

do while xxx\=''; parse var xxx r c marks ',' xxx
do while marks\=''; _=@.r.c
parse var marks x marks
parse var marks x marks
if datatype(x,'N') then do; x=x/1 /*normalize X*/
if datatype(x,'N') then do; x=x/1 /*normalize X*/
if x<0 then PZ='Numbrix puzzle'
if x<0 then PZ= 'Numbrix puzzle'
x=abs(x) /*use │x│ */
x=abs(x) /*use │x│ */
end
end
minr=min(minr,r); maxr=max(maxr,r)
minR=min(minR,r); maxR=max(maxR,r); minC=min(minC,c); maxC=max(maxC,c)
minc=min(minc,c); maxc=max(maxc,c)
if x==1 then do; !r=r; !c=c; end /*the START cell. */
if x==1 then do; !r=r; !c=c; end /*start cell.*/
if _\=='' then call err "cell at" r c 'is already occupied with:' _
if _\=='' then call err "cell at" r c 'is already occupied with:' _
@.r.c=x; c=c+1; cells=cells+1 /*assign a mark. */
@.r.c=x; c=c+1; cells=cells+1 /*assign mark*/
if x==. then iterate /*is a hole? Skip*/
if x==. then iterate /*hole? Skip.*/
if \datatype(x,'W') then call err 'illegal marker specified:' x
if \datatype(x,'W') then call err 'illegal marker specified:' x
minx=min(minx,x); maxx=max(maxx,x) /*min & max X*/
minX=min(minX,x); maxX=max(maxX,x) /*min and max X. */
end /*while marks¬='' */
end /*while marks¬='' */
end /*while xxx ¬='' */
end /*while xxx ¬='' */
call showGrid /* [↓] used for making fast moves*/
call show /* [↓] is used for making fast moves. */
Nr = '0 1 0 -1 -1 1 1 -1' /*possible row for the next move.*/
Nr = '0 1 0 -1 -1 1 1 -1' /*possible row for the next move. */
Nc = '1 0 -1 0 1 -1 1 -1' /* " col " " " " */
Nc = '1 0 -1 0 1 -1 1 -1' /* " column " " " " */
pMoves=words(Nr) -4*(left(PZ,1)=='N') /*is this to be a Numbrix puzzle?*/
pMoves=words(Nr) -4*(left(PZ,1)=='N') /*is this to be a Numbrix puzzle ? */
do i=1 for pMoves; Nr.i=word(Nr,i); Nc.i=word(Nc,i); end /*fast moves*/
do i=1 for pMoves; Nr.i=word(Nr,i); Nc.i=word(Nc,i); end /*for fast moves. */
if \next(2,!r,!c) then say 'No solution possible for this' PZ "puzzle."
if \next(2,!r,!c) then call err 'No solution possible for this' PZ "puzzle."
else say 'A solution for the' PZ "exists."
say 'A solution for the' PZ "exists."; say; call show
say; call showGrid
exit /*stick a fork in it, we're done.*/
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────ERR subroutine──────────────────────*/
err: say; say '***error!*** (from' PZ"): " arg(1); say; exit 13
err: say; say '***error*** (from' PZ"): " arg(1); say; exit 13
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────NEXT subroutine─────────────────────*/
next: procedure expose @. Nr. Nc. cells pMoves; parse arg #,r,c; ##=#+1
next: procedure expose @. Nr. Nc. cells pMoves; parse arg #,r,c; ##=#+1
do t=1 for pMoves /* [↓] try some moves.*/
do t=1 for pMoves /* [↓] try some moves. */
parse value r+Nr.t c+Nc.t with nr nc /*next move coördinates*/
parse value r+Nr.t c+Nc.t with nr nc /*next move coördinates.*/
if @.nr.nc==. then do; @.nr.nc=# /*a move.*/
if @.nr.nc==. then do; @.nr.nc=# /*let's try this move. */
if #==cells then leave /*last 1?*/
if #==cells then leave /*is this the last move?*/
if next(##,nr,nc) then return 1
if next(##,nr,nc) then return 1
@.nr.nc=. /*undo the above move. */
@.nr.nc=. /*undo the above move. */
iterate /*go & try another move*/
iterate /*go & try another move.*/
end
end
if @.nr.nc==# then do /*is this a fill-in ? */
if @.nr.nc==# then do /*this a fill-in move ? */
if #==cells then return 1 /*last 1.*/
if #==cells then return 1 /*this is the last move.*/
if next(##,nr,nc) then return 1 /*fill-in*/
if next(##,nr,nc) then return 1 /*a fill-in move. */
end
end
end /*t*/
end /*t*/
return 0 /*This ain't working. */
return 0 /*this ain't working. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
/*──────────────────────────────────SHOWGRID subroutine─────────────────*/
showGrid: if maxr<1 | maxc<1 then call err 'no legal cell was specified.'
show: if maxR<1 | maxC<1 then call err 'no legal cell was specified.'
if minx<1 then call err 'no 1 was specified for the puzzle start'
if minX<1 then call err 'no 1 was specified for the puzzle start'
w=max(2,length(cells)); do r=maxR to minR by -1; _=
if maxx\==cells then call err 'no' cells "was specified for the puzzle end"
do c=minC to maxC; _=_ right(@.r.c,w); end /*c*/
w=length(cells); do r=maxr to minr by -1; _=
do c=minc to maxc; _=_ right(@.r.c,w); end /*c*/
say _
say _
end /*r*/
end /*r*/
say; return</lang>
'''output''' &nbsp; when using the following as input:
say; return</lang>
'''output''' using the following as input:
<br> <tt> 1 7 5 .\2 5 . 7 . .\3 3 . . 18 . .\4 1 27 . . . 9 . 1\5 1 . 26 . 13 40 11\6 1 . . . 21 . .\7 1 . . 24 22 .\8 1 . 33 35 . .</tt>
<br> <tt> 1 7 5 .\2 5 . 7 . .\3 3 . . 18 . .\4 1 27 . . . 9 . 1\5 1 . 26 . 13 40 11\6 1 . . . 21 . .\7 1 . . 24 22 .\8 1 . 33 35 . .</tt>
<pre>
<pre>