Towers of Hanoi: Difference between revisions

Content added Content deleted
Line 1,197: Line 1,197:


The minimum number of moves to solve a 5 ring Tower of Hanoi is 31.
The minimum number of moves to solve a 5 ring Tower of Hanoi is 31.
</pre>
===version 2===
This version pictorially shows the moves for solving the Town of Hanoi.
<br>
Quite a bit of code has been dedicated to showing a picture of the
towers with the disks on them, and the movement of the disk (the move).
<br>
In addition, it shows each move in a countdown manner (the last move is
move #1).
<br>
No attempt is mode to explain this REXX code because of the complexity
and somewhat obtuse features of the REXX language, the smallest of which
is support for ASCII and EBCDIC "graphic" characters.
</lang>
/*REXX program pictorially shows moves for solving the Tower of Hanoi. */

arg z .
if z=='' then z=3
sw=80
wp=sw%3-1
c.1=sw%3%2
c.2=sw%2-1
c.3=sw-1-c.1-1
move=0
totmoves=2**z-1
movek=totmoves
lentot=length(totmoves)
@abc='abcdefghijklmnopqrstuvwxyz'
ebcdic='f0'x==0

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
end
else do
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

verts=vert||vert
downs=down||down
Tcorners=tl||tr
Bcorners=bl||br
box=left(boxen,1)
boxchars=boxen||@abc
bararrow=bar||bar||ar
$.1=z
$.2=0
$.3=0
k=z
kk=k+k
blanks=centre('',wp)
call sayhdr 1

do j=1 for z
@.3.j=blanks
@.2.j=blanks
@.1.j=centre(copies(box,kk),wp)
if z<=length(boxchars) then @.1.j=,
translate(@.1.j,substr(boxchars,kk%2,1),box)
kk=kk-2
end

call showtowers
call mov 1,3,z
call sayhdr 2
exit



/*─────────────────────────────MOV subroutine───────────────────────────*/
mov: if arg(3)==1 then call rng arg(1) arg(2)
else do
call mov arg(1),6-arg(1)-arg(2),arg(3)-1
call mov arg(1),arg(2),1
call mov 6-arg(1)-arg(2),arg(2),arg(3)-1
end
return


/*─────────────────────────────RNG subroutine───────────────────────────*/
rng: parse arg from dest
move=move+1
pp=

if from==1 then do
pp=overlay(bl,pp,c.1)
pp=overlay(bar,pp,c.1+1,c.dest-c.1-1,bar)
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
if from==2 then do
lpost=min(2,dest)
hpost=max(2,dest)

if dest==1 then do
pp=overlay(tl,pp,c.1)
pp=overlay(bar,pp,c.1+1,c.2-c.1-1,bar)
pp=pp||br
end

if dest==3 then do
pp=overlay(bl,pp,c.2)
pp=overlay(bar,pp,c.2+1,c.3-c.2-1,bar)
pp=pp||tr
end

end

say translate(pp,verts,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
@.dest._t=@.from._f
@.from._f=blanks
call showtowers
return


/*═════════════════════════════general 1-line subs══════════════════════*/
sayhdr:parse arg x;if x==1 then call saysep;call sayMinMov;say;if x==2 then call saysep;return
sayMinMov:say
_="The minimum number of moves for a" z 'ring Tower of Hanoi is'
say centre(_ totmoves,sw-1,bar);return
saysep:say copies(bar,sw-1);return
showtowers:do j=z to 1 by -1;_p=@.1.j @.2.j @.3.j;if _p\='' then say _p;end;return
</lang>
Output:
<pre style="height:30ex;overflow:scroll">

@@@@@@@@@@@@@@@@@@

</pre>
</pre>