Towers of Hanoi: Difference between revisions

Content added Content deleted
No edit summary
m (→‎{{header|REXX}}: added/changed whitespace and comments.)
Line 2,467: Line 2,467:
=={{header|REXX}}==
=={{header|REXX}}==
===simple text moves===
===simple text moves===
<lang rexx>/*REXX pgm shows the moves to solve the Tower of Hanoi (with 3 disks). */
<lang rexx>/*REXX program shows the moves to solve the Tower of Hanoi (with N towers).*/
parse arg N . /*get optional # towers from C.L.*/
parse arg N . /*get optional number of disks from CL.*/
if N=='' then N=3 /*Not given? Use default 3 towers*/
if N=='' then N=3 /*Not given? Then use default 3 towers*/
#=0; z=2**N - 1 /*number of ring moves so far. */
#=0; z=2**N - 1 /*# ring moves so far; # of min moves.*/
call mov 1, 3, N /*move top ring, then recurse··· */
call mov 1, 3, N /*move the top ring, then recurse ··· */
say
say
say 'The minimum number of moves to solve a ' N " Tower of Hanoi is " z
say 'The minimum number of moves to solve a ' N " Tower of Hanoi is " z
exit /*stick a fork in it, we're done.*/
exit /*stick a fork in it, we're all done. */
/*─────────────────────────────DSK subroutine───────────────────────────*/
/*─────────────────────────────DSK subroutine─────────────────────────────────*/
dsk: #=#+1 /*bump the move counter by one. */
dsk: #=#+1 /*bump the (ring) move counter by one. */
say 'step' right(#,length(z))": move disk on tower" arg(1) '───►' arg(2)
say 'step' right(#,length(z))": move disk on tower" arg(1) '───►' arg(2)
return /* [↑] display the move message (text)*/
return
/*─────────────────────────────MOV subroutine───────────────────────────*/
/*─────────────────────────────MOV subroutine─────────────────────────────────*/
mov: procedure expose # z; parse arg @1, @2, @3
mov: procedure expose # z; parse arg @1, @2, @3
if @3==1 then call dsk @1, @2
if @3==1 then call dsk @1, @2
Line 2,530: Line 2,530:


No attempt is made to explain this version of the REXX program 'cause of the complexity and somewhat obtuse features of the REXX language, the smallest of which is support for ASCII and EBCDIC "graphic" characters (glyphs). &nbsp; It may not be obvious from the pictorial display of the moves, but whenever a ring is moved from one tower to another, it is always the top ring that is moved &nbsp; (to the target tower).
No attempt is made to explain this version of the REXX program 'cause of the complexity and somewhat obtuse features of the REXX language, the smallest of which is support for ASCII and EBCDIC "graphic" characters (glyphs). &nbsp; It may not be obvious from the pictorial display of the moves, but whenever a ring is moved from one tower to another, it is always the top ring that is moved &nbsp; (to the target tower).
<lang rexx>/*REXX pgm shows pictorial moves to solve Tower of Hanoi (with N disks).*/
<lang rexx>/*REXX program shows pictorial moves to solve Tower of Hanoi (with N towers)*/
parse arg N .; if N=='' then N=3 /*Not given? Use default 3 disks.*/
parse arg N .; if N=='' then N=3 /*Not given? Then use default 3 disks.*/
sw=80; wp=sw%3-1; blanks=center('',wp) /*define some default variables. */
sw=80; wp=sw%3-1; blanks=left('',wp) /*define some default REXX variables. */
c.1=sw%3%2 /* [↑] SW: assume default Screen Width*/
c.1=sw%3%2
c.2=sw%2-1
c.2=sw%2-1
c.3=sw-1-c.1-1
c.3=sw-1-c.1-1
#=0; z=2**N-1; movek=z
#=0; z=2**N-1; moveK=z /*#moves; min# of moves; where to move.*/
@abc='abcdefghijklmnopqrstuvwxyN' /*dithering chars when many disks*/
@abc='abcdefghijklmnopqrstuvwxyN' /*dithering chars when many disks used.*/
ebcdic= 'f0'x==0 /*determine if EBCDIC or ASCII*/
ebcdic=('f0'x==0) /*determine if EBCDIC or ASCII machine.*/

if ebcdic then do
if ebcdic then do
bar='bf'x;ar='df'x;boxen='db9f9caf'x;tl='ac'x;tr='bf'x;bl='ab'x;br='bb'x;vert='fa'x;down='9a'x
bar='bf'x;ar='df'x;boxen='db9f9caf'x;tl='ac'x;tr='bf'x;bl='ab'x;br='bb'x;vert='fa'x;down='9a'x
Line 2,545: Line 2,546:
bar='c4'x;ar='10'x;boxen='b0b1b2db'x;tl='da'x;tr='bf'x;bl='c0'x;br='d9'x;vert='b3'x;down='19'x
bar='c4'x;ar='10'x;boxen='b0b1b2db'x;tl='da'x;tr='bf'x;bl='c0'x;br='d9'x;vert='b3'x;down='19'x
end
end
verts=vert || vert
downs=down || down
Tcorners=tl || tr
Bcorners=bl || br
box=left(boxen,1); boxchars=boxen || @abc
bararrow=bar || bar || ar
$.=0; $.1=N; k=N; kk=k+k


verts = vert || vert; Tcorners= tl || tr
do j=1 for N
downs = down || down; Bcorners= bl || br
@.3.j=blanks; @.2.j=blanks
box = left(boxen,1); boxchars=boxen || @abc; bararrow= bar || bar || ar
$.=0; $.1=N; k=N; kk=k+k

do j=1 for N; @.3.j=blanks; @.2.j=blanks
@.1.j=center(copies(box,kk),wp)
@.1.j=center(copies(box,kk),wp)
if N<=length(boxchars) then @.1.j=translate(@.1.j, ,
if N<=length(boxchars) then @.1.j=translate(@.1.j,,substr(boxchars,kk%2,1),box)
substr(boxchars,kk%2,1),box)
kk=kk-2
kk=kk-2
end /*j*/
end /*j*/
Line 2,565: Line 2,562:
say "The minimum number of moves to solve a " N ' Tower of Hanoi is ' z
say "The minimum number of moves to solve a " N ' Tower of Hanoi is ' z
exit
exit
/*─────────────────────────────MOV subroutine───────────────────────────*/
/*─────────────────────────────MOV subroutine─────────────────────────────────*/
mov: if arg(3)==1 then call rng arg(1) arg(2)
mov: if arg(3)==1 then call rng arg(1) arg(2)
else do
else do
Line 2,573: Line 2,570:
end
end
return
return
/*─────────────────────────────RNG subroutine───────────────────────────*/
/*─────────────────────────────RNG subroutine─────────────────────────────────*/
rng: parse arg from dest; #=#+1; pp=
rng: parse arg from dest; #=#+1; pp=
if from==1 then do
if from==1 then do
Line 2,579: Line 2,576:
pp=overlay(bar,pp,c.1+1,c.dest-c.1-1,bar)
pp=overlay(bar,pp,c.1+1,c.dest-c.1-1,bar)
pp=pp || tr
pp=pp || tr
end
if from==3 then do
pp=overlay(br,pp,c.3)
pp=overlay(bar,pp,c.dest+1,c.3-c.dest-1,bar)
pp=overlay(tl,pp,c.dest)
end
end
if from==2 then do
if from==2 then do
Line 2,599: Line 2,591:
end
end
end
end
if from==3 then do
say translate(pp,downs,Bcorners||Tcorners||bar); say overlay(movek,pp,1)
pp=overlay(br,pp,c.3)
say translate(pp,verts,Tcorners||Bcorners||bar)
pp=overlay(bar,pp,c.dest+1,c.3-c.dest-1,bar)
say translate(pp,downs,Tcorners||Bcorners||bar)
pp=overlay(tl,pp,c.dest)
movek=movek-1
end
say translate(pp,downs,Bcorners || Tcorners || bar); say overlay(moveK,pp,1)
say translate(pp,verts,Tcorners || Bcorners || bar)
say translate(pp,downs,Tcorners || Bcorners || bar)
moveK=moveK-1
$.from=$.from-1; $.dest=$.dest+1; _f=$.from+1; _t=$.dest
$.from=$.from-1; $.dest=$.dest+1; _f=$.from+1; _t=$.dest
@.dest._t=@.from._f; @.from._f=blanks
@.dest._t=@.from._f; @.from._f=blanks
call showtowers
call showtowers
return
return
/*─────────────────────────────SHOWTOWERS subroutine────────────────────*/
/*─────────────────────────────SHOWTOWERS subroutine──────────────────────────*/
showtowers: do j=N by -1 for N
showtowers: do j=N by -1 for N; _=@.1.j @.2.j @.3.j; if _\='' then say _
_=@.1.j @.2.j @.3.j; if _\='' then say _
end /*j*/
end /*j*/
return</lang>
return</lang>
{{out}}when the default input was used:
{{out}}when the default input was used: