Tutorial 025 TOWERS OF HANOI - recursion to the
rescue.....
The Towers of Hanoi is an intriguing puzzle about which you can find
lots more on the net using Google. Here are several programs written to help
you understand its solution.
Richard Russell's clever demonstration program HANOI, written in 1982
for the BBC micro, is all over in a flash using BB4W on a modern PC. In
the following modification I have added PROCcontrol and the other unnumbered
lines so that its possible to see what's going on. Start with a small
number of discs if you are unfamiliar with the problem, which is to move
all the discs of a tapered tower from one postion to another in single
disc moves, which at no time place a larger disc on top of a smaller one.
Its worth rehearsing Towers of Hanoi away from the computer on the
kitchen table with suitable disclike objects (of increasing base radius)
on say three table mats to act as your "holders". (Tins, bottles and pill-boxes
will do very well). The three mats can be in an equilateral triangle as the
empty starting pegs' positions are essentially equivalent. Work up from two
discs; five discs take a very long time to solve. Allow several hours is
the advice given in "Computer science for A Level" by Ray Bradley, which made
me feel a lot better! The mind boggles....
You will see that the procedure employed below is recursive (it calls
itself) and by adding a counter I've made it easier to see that a number
of such calls occur before anything happens.
10 REM. "THE TOWERS OF HANOI"
20 REM. R.T.RUSSELL, 08-08-1982: BBC BASIC
:
REM: Unnumbered lines added by Richard
Weston 15-05-2003
REM: (and line 150 modified) to slow
down the display on a modern pc
REM: PROCcontrol added to give control
options
30 :
i=0
delay$=""
40 DIM DISC$(13),SIZE(3)
50 FOR DISC=1 TO 13
60 DISC$(DISC)=STRING$(DISC," ")+STR$DISC+STRING$(DISC,"
")
70 IF DISC>=10 DISC$(DISC)=MID$(DISC$(DISC),2)
80 DISC$(DISC)=CHR$17+CHR$(128+DISC-(DISC>7))+DISC$(DISC)+CHR$17+CHR$128
90 NEXT DISC
100 :
110 MODE 3
120 INPUT "Number of discs (1-13): "F
130 IF F>13 RUN
140 FOR N=F TO 1 STEP -1:PROCPUT(N,1):NEXT
150 PRINT TAB(0,1)"Press SPACE to start, halt and restart":A=GET
PRINTTAB(0,3)"Press q to finish quickly"
160 OFF
170 PROCHANOI(F,1,2,3)
180 PRINTTAB(0,22);
PRINT"Press SPACE to go again"
G=GET
RUN
190 END
200 ;
210 DEF PROCHANOI(A,B,C,D)
IF A=0 ENDPROC
PROCcontrol
220 PROCHANOI(A-1,B,D,C)
230 PROCTAKE(A,B):PROCPUT(A,C)
240 PROCHANOI(A-1,D,C,B)
250 ENDPROC
260 ;
270 DEF PROCPUT(DISC,PILE)
280 PRINTTAB(13+26*(PILE-1)-DISC,20-SIZE(PILE))DISC$(DISC);
290 SIZE(PILE)=SIZE(PILE)+1
300 ENDPROC
310 ;
320 DEF PROCTAKE(DISC,PILE)
330 SIZE(PILE)=SIZE(PILE)-1
340 PRINTTAB(13+26*(PILE-1)-DISC,20-SIZE(PILE))STRING$(2*DISC+1,"
");
350 ENDPROC
:
DEF PROCcontrol
i+=1
PRINTTAB(1,23);i
IF delay$<>"q" THEN
SOUND1,-8,i,1
delay$=INKEY$(80)
IF delay$=" " THEN
G=GET
ENDIF
ENDIF
ENDPROC
A simpler version, which just shows the moves, comes
from SG Brewer's (ageist!) "Program's in BBC Basic for Young Mathematicians"
:
REM: Hanoi
MODE8
VDU14:REM: paged mode on - use shift
key to scroll down
INPUT"Starting Pole; 1,2 or 3 : "A
INPUT"Finishing Pole; 1,2 or 3 : "B
REPEAT
i=0
INPUT"Number of discs :
"N
PROCswitch(N,A,B)
UNTIL FALSE
END
:
DEF PROCswitch(N,A,B)
C=6-A-B
IF N=1 THEN
PRINT A;".....";B
ELSE
PROCswitch(N-1,A,C)
PROCswitch(1,A,B)
PROCswitch(N-1,C,B)
ENDIF
ENDPROC
Here is the output for three discs:
Starting Pole; 1,2 or 3 : 1
Finishing Pole; 1,2 or 3 : 2
Number of discs : 3
1.....2
1.....3
2.....3
1.....2
3.....1
3.....2
1.....2
You see that it takes seven moves to reposition the three discs.
If necessary you can take such a printout to the kitchen table to
help you!
The following little program shows you how many
moves it takes to solve the problem as the number of discs increases:
REM:Tower of Hanoi
Moves
REM: Richard Weston afterJan Gulberg
("From the Birth of Numbers")
MODE8
PRINT'" Tower of Hanoi";
PRINT" - number of moves required
for n discs"
PRINT'TAB(9)"n"TAB(17)"moves"'
FOR n=1 TO 20
moves=(2^n)-1
PRINTn,moves
NEXT n
Here is the output copied from the display using Ctr-TAB :
Tower of Hanoi - number of moves required
for n discs
n
moves
1
1
2
3
3
7
4
15
5
31
6
63
7
127
8
255
9
511
10
1023
11
2047
12
4095
13
8191
14
16383
15
32767
16
65535
17 131071
18 262143
19 524287
20 1048575
You can check this out using Richard Russell's program, up to 13 discs.
The later ones will keep you busy at the kitchen table.
Recursion!
As an example of a very simple recursive program, to show you how such
programs act, here is one given by Jim McGregor and Alan Watt in their excellent
"Advanced Programming Techniques for the BBC Micro".
REM: Intro to recursion
REM: R Weston after McGregor & Watt
MODE8
INPUT'"Input a small integer : " n
PROCprintupto(n)
END
:
DEF PROCprintupto(n)
IF n=0 THEN ENDPROC
PROCprintupto(n-1)
PRINT n
ENDPROC
With an output:
Input a small integer : 6
1
2
3
4
5
6
By adding two extra lines:
REM: Intro to recursion
REM: R Weston after McGregor & Watt
MODE8
i=0
INPUT"Input a smallish integer : " n
PROCprintupto(n)
END
:
DEF PROCprintupto(n)
i=i+1
PRINT"Yes ";i
IF n=0 THEN ENDPROC
PROCprintupto(n-1)
PRINT n
ENDPROC
we get the output :
Input a smallish integer : 5
Yes 1
Yes 2
Yes 3
Yes 4
Yes 5
Yes 6
1
2
3
4
5
>
This shows how six calls are necessary to PROCprintupto before the condition
n=0 is met, then the process unwinds printing the required number sequence.
A cunning process of which more later....
Next Tutorial
Richard Weston's Homepage