Psychology Wiki
No edit summary
(ZxqYFJtu)
Line 1: Line 1:
  +
rIvRISJB
{{ExpPsy}}
 
  +
rIvRISJB
[[Image:Tower_of_Hanoi.jpeg|300px|thumb|A model set of the Towers of Hanoi (with 8 disks)]]
 
[[Image:Tower of Hanoi 4.gif|300px|thumb|An animated solution of the '''Tower of Hanoi''' puzzle for ''T(4,3)''.]]
 
The '''Tower of Hanoi''' or '''Towers of Hanoi''' is a [[mathematical game]] or [[puzzle]]. It consists of three pegs, and a number of disks of different sizes which can slide onto any peg. The puzzle starts with the disks neatly stacked in order of size on one peg, the smallest at the top, thus making a conical shape.
 
 
The objective of the puzzle is to move the entire stack to another peg, obeying the following rules:
 
 
* Only one disk may be moved at a time.
 
* Each move consists of taking the upper disk from one of the pegs and sliding it onto another peg, on top of the other disks that may already be present on that peg.
 
* No disk may be placed on top of a smaller disk.
 
 
== Origins ==
 
[[Image:Hanoi Flagtower.jpg|right|thumb|Flag Tower of Hanoi]]
 
The puzzle was invented by the French [[mathematician]] Édouard Lucas in [[1883]]. There is a legend about an Indian temple which contains a large room with three time-worn posts in it surrounded by 64 golden disks. The priests of [[Brahma]], acting out the command of an ancient prophecy, have been moving these disks, in accordance with the rules of the puzzle. According to the legend, when the last move of the puzzle is completed, the world will end. The puzzle is therefore also known as the Tower of Brahma puzzle. It is not clear whether Lucas invented this legend or was inspired by it. The Tower of Hanoi is a problem often used to teach beginning programming, in particular, as an example of a simple [[recursion|recursive algorithm]].
 
 
If the legend were true, and if the priests were able to move disks at a rate of one per second, using the smallest number of moves, it would take them 2<sup>64</sup>−1 seconds or roughly 600 billion years (operation taking place is <math>\frac{{2}^{64}-1}{60 \times 60 \times 24 \times 365.2425}</math>) .<ref>''1000 Play Thinks''.</ref> (In context, the universe is currently about 13.7 billion years old.)
 
 
There are many variations on this legend. For instance, in some tellings, the temple is a monastery and the priests are monks. The temple or monastery may be said to be in different parts of the world — including Hanoi, Vietnam, and may be associated with any [[religion]]. In some versions, other elements are introduced, such as the fact that the tower was created at the beginning of the world, or that the priests or monks may make only one move per day.
 
 
The Flag Tower of Hanoi may have served as the inspiration for the name.
 
 
== Solution ==
 
Most toy versions of the puzzle have 8 disks. The game seems impossible to many novices, yet is solvable with a simple [[algorithm]]:
 
 
===Simple solution===
 
The following solution is a simple solution for the toy puzzle.
 
 
Alternate moves between the smallest piece and a non-smallest piece. When moving the smallest piece, always move it in the same direction (either to the left or to the right, but be consistent). If there is no tower in the chosen direction, move it to the opposite end. When the turn is to move the non-smallest piece, there is only one legal move.
 
 
===Recursive solution===
 
<!-- TODO: This section needs copy-editing for tone, professionalism and clarity: edited/bolded .-->
 
As in many mathematical puzzles, finding a solution is made easier by solving a slightly more general problem: how to move a tower of h (h=height) disks from a starting peg '''f''' (f=from) onto a destination peg '''t''' (t=to), '''r''' being the remaining third peg and assuming '''t''' ≠ '''f'''. First, observe that the problem is symmetric for permutations of the names of the pegs ([[Symmetric group|symmetric group S<sub>''3''</sub>]]). If a solution is known moving from peg '''f''' to peg '''t''', then, by renaming the pegs, the same solution can be used for every other choice of starting and destination peg. If there is only one disk (or even none at all), the problem is trivial. If h=1, then simply move the disk from peg '''f''' to peg '''t'''. If h>1, then somewhere along the sequence of moves, the largest disk must be moved from peg '''f''' to another peg, preferably to peg '''t'''. The only situation that allows this move is when all smaller h-1 disks are on peg '''r'''. Hence, first all h-1 smaller disks must go from '''f''' to '''r'''. Subsequently move the largest disk and finally move the h-1 smaller disks from peg '''r''' to peg '''t'''. The presence of the largest disk does not impede any move of the h-1 smaller disks and can temporarily be ignored. Now the problem is reduced to moving h-1 disks from one peg to another one, first from '''f''' to '''r''' and subsequently from '''r''' to '''t''', but the same method can be used both times by renaming the pegs. The same strategy can be used to reduce the h-1 problem to h-2, h-3, and so on until only one disk is left. This is called [[recursion]]. This algorithm can be schematized as follows. Identify the disks in order of increasing size by the natural numbers from 0 up to but not including h. Hence disk 0 is the smallest one and disk h-1 the largest one.
 
 
The following is a procedure for moving a tower of h disks from a peg '''f''' onto a peg '''t''', with '''r''' being the remaining third peg:
 
*Step 1: If h>1 then first use this procedure to move the h-1 smaller disks from peg '''f''' to peg '''r'''.
 
*Step 2: Now the largest disk, i.e. disk h-1 can be moved from peg '''f''' to peg '''t'''.
 
*Step 3: If h>1 then again use this procedure to move the h-1 smaller disks from peg '''r''' to peg '''t'''.
 
 
By means of [[mathematical induction]], it is easily proven that the above procedure requires the minimal number of moves possible, and that the produced solution is the only one with this minimal number of moves.
 
 
Using [[recurrence relation]]s, the exact number of moves that this solution requires can be calculated by: <math>2^h - 1</math>. This result is obtained by noting that steps 1 and 3 take <math>T_{h-1}</math> moves, and step 2 takes one move, giving <math>T_h = 2T_{h-1} + 1</math>.
 
 
The algorithm can be written elegantly in various programming languages:
 
 
 
====Objective Caml====
 
<source lang="ocaml">
 
let rec move_tower n a b c = match n with
 
| 1 -> [(a,c)]
 
| _ -> (move_tower (n-1) a c b) @ (move_tower 1 a b c) @ (move_tower (n-1) b a c);;
 
</source>
 
 
====PL/I programming language====
 
hanoi:proc(n, f, t, u) recursive;
 
dcl(n, f, t, u) fixed bin(31);
 
if n > 0 then
 
do;
 
call hanoi(n-1, f, u, t);
 
call movedisk(f, t);
 
call hanoi(n-1, u, t, f);
 
end;
 
end hanoi;
 
 
movedisk:proc(f, t);
 
dcl (f, t) fixed bin(31);
 
put skip list('move' || f, '->' || t);
 
end movedisk;
 
 
====Solution from an arbitrary initial configuration====
 
 
To find the optimal solution from an arbitrary initial configuration, the algorithm can be generalized as follows:
 
 
In JavaScript (adapted from http://my.opera.com/sykora/blog/the-towers-of-hanoi):
 
<source lang='javascript'>
 
function transfer(numDiscs, source, destination, storage)
 
{
 
// If there is nothing to transfer, do nothing.
 
if (numDiscs == 0)
 
return;
 
 
//Transfer all but the last disc to the temporary storage location
 
transfer(numDiscs - 1, source, storage, destination);
 
 
//Transfer the last disc to the destination
 
document.writeln("Moving disc " + numDiscs + " from " + source + " to " + destination + "<br />");
 
 
//Transfer all but the last disc from the temporary storage to the destination
 
transfer(numDiscs - 1, storage, destination, source);
 
}
 
 
function main()
 
{
 
numDisks = prompt("Please enter the number of disks you want to use:", "");
 
source = 'A';
 
destination = 'C';
 
storage = 'B';
 
transfer(numDisks, source, destination, storage);
 
}
 
</source>
 
In Ruby:
 
<source lang='ruby'>
 
def transfer_discs(discs_id, source, destination, temporary)
 
if discs_id>0
 
transfer_discs(discs_id-1, source, temporary, destination)
 
puts("Moving disc #{discs_id} from #{source} to #{destination}")
 
transfer_discs(discs_id-1, temporary, destination, source)
 
end
 
return
 
end
 
 
print("input disc amount: ")
 
discs_amount=STDIN.gets
 
discs_amount=discs_amount.tr("\r\n", '')
 
while(/^[1-9][0-9]*$/.match(discs_amount)==nil)
 
puts("amount error")
 
print("input disc amount: ")
 
discs_amount=STDIN.gets
 
discs_amount=discs_amount.tr("\r\n", '')
 
end
 
discs_amount=discs_amount.to_i
 
flat_1_name="A"
 
flat_2_name="B"
 
flat_3_name="C"
 
transfer_discs(discs_amount, flat_1_name, flat_2_name, flat_3_name)
 
</source>
 
In Java:
 
<source lang='Java'>
 
public class Towers {
 
 
public static void main(String args[]) {
 
hanoi(2,"A","B","C");
 
}
 
 
//from, tmp, to
 
public static void hanoi(int n, String a, String b, String c) {
 
 
if (n==1) {
 
System.out.println("Moved from:"+a+" to "+ c);
 
}
 
else {
 
hanoi(n-1,a,c,b);
 
hanoi(1,a,b,c);
 
hanoi(n-1,b,a,c);
 
}
 
 
 
}
 
 
}
 
 
</source>
 
 
 
In Scheme:
 
<source lang='scheme'>
 
; Let conf be a list of the positions of the disks in order of increasing size.
 
; Let the pegs be identified by the numbers 0, 1 and 2.
 
(define (hanoi conf t)
 
(let ((c (list->vector conf)))
 
(define (move h f t)
 
(vector-set! c h t)
 
(printf "move disk ~s from peg ~s to peg ~s~n" h f t))
 
(define (third-peg f t) (- 3 f t))
 
(define (hanoi h t)
 
(if (> h 0)
 
(let ((h (sub1 h)))
 
(let ((f (vector-ref c h)))
 
(if (not (= f t))
 
(let ((r (third-peg f t)))
 
(hanoi h r)
 
(move h f t)))
 
(hanoi h t)))))
 
(hanoi (vector-length c) t)))
 
</source>
 
In C:
 
 
<source lang='C'>
 
int conf[HEIGHT]; /* Element conf[d] gives the current position of disk d. */
 
 
void move(int d, int t) {
 
/* move disk d to peg t */
 
conf[d] = t;
 
}
 
 
void hanoi(int h, int t) {
 
if (h > 0) {
 
int f = conf[h-1];
 
if (f != t) {
 
int r = 3 - f - t ;
 
hanoi(h-1, r);
 
move(h-1, t);
 
}
 
hanoi(h-1, t);
 
}
 
}
 
</source>
 
 
In PASCAL:
 
<source lang="pascal">
 
procedure Hanoi(n: integer; from, to, by: char);
 
Begin
 
if (n=1) then
 
writeln('Move the plate from ', from, ' to ', to)
 
else begin
 
Hanoi(n-1, from, by, to);
 
Hanoi(1, from, to, by);
 
Hanoi(n-1, by, to, from);
 
end;
 
End;
 
</source>
 
 
In Visual Basic.NET:
 
<source lang="vbnet">
 
Private Sub MoveDiscs(ByVal FromPost As String, ByVal ToPost As String, _
 
ByVal IntPost As String, ByVal N As Integer)
 
If N = 0 then
 
'Stopping case
 
lstMoves.Items.Add("Move disc 0 from post " + FromPost + " To Post" + ToPost)
 
Else
 
MoveDiscs(FromPost, IntPost, ToPost, N - 1)
 
lstMoves.Items.Add("Move disc" + Cstr(N) + " from post " + FromPost + _
 
"To Post" + ToPost)
 
MoveDiscs(IntPost, ToPost, FromPost, N - 1)
 
End If
 
End Sub
 
</source>
 
trbDiscs being a track bar to choose amount of discs
 
 
===Non-recursive solution===
 
The list of moves for a tower being carried from one peg onto another one, as produced by the recursive algorithm has many regularities. When counting the moves starting from 1, the ordinal of the disk to be moved during move ''m'' is the number of times ''m'' can be divided by 2. Hence every odd move involves the smallest disk. It can also be observed that the smallest disk traverses the pegs f, t, r, f, t, r, etc. for odd height of the tower and traverses the pegs f, r, t, f, r, t, etc. for even height of the tower. This provides the following algorithm, which is easier, carried out by hand, than the recursive algorithm.
 
 
In alternate moves:
 
* move the smallest disk to the peg it has not recently come from.
 
* move another disk legally (there will be one possibility only)
 
For the very first move, the smallest disk goes to peg t if h is odd and to peg r if h is even.
 
 
So if the number of disks is even the solution will start:
 
#Move disk 0 from peg f to peg r ignoring peg t.
 
#Move disk 1 from peg f to peg t ignoring peg r.
 
#Move disk 0 from peg r to peg t ignoring peg f.
 
#Move disk 2 from peg f to peg r ignoring peg t.
 
#Move disk 0 from peg t to peg f ignoring peg r.
 
#Move disk 1 from peg t to peg r ignoring peg f.
 
#Move disk 0 from peg f to peg r ignoring peg t.
 
#Move disk 3 from peg f to peg t ignoring peg r.
 
#Move disk 0 from peg r to peg t ignoring peg f.
 
#Move disk 1 from peg r to peg f ignoring peg t.
 
#Move disk 0 from peg t to peg f ignoring peg r.
 
#Move disk 2 from peg r to peg t ignoring peg f.
 
#Move disk 0 from peg f to peg r ignoring peg t.
 
#Move disk 1 from peg f to peg t ignoring peg r.
 
#Move disk 0 from peg r to peg t ignoring peg f.
 
#Move disk 4 from peg f to peg r ignoring peg t.
 
etc.
 
 
Also observe that:
 
* Disks whose ordinals have even parity move in the same sense as the smallest disk.
 
* Disks whose ordinals have odd parity move in opposite sense.
 
* If h is even, the remaining third peg during successive moves is t, r, f, t, r, f, etc.
 
* If h is odd, the remaining third peg during successive moves is r, t, f, r, t, f, etc.
 
 
===Binary solutions===
 
Disk positions may be determined more directly from the [[Binary numeral system|binary]] (base 2) representation of the move number (the initial state being move #0, with all digits 0, and the final state being #2<sup>''n''</sup>−1, with all digits 1), using the following rules:
 
* There is one binary digit ([[bit]]) for each disk
 
* The most significant (leftmost) bit represents the largest disk. A value of 0 indicates that the largest disk is on the initial peg, while a 1 indicates that it's on the final peg.
 
* The bitstring is read from left to right, and each bit can be used to determine the location of the corresponding disk.
 
* A bit with the same value as the previous one means that the corresponding disk is stacked on top the previous disk on the same peg.
 
** (That is to say: a straight sequence of 1's or 0's means that the corresponding disks are all on the same peg).
 
* A bit with a different value to the previous one means that the corresponding disk is one position to the left or right of the previous one. Whether it is left or right is determined by this rule:
 
** Assume that the initial peg is on the left and the final peg is on the right.
 
** Also assume "wrapping" - so the right peg counts as one peg "left" of the left peg, and vice versa.
 
** Let n be the number of greater disks that are located on the same peg as their first greater disk and add 1 if the largest disk is on the left peg. If n is even, the disk is located one peg to the left, if n is odd, the disk located one peg to the right.
 
 
For example, in an 8-disk Hanoi:
 
* Move #0)
 
** The largest disk is 0, so it is on the left (initial) peg.
 
** All other disks are 0 as well, so they are stacked on top of it. Hence all disks are on the initial peg.
 
* Move #2^8-1)
 
** The largest disk is 1, so it is on the right (final) peg.
 
** All other disks are 1 as well, so they are stacked on top of it. Hence all disks are on the final peg and the puzzle is complete.
 
* Move #0b11011000)
 
** The largest disk is 1, so it is on the right (final) peg.
 
** Disk two is also 1, so it is stacked on top of it, on the right peg.
 
** Disk three is 0, so it is on another peg. Since n is odd, it is one peg to the right, i.e. on the middle peg.
 
** Disk four is 1, so it is on another peg. Since n is still odd, it is one peg to the right, i.e. on the right peg.
 
** Disk five is also 1, so it is stacked on top of it, on the right peg.
 
** Disk six is 0, so it is on another peg. Since n is even, the disk is one peg to the left, i.e. on the middle peg.
 
** Disks seven and eight are also 0, so they are stacked on top of it, on the middle peg.
 
 
The above algorithm can be coded in Scheme as follows:
 
<source lang="scheme">
 
(define (conf m h f t) ; m=move number, h=height of tower, f=starting peg, t=destination peg
 
; Identify the pegs by the numbers 0, 1 and 2.
 
(let loop ((prev-zero? #t) (mask (arithmetic-shift 1 (sub1 h))) (rotation (- t f)) (f f))
 
(if (zero? mask) ()
 
(let ((zero-bit? (zero? (bitwise-and mask m))) (mask (arithmetic-shift mask -1)))
 
(if (eq? prev-zero? zero-bit?) (cons f (loop zero-bit? mask (- rotation) f))
 
(let ((f (modulo (+ f rotation) 3)))
 
(cons f (loop zero-bit? mask rotation f))))))))
 
 
; This procedure produces a list of the positions of the disks in order of decreasing size.
 
; Example:
 
 
(conf #e6022e20 80 0 2) ; in less than a milisecond on a plain 1.8 GHz personal computer:
 
;--> (01111111100001201201221111201112012000)
 
; #e6022e20 = 602, which is about the number of [[Avagadro]].
 
</source>
 
The source and destination pegs for the ''m''th move can also be found elegantly from the binary representation of ''m'' using [[bitwise operation]]s. To use the syntax of the [[C (programming language)|C programming language]], the ''m''th move is from peg <code>(m&m-1)%3</code> to peg <code>((m|m-1)+1)%3</code>, where the disks begin on peg 0 and finish on peg 1 or 2 according as whether the number of disks is even or odd. Furthermore the disk to be moved is determined by the number of times the move count (m) can be divided by 2 (i.e. the number of zero bits at the right), counting the first move as 1 and identifying the disks by the numbers 0, 1, 2 etc in order of increasing size. This permits a very fast non-recursive computer implementation to find the positions of the disks after m moves without reference to any previous move or distribution of disks:
 
<source lang="scheme">
 
; h : total number of disks
 
; m : move counter, starting with 1 for the first move.
 
; f : starting peg; the pegs are identified by the numbers 0, 1 and 2.
 
; t : destination peg
 
; d : disk (numbered 0, 1, 2, etc in order of increasing size)
 
; Function =quotient= takes two integer numbers and computes their quotient rounded to integer towards zero.
 
; (rot3 m) : sense of rotation of the remaining third peg during move m.
 
; (rotd d) : sense of rotation of disk d.
 
; mcnt : number of moves disk d has made after a total of m moves.
 
; from : the peg a disk is taken from during move m.
 
; onto : the peg a disk is put onto during move m.
 
; thrd : the remaining third peg. (- 3 from onto)
 
; disk : disk being moved.
 
; conf : position of disk d after a total of m moves.
 
 
(define (exp2 n ) (expt 2 n))
 
(define (mod2 n ) (modulo n 2))
 
(define (mod3 n ) (modulo n 3))
 
(define (pari n ) (add1 (mod2 (add1 n))))
 
(define (rotd h d f t) (mod3 (* (- t f) (pari (- h d)))))
 
(define (rot3 h f t) (rotd h 0 f t))
 
(define (mcnt m d ) (quotient (+ m (exp2 d)) (exp2 (add1 d))))
 
(define (thrd m h f t) (mod3 (- f (* m (rot3 h f t)))))
 
(define (onto m h f t) (mod3 (- (thrd m h f t) (rotd h (disk m) f t))))
 
(define (from m h f t) (mod3 (+ (thrd m h f t) (rotd h (disk m) f t))))
 
(define (conf m h d f t) (mod3 (+ f (* (rotd h d f t) (mcnt m d)))))
 
(define (disk m ) (sub1 (bit-count (bitwise-xor m (sub1 m)))))
 
</source>
 
 
===Gray code solution===
 
The [[binary numeral system]] of [[Gray code]]s gives an alternative way of solving the puzzle. In the Gray system, numbers are expressed in a binary combination of 0s and 1s, but rather than being a standard [[Numeral system|positional numeral system]], Gray code operates on the premise that each value differs from its predecessor by only one (and exactly one) bit changed. The number of bits present in Gray code is important, and leading zeros are not optional, unlike in positional systems.
 
 
If one counts in Gray code of a bit size equal to the number of disks in a particular Tower of Hanoi, begins at zero, and counts up, then the bit changed each move corresponds to the disk to move, where the least-significant-bit is the smallest disk and the most-significant-bit is the largest.
 
 
:Counting moves from 1 and identifying the disks by numbers starting from 0 in order of increasing size, the ordinal of the disk to be moved during move m is the number of times m can be divided by 2.
 
 
This technique identifies which disk to move, but not where to move it to. For the smallest disk there are always two possibilities. For the other disks there is always one possibility, except when all disks are on the same peg, but in that case either it is the smallest disk that must be moved or the objective has already been achieved. Luckily, there is a rule which does say where to move the smallest disk to. Let f be the starting peg, t the destination peg and r the remaining third peg. If the number of disks is odd, the smallest disk cycles along the pegs in the order f->t->r->f->t->r, etc. If the number of disks is even, this must be reversed: f->r->t->f->r->t etc. [http://occawlonline.pearsoned.com/bookbind/pubbooks/miller2_awl/chapter4/essay1/deluxe-content.html#tower]
 
 
==Long solutions==
 
A modification of the game can be to move the tower from one peg to another peg using as many moves as possible without ever producing the same distribution of disks more than once. A simple algorithm (written in Scheme) is:
 
 
<source lang="scheme">
 
(define (long-move-tower h f t r)
 
(if (positive? h)
 
(let ((h (sub1 h)))
 
(long-move-tower h f t r)
 
(move-disk h f r t)
 
(long-move-tower h t f r)
 
(move-disk h r t f)
 
(long-move-tower h f t r))))
 
</source>
 
 
Where procedure (move-disk d f t r) moves disk d from peg f onto peg t, ignoring peg r. The number of moves of this uniquely defined solution is 3<sup>height</sup>-1 and all 3<sup>height</sup> different distributions of disks are traversed (when including the starting and final distribution). This is called a Hamilton path. For this solution the disk to be moved can be found with a ternary gray code in a similar way as explained for the shortest solution. In fact there is a ternary Gray code starting with all digits 0 and ending with all digits equal 2, that lists the successive distributions of disks of a Hamilton path from peg 0 to peg 2 for a tower of h disks, each code showing the positions of the disks in decreasing order of size when read from left to right. This Gray code is uniquely defined by imposing the extra condition that each digit is switched more often than each more significant digit on the left. This is the code needed for the Tower of Hanoi.
 
 
<source lang="scheme">
 
(define (number->p-ary-gray-code n h p) ; n h p --> n-th h digit p-ary gray-code
 
(let ((2p (* 2 p)))
 
(let loop ((n n) (h h) (gc ()))
 
(if (zero? h) gc
 
(let ((q (quotient n p)) (r (modulo n 2p)))
 
(loop q (sub1 h) (cons (if (>= r p) (- 2p r 1) r) gc)))))))
 
 
(define (p-ary-gray-code->number gc p) ; n-th p-ary gray-code --> n
 
(let loop ((gc gc) (significance (expt p (sub1 (length gc)))))
 
(if (null? gc) 0
 
(let ((digit (car gc)) (gc (cdr gc)))
 
(let ((n (loop gc (quotient significance p))))
 
(+ (* digit significance)
 
(if (odd? digit) (- significance n 1) n)))))))
 
 
(define (number->hanoian-gray-code n h) (number->p-ary-gray-code n h 3))
 
(define (hanoian-gray-code->number gc) (p-ary-gray-code->number gc 3))
 
</source>
 
 
The disk to be moved is determined by the number of times the move counter can be divided by 3. Where the disk is to be moved to can easily be determined too. For every triplet of moves, move the smallest disk twice in succession in the same direction, followed by a move of one of the larger disks (only one direction possible) Between every triplet of moves reverse the direction of the smallest disk. The very first move of the smallest disk is to be made from the starting peg onto the remaining third peg. Also observe that the unused peg of each move alternates between the starting and destination peg. These statements are easily proven by mathematical induction.
 
 
<source lang="scheme">
 
(define (exp3 n ) (expt 3 n))
 
(define (mod3 n ) (modulo n 3))
 
(define (mod4 n ) (modulo n 4))
 
(define (mcnt m d ) (+ (* 2 (quotient m (exp3 (add1 d)))) (mod3 (quotient m (exp3 d)))))
 
(define (thrd m h f t) (if (odd? m) t f))
 
(define (onto m h f t) (posi m h (disk m) f t))
 
(define (from m h f t) (- 3 (onto m h f t) (thrd m h f t)))
 
(define (posi m h d f t) (vector-ref (vector f (- 3 f t) t (- 3 f t)) (mod4 (mcnt m d))))
 
(define (disk m) (if (zero? (mod3 m)) (add1 (disk (quotient m 3))) 0))
 
</source>
 
 
Another modification is to move a tower from a peg back to the same peg while traversing all distributions of disks. (circular Hamilton path) There are exactly two solutions, but they mirror each other in the sense that there is in fact one path that can be traversed in both directions. Obviously, the length of the path is 3<sup>height</sup>. A simple algorithm for the circular Hamilton path is:
 
 
<source lang="scheme">
 
(define (circular-hamilton-move-tower h a b c) ; h=height. a, b and c are the three pegs.
 
(if (positive? h) ; start with a tower at peg a, move tower to peg b, then to peg c and finally return to peg a.
 
(let ((h-1 (sub1 h)))
 
(hamilton-start h-1 a c b) ; The largest disk is moved three times.
 
(move-disk h-1 a b c) ; Between these moves the longest non selfcrossing path is used in order to move the
 
(long-move-tower h-1 c a b) ; partial tower consisting of the h-1 smaller disks from one peg onto another one.
 
(move-disk h-1 b c a) ; Together the procedures hamilton-start and hamilton-finish make such a longest
 
(long-move-tower h-1 a b c) ; non selfcrossing path too. The moves made by hamiton-finish followed by
 
(move-disk h-1 c a b) ; those of hamilton-start form a longest non selfcrossing path for the same
 
(hamilton-finish h-1 b a c)))); partial tower from peg b to peg c.
 
 
(define (hamilton-start h a b c)
 
(if (positive? h)
 
(let ((h-1 (sub1 h)))
 
(hamilton-start h-1 a c b)
 
(move-disk h-1 a b c)
 
(long-move-tower h-1 c b a))))
 
 
(define (hamilton-finish h a b c)
 
(if (positive? h)
 
(let ((h-1 (sub1 h)))
 
(long-move-tower h-1 a c b)
 
(move-disk h-1 a b c)
 
(hamilton-finish h-1 c b a))))
 
</source>
 
 
==Graphical representation==
 
The game can be represented by an undirected [[graph (mathematics)|graph]], the nodes representing distributions of disks and the branches representing moves. For one disk, the graph is a triangle:
 
 
/\
 
/__\
 
 
For h+1 disks, take the graph of h disks and replace each small triangle by:
 
 
/\
 
/__\
 
/ \
 
/ \
 
/\ /\
 
/__\ __ /__\
 
 
The above graph is for 2 disks. The angular points of the outermost triangle represent distributions with all disks on the same peg. For 3 disks the graph is:
 
 
ccc
 
/\ ; call the pegs a, b and c
 
acc /__\ bcc ; list disk positions from left to right in order of increasing size
 
/ \
 
abc / \ bac
 
/\ /\
 
bbc /__\ __ /__\ aac
 
/ cbc cac \
 
bba / \ aab
 
/\ /\
 
cba /__\aba bab/__\ cab
 
/ \ / \
 
caa / \aca bcb/ \ cbb
 
/\ /\ /\ /\
 
aaa /__\ __ /__\ __ /__\ __ /__\ bbb
 
baa bca cca ccb acb abb
 
 
Each side of the outermost triangle represent the shortest ways of moving a tower from one peg to another one. The branch in the middle of the sides of the largest triangle represents a move of the largest disk. The branch in the middle of the sides of each next smaller triangle represents a move of each next smaller disk. The sides of the smallest triangles represent moves of the smallest disk.
 
 
The longest non repetive way for three disks can be visualized by erasing the unused branches:
 
 
ccc
 
/\ ; call the pegs a, b and c
 
acc / \ bcc ; list disk positions from left to right in order of increasing size
 
/ \
 
abc / \ bac
 
\ /
 
bbc __\ /__ aac
 
/ cbc cac \
 
bba / \ aab
 
/ \
 
cba /__ aba bab __\ cab
 
\ /
 
caa \aca bcb/ cbb
 
/\ \ / /\
 
aaa / \ __ __\ /__ __ / \ bbb
 
baa bca cca ccb acb abb
 
 
The circular hamilton path for three disks is:
 
 
ccc
 
/\ ; call the pegs a, b and c
 
acc / \ bcc ; list disk positions from left to right in order of increasing size
 
/ \
 
abc / \ bac
 
\ /
 
bbc __\ /__ aac
 
/ cbc cac \
 
bba / \ aab
 
\ /
 
cba __\aba bab/__ cab
 
/ \
 
caa / aca bcb \ cbb
 
/ /\ /\ \
 
aaa /__ __ / \ __ / \ __ __\ bbb
 
baa bca cca ccb acb abb
 
 
The graphs clearly show that:
 
* From every arbitrary distribution of disks, there is exactly one shortest way to move all disks onto one of the three pegs.
 
* Between every pair of arbitrary distributions of disks there are one or two different shortest paths.
 
* From every arbitrary distribution of disks, there are one or two different longest non selfcrossing paths to move all disks to one of the three pegs.
 
* Between every pair of arbitrary distributions of disks there are one or two different longest non selfcrossing paths.
 
* Let N<sub>h</sub> be the number of non selfcrossing paths for moving a tower of h disks from one peg to another one. Then:
 
** N<sub>1</sub>=2
 
** N<sub>h+1</sub>=(N<sub>h</sub>)<sup>2</sup>+(N<sub>h</sub>)<sup>3</sup>.
 
** For example: N<sub>8</sub>≈1.5456x10<sup>795</sup>
 
 
== Applications ==
 
The Tower of Hanoi is frequently used in psychological research on [[problem solving]]. There also exists a variant of this task called [[Tower of London Test|Tower of London]] for neuropsychological diagnosis and treatment of executive functions.
 
 
The Tower of Hanoi is also used as [[Backup rotation scheme]] when performing computer data [[Backups]] where multiple tapes/media are involved.
 
 
As mentioned above, the Tower of Hanoi is popular for teaching recursive algorithms to beginning programming students. A pictorial version of this puzzle is programmed into the [[emacs]] editor, accessed by typing M-x hanoi. There is also a sample algorithm written in [[Prolog]].
 
 
The Tower of Hanoi is also used as a [[memory]] test by neuropsychologists trying to evaluate amnesia.
 
 
== Four pegs and beyond ==
 
Although the three-peg version has a simple recursive solution as outlined above, the ''optimal'' solution for the Tower of Hanoi problem with four or more pegs is still an [[open problem]]. This is a good example of how a simple, solvable problem can be made dramatically more difficult by slightly loosening one of the problem constraints.
 
 
The fact that the problem with four or more pegs is an open problem does not imply that no algorithm exists for finding (all of) the optimal solutions. Simply represent the game by an undirected graph, the nodes being distributions of disks and the edges being moves (of length 1) and use [[Dijkstra's algorithm]] to find one (or all) shortest paths moving a tower from one peg onto another one. However, even smartly implemented on the fastest computer now available, this algorithm provides no way of effectively computing solutions for large numbers of disks; the program would require more time and memory than available. Hence, even having an algorithm, it remains unknown how many moves an optimal solution requires and how many optimal solutions exist for 1000 disks and 10 pegs.
 
 
Though it is not known exactly how many moves must be made, there are some asymptotic results. There is also a "presumed-optimal solution" that can be recursively applied to find a solution - see [http://www.cs.wm.edu/~pkstoc/boca.ps Paul Stockmeyer's survey paper] for an explanation and some variants of the four-peg problem.
 
 
Although it agrees with computer experiments for small numbers of disks, there is not yet a general proof that this presumed-optimal solution is in fact optimal. However, [http://epubs.siam.org/sam-bin/dbq/article/43101 results in 2004] showed that the presumed-optimal solution must be of the same order of magnitude as the optimal solution.
 
 
=== Description of the presumed-optimal solution ===
 
The problem for four pegs is sometimes called "Reve's puzzle". ''A'' solution for four (or more) pegs, which has not been proved to be optimal, is described below:
 
* Let <math>n</math> be the number of disks.
 
* Let <math>r</math> be the number of pegs.
 
* Define <math>T(n,r)</math> to be the number of moves required to transfer n disks using r pegs
 
The algorithm can be described recursively:
 
# For some <math>k</math>, <math>1 \leq k < n</math>, transfer the top <math>k</math> disks to a single other peg, taking <math>T(k,r)</math> moves.
 
# Without disturbing the peg that now contains the top <math>k</math> disks, transfer the remaining <math>n-k</math> disks to the destination peg, using only the remaining <math>r-1</math> pegs, taking <math>T(n-k,r-1)</math> moves.
 
# Finally, transfer the top <math>k</math> disks to the destination peg, taking <math>T(k,r)</math> moves.
 
The entire process takes <math>2T(k,r)+T(n-k,r-1)</math> moves. Therefore, the count <math>k</math> should be picked for which this quantity is minimum. <br/>
 
This algorithm (with the above choice for <math>k</math>) is presumed to be optimal, and no counterexamples are known.
 
 
===Two stacks and more stacks===
 
 
A recent U.S. patent application discloses multistack Tower of Hanoi puzzles [Feb. 1, 2007, Serial No.11/701,454] with two or more stacks and twice as many pegs as stacks. After beginning on a particular peg, each stack displaces and is displaced by a different colored stack on another peg when the puzzle is solved. Disks of one color also have another peg that excludes all other colors, so that there are three pegs available for each color disk, two that are shared with other colors and one that is not shared. On the shared pegs, a disk may not be placed on a different colored disk of the same size, a possibility that does not arise in the standard puzzle.
 
 
The simplest multistack game (2 x 4) has two stacks and four pegs, and it requires 3[T(n)] moves to solve where T(n) is the number of moves needed to solve a single stack classic of n disks. The game proceeds in seesaw fashion with longer and longer series of moves that alternate between colors. It concludes in reverse seesaw fashion with shorter and shorter such series of moves. Starting with the second series of three moves, these alternate series of moves double in length for the first half of the game, and the lengths are halved as the game concludes. The solution involves nesting an algorithm suitable for Tower of Hanoi into an algorithm that indicates when to switch between colors. When there are k stacks of n disks apiece in a game, and k > 2, it requires k[T(n)] + T(n-1) moves to relocate them.
 
 
The addition of a centrally located universal peg open to disks from all stacks converts these multistack Tower of Hanoi puzzles to multistack Reve's puzzles as described in the preceding section. In these games each stack may move among four pegs, the same combination of three in the 2 x 4 game plus the central universal peg. The simplest game of this kind (2 x 5) has two stacks and five pegs. A solution conjectured to be optimal interlocks the optimal solution of the 2 x 4 puzzle with the presumed optimal solution to Reve's puzzle. It takes R(n) + 2R(n-1) + 2 moves, where R(n) is the number of moves in the presumed optimal Reve's solution for a stack of n disks.
 
 
== In popular culture ==
 
In the classic science fiction story ''Now Inhale'', by [[Eric Frank Russell]] (''Astounding Science Fiction'' April 1959, and in various anthologies), the human hero is a prisoner on a planet where the local custom is to make the prisoner play a game until it is won or lost, and then execution is immediate. The hero is told the game can be one of his own species', as long as it can be played in his cell with simple equipment strictly according to rules which are written down before and cannot change after play starts, and it has a finite endpoint. The game and execution are televised planet-wide, and watching the desperate prisoner try to spin the game out as long as possible is very popular entertainment; the record is sixteen days. The hero knows a rescue ship might take a year or more to arrive, so chooses to play Towers of Hanoi with 64 disks until rescue arrives. When the locals realize they've been had, they are angry, but under their own rules there is nothing they can do about it. They do change the rules, which will apply to any ''future'' prisoners. This story makes reference to the legend about the Buddhist monks playing the game until the end of the world, and refers to the game as '''arkymalarky'''. (The slang term "malarky", meaning nonsense, pre-dates this story by at least 30 years. [http://www.phrases.org.uk/bulletin_board/7/messages/555.html])
 
 
In the movie [[Stranger than Fiction (film)|Stranger than Fiction]], a miniature Towers of Hanoi puzzle can be seen on the cluttered desk of Professor Jules Hilbert.
 
 
In the ''[[Doctor Who]]'' serial "[[The Celestial Toymaker]]", the Toymaker challenges the Doctor to complete the "Trilogic Game" (ten disk Hanoi) in exactly 1,023 (2<sup>10</sup> − 1) moves.
 
 
There is a band named [http://www.towersofhanoi.org Towers of Hanoi].
 
 
=== In video games ===
 
The puzzle is featured regularly in [[Adventure game|adventure]] and [[Computer puzzle game|puzzle]] games. Since it is easy to implement, and easily-recognised, it is well-suited to use as a puzzle in a larger graphical game. Some implementations use straight disks, but others disguise the puzzle in some other form. What follows is a partial list of games which use the puzzle:
 
* [[Black & White (game)|Black & White]]
 
* [[Dr. Brain|The Island of Dr. Brain]]
 
* [[The Secret Island of Dr. Quandary]]
 
* [[Star Wars: Knights of the Old Republic]]
 
* [[Zork Zero]]
 
* [[The Legend of Kyrandia|The Legend of Kyrandia: Hand of Fate]]
 
* [[Escape from Paradise (game)|Escape from Paradise]]
 
* [[ECHO: Secrets of the Lost Cavern]]
 
* [[Clan Lord]]
 
* [[Mass Effect]]
 
 
==Notes==
 
<div class="references-small">
 
<references/>
 
</div>
 
 
==See also==
 
 
*[[Baguenaudier]]
 
*[[Recursion (computer science)]]
 
 
== External links ==
 
{{commonscat|Tower of Hanoi}}
 
 
===Online demonstrations===
 
* [http://www.raptivity.com/Demo%20Courses/Interactivity%20Builder%20Sample%20Course/Content/Booster%20Pack/HTML%20Pages/Towers%20of%20Hanoi.html Tower of Hanoi Interactivity] Raptivity Customizable Interaction Model(CIM) for the Tower of Hanoi.
 
* [http://funmin.com/online-games/tower-of-hanoi/index.php Tower Of Hanoi Game developed using Javascript ]
 
* [http://chemeng.p.lodz.pl/zylla/games/hf.html A JavaScript implementation featuring Shuffle disks and Help buttons ]
 
* [http://illuminations.nctm.org/ActivityDetail.aspx?ID=40 An online Java demonstration of this famous puzzle: allows trying to solve for up to 20 disks, or lets the computer solve.]
 
* [http://www.hanoitower.info/ An online flash demonstration of this famous puzzle: allows trying to solve for n disks (with n being a maximum of ten disks)].
 
* [http://www-mat.pfmb.uni-mb.si/personal/petr/hanoi/graphs/index.htm Multipeg Tower of Hanoi Graphs].
 
* [http://www.daftlogic.com/projects-towers-of-hanoi.htm Simple 4 disk demonstration of Towers of Hanoi].
 
* [http://www.cheesygames.com/hanoi Tower of Hanoi implement in Java].
 
* [http://www.mathapplets.net A Multi-Peg Tower of Hanoi Applet].
 
* [http://www.jimloy.com/puzz/hanoi0.htm Tower Of Hanoi Animation].
 
* [http://www.novelgames.com/flashgames/game.php?id=31 Tower of Hanoi Flash Game]: a Flash implementation of the Tower of Hanoi game.
 
* [http://www.walkingideas.com/oshiro Oshiro]: A flash game with Tower of Hanoi concept incorporated with colors, different board, and different end goals.
 
* ''[http://demonstrations.wolfram.com/TowersOfHanoi/ Towers of Hanoi]'' by Jay Warendorff based on a program by Jaime Rangel-Mondragón, [[The Wolfram Demonstrations Project]].
 
 
===History===
 
* [http://www.lawrencehallofscience.org/Java/Tower/towerhistory.html Tower of Hanoi Facts]
 
 
===Algorithm===
 
* [http://www.cut-the-knot.org/Curriculum/Combinatorics/TowerOfHanoi.shtml Theory, recursive and a per step algorithms with Java implementation] at [[cut-the-knot]]
 
* [http://24bytes.com/Towers-Of-Hanoi.html Towers Of Hanoi in c++ using Stacks ] at [[24bytes]]
 
 
* [http://www.cut-the-knot.org/Curriculum/Combinatorics/BiColorTowerOfHanoi.shtml Bicolor Tower of Hanoi] at [[cut-the-knot]]
 
* [http://www.kernelthread.com/hanoi/ Hanoimania, implementations of the Tower of Hanoi problem in over 100 different programming environments and languages]
 
* [http://math.bu.edu/DYSYS/applets/hanoi.html Towers of Hanoi Online game]<!--site goobix.com no longer exists-->
 
* [http://www.farfarfar.com/games/towers_of_hanoi/ Play Towers of Hanoi Online]
 
*[http://occawlonline.pearsoned.com/bookbind/pubbooks/miller2_awl/chapter4/essay1/deluxe-content.html#tower Binary Numbers and the Standard Gray Code, with a diskussion of the Gray Code solution]
 
* [http://hanoitower.mkolar.org/ Some implementations including a mysterious binary solution]
 
* [http://www.jsjsoftware.com/product.php?id=16 Tower of Hanoi game for Palm OS]
 
* [http://www.telefonica.net/web2/koot/hanoi.doc A variety of Tower of Hanoi Algorithms in PLT MzScheme]
 
* [http://www.quitebasic.com/prj/puzzle/towers-of-hanoi/ Solution in an all web-based interactive classical BASIC environment]
 
* [http://www.datastructures.info/the-towers-of-hanoi/ Two non-recursive solutions in C++]
 
 
===Events===
 
 
 
 
 
<!--
 
{{Link FA|he}}
 
 
[[bg:Ханойска кула]]
 
[[ca:Torres de Hanoi]]
 
[[da:Hanois tårn]]
 
[[de:Türme von Hanoi]]
 
[[es:Torres de Hanoi]]
 
[[eo:Turoj de Hanojo]]
 
[[eu:Hanoiko Dorreak]]
 
[[fr:Tours de Hanoï]]
 
[[ko:하노이의 탑]]
 
[[id:Menara Hanoi]]
 
[[is:Turninn í Hanoi]]
 
[[it:Torre di Hanoi]]
 
[[he:מגדלי האנוי]]
 
[[lb:Hanoi-Tuerm]]
 
[[nl:Torens van Hanoi]]
 
[[ja:ハノイの塔]]
 
[[pl:Wieże Hanoi]]
 
[[pt:Torre de Hanoi]]
 
[[ru:Ханойская башня]]
 
[[sl:Hanojski stolpi]]
 
[[fi:Hanoin torni]]
 
[[sv:Tornen i Hanoi]]
 
[[th:หอคอยแห่งฮานอย]]
 
[[vi:Tháp Hà Nội (bài toán)]]
 
[[tr:Hanoi kuleleri]]
 
[[zh:河內塔]]
 
-->
 
{{enWP|Tower of Hanoi}}
 
[[Category:Problem solving]]
 

Revision as of 13:39, 7 September 2010

rIvRISJB rIvRISJB