Towers of Hanoi: Difference between revisions

m
much cleaning up
mNo edit summary
m (much cleaning up)
Line 1:
{{task|Classic CS problems and programs}}[[Category:Recursion]][[Category:Games]][[Category:Classic CS problems and programs]]In this task, the goal is to solve the [[wp:Towers_of_Hanoi|Towers of Hanoi]] problem with recursion.
In this task, the goal is to solve the [[wp:Towers_of_Hanoi|Towers of Hanoi]] problem with recursion.
 
=={{header|ActionScript}}==
Line 111 ⟶ 112:
{{trans|Logo}}
<lang AWK>$ awk 'func hanoi(n,f,t,v){if(n>0){hanoi(n-1,f,v,t);print(f,"->",t);hanoi(n-1,v,t,f)}}
BEGIN{hanoi(4,"left","middle","right")}'</lang>
{{out}}
left -> right
<pre>left -> right
left -> middle
right -> middle
Line 126 ⟶ 128:
left -> right
left -> middle
right -> middle</langpre>
 
=={{header|BASIC}}==
{{works with|FreeBASIC}}
{{works with|RapidQ}}
<lang freebasic>SUB move (n AS Integer, fromPeg AS Integer, toPeg AS Integer, viaPeg AS Integer)
<lang freebasic>
SUB move (n AS Integer, fromPeg AS Integer, toPeg AS Integer, viaPeg AS Integer)
IF n>0 THEN
move n-1, fromPeg, viaPeg, toPeg
Line 140 ⟶ 141:
END SUB
 
move 4,1,2,3</lang>
</lang>
 
Here's an example of implementing recursion in an old BASIC that only has global variables:
 
{{works with|Commodore_BASIC}}
<lang freebasic>10 DIM N(1024), F(1024), T(1024), V(1024): REM STACK PER PARAMETER
Line 275 ⟶ 273:
 
=={{header|Clojure}}==
 
<lang lisp>(defn towers-of-hanoi [n from to via]
(if (= n 1)
Line 285 ⟶ 282:
 
=={{header|CoffeeScript}}==
<lang coffeescript>hanoi = (ndisks, start_peg=1, end_peg=3) ->
 
<lang coffeescript>
hanoi = (ndisks, start_peg=1, end_peg=3) ->
if ndisks
staging_peg = 1 + 2 + 3 - start_peg - end_peg
Line 294 ⟶ 289:
hanoi(ndisks-1, staging_peg, end_peg)
hanoi(4)</lang>
</lang>
 
 
=={{header|Common Lisp}}==
 
<lang lisp>(defun move (n from to via)
(cond ((= n 1)
Line 323 ⟶ 315:
hanoi(3, 'L', 'M', 'R');
}</lang>
{{out}}
Output:
<pre>Move disk 1 from L to M
Move disk 2 from L to R
Line 331 ⟶ 323:
Move disk 2 from R to M
Move disk 1 from L to M</pre>
 
===Iterative===
Fast iterative version. See: [http://hanoitower.mkolar.org/shortestTHalgo.html The shortest and "mysterious" TH algorithm]
Line 377 ⟶ 368:
}
}</lang>
{{out}}
Output:
<pre>| 3 2 1
|
Line 425 ⟶ 416:
 
hanoi(3,3,1,2);
}</lang>
}
{{out}}
</lang>
Output:
<pre>move 1 ---> 3
move 1 ---> 2
Line 436 ⟶ 426:
move 1 ---> 3
</pre>
 
=={{header|Dc}}==
From [http://se.aminet.net/pub/OpenBSD/src/regress/usr.bin/dc/t20.in Here]
Line 519 ⟶ 510:
 
=={{header|E}}==
 
<lang e>def move(out, n, fromPeg, toPeg, viaPeg) {
if (n.aboveZero()) {
Line 548 ⟶ 538:
 
move(3, "left", "right", "middle")</lang>
{{out}}
 
Output:
<pre>Move disk 1 from the left pole to the right pole
Move disk 2 from the left pole to the middle pole
Line 559 ⟶ 548:
</pre>
 
=={{header|F sharp|F#}}==
<lang fsharp>#light
let rec hanoi num start finish =
Line 603 ⟶ 592:
=={{header|Forth}}==
With locals:
 
<lang forth>CREATE peg1 ," left "
CREATE peg2 ," middle "
Line 617 ⟶ 605:
n 1- via to from RECURSE
THEN ;</lang>
 
Without locals, executable pegs:
 
<lang forth>: left ." left" ;
: right ." right" ;
Line 656 ⟶ 642:
 
END PROGRAM TOWER</lang>
 
=={{header|GAP}}==
<lang gap>Hanoi := function(n)
Line 689 ⟶ 676:
 
=={{header|Go}}==
<lang go>package main
package main
 
import "fmt"
Line 731 ⟶ 717:
func (t *towers) move1(from, to int) {
fmt.Println("move disk from rod", from, "to rod", to)
}</lang>
}
</lang>
 
=={{header|Groovy}}==
Line 753 ⟶ 738:
moveStack(tail(using, n-1), to, from)
}</lang>
 
Test program:
<lang groovy>enum Ring {
Line 771 ⟶ 755:
 
=={{header|Haskell}}==
 
Most of the programs on this page use an imperative approach (i.e., print out movements as side effects during program execution). Haskell favors a purely functional approach, where you would for example return a (lazy) list of movements from a to b via c:
 
<lang haskell>hanoi :: Integer -> a -> a -> a -> [(a, a)]
hanoi 0 _ _ _ = []
hanoi n a b c = hanoi (n-1) a c b ++ [(a,b)] ++ hanoi (n-1) c b a</lang>
 
One can use this function to produce output, just like the other programs:
 
<lang haskell>hanoiIO n = mapM_ f $ hanoi n 1 2 3 where
f (x,y) = putStrLn $ "Move " ++ show x ++ " to " ++ show y</lang>
 
Or, instead one can of course also program imperatively, using the IO monad directly:
 
<lang haskell>hanoiM :: Integer -> IO ()
hanoiM n = hanoiM' n 1 2 3 where
Line 793 ⟶ 771:
hanoiM' (n-1) c b a</lang>
 
== {{header|Icon}} and {{header|Unicon }}==
The following is based on a solution in the Unicon book.
==={{header|Icon}}===
<lang Icon>procedure main(arglist)
hanoi(arglist[1]) | stop("Usage: hanoi n\n\rWhere n is the number of disks to move.")
Line 819 ⟶ 796:
return
end</lang>
 
==={{header|Unicon}}===
This Icon solution works in Unicon.
 
=={{header|Inform 7}}==
Line 881 ⟶ 855:
'''Solutions'''
<lang j>H =: i.@,&2 ` (({&0 2 1,0 2,{&1 0 2)@$:@<:) @. * NB. tacit using anonymous recursion</lang>
'''{{out|Example use'''}}
<lang j> H 3
0 2
Line 891 ⟶ 865:
2 0</lang>
The result is a 2-column table; a row <tt>i,j</tt> is interpreted as: move a disk (the top disk) from peg <tt>i</tt> to peg<tt> j</tt> .
 
Or, using explicit rather than implicit code:
 
<lang j>H1=: monad define NB. explicit equivalent of H
if. y do.
Line 901 ⟶ 873:
end.
)</lang>
 
The usage here is the same:
 
<pre> H1 2
0 1
0 2
1 2</pre>
;Alternative solution
 
'''Alternative solution'''<br>
If a textual display is desired, similar to some of the other solutions here (counting from 1 instead of 0, tracking which disk is on the top of the stack, and of course formatting the result for a human reader instead of providing a numeric result):
 
<lang J>hanoi=: monad define
moves=. H y
Line 917 ⟶ 885:
('move disk ';' from peg ';' to peg ');@,."1 ":&.>disks,.1+moves
)</lang>
{{out|Demonstration}}
 
For example:
<lang J> hanoi 3
move disk 1 from peg 1 to peg 3
Line 929 ⟶ 896:
 
=={{header|Java}}==
 
<lang java>public void move(int n, int from, int to, int via) {
if (n == 1) {
Line 980 ⟶ 946:
2:1->2
1:3->2</lang>
 
The disk to move in the i'th step is the same as the position of the leftmost 1 in the binary representation of 1..2^n.
<lang K> s:();{[n;a;b;c]if[n>0;_f[n-1;a;c;b];s,:n;_f[n-1;c;b;a]]}[4;1;2;3];s
Line 990 ⟶ 955:
=={{header|Liberty BASIC}}==
This looks much better with a GUI interface.
<lang lb> source$ ="A"
source$ ="A"
via$ ="B"
target$ ="C"
Line 1,009 ⟶ 973:
end sub
 
end</lang>
</lang>
 
 
=={{header|Logo}}==
Line 1,054 ⟶ 1,016:
 
=={{header|Lua}}==
<lang Lua>function move(n, src, dst, via)
function move(n, src, dst, via)
if n > 0 then
move(n - 1, src, via, dst)
Line 1,063 ⟶ 1,024:
end
 
move(4, 1, 2, 3)</lang>
</lang>
 
 
=={{header|Mathematica}}==
Line 1,075 ⟶ 1,034:
 
=={{header|MATLAB}}==
 
This is a direct translation from the Python example given in the Wikipedia entry for the Tower of Hanoi puzzle.
<lang MATLAB>function towerOfHanoi(n,A,C,B)
Line 1,084 ⟶ 1,042:
end
end</lang>
{{out|Sample output}}
 
Sample output:
<lang MATLAB>towerOfHanoi(3,1,3,2)
Move plate 1 from tower 1 to tower 3
Line 1,144 ⟶ 1,101:
hanoi(4, "1", "2", "3")</lang>
{{out}}
Output:
<pre>Move disk 1 from 1 to 3
Move disk 2 from 1 to 2
Line 1,160 ⟶ 1,117:
Move disk 2 from 1 to 2
Move disk 1 from 3 to 2</pre>
 
=={{header|NewLISP}}==
<lang lisp>(define (move n from to via)
(define (move n from to via)
(if (> n 0)
(move (- n 1) from via to
(print "move disk from pole " from " to pole " to "\n")
(move (- n 1) via to from))))
 
 
(move 4 1 2 3)</lang>
Line 1,174 ⟶ 1,130:
From [http://sites.google.com/site/vinodkshukla/code-snippets/objectivec-towersofhanoi here]
 
{{works with|GNUstep}}
This has been tested on GNUstep compiler. But it should be compatible with XCode/Cocoa on MacOS too.
It should be compatible with XCode/Cocoa on MacOS too.
 
The Interface - TowersOfHanoi.h:
Line 1,189 ⟶ 1,146:
-(void) movePegFrom: (int) from andMovePegTo: (int) to andMovePegVia: (int) via andWithNumDisks: (int) disks;
@end</lang>
 
The Implementation - TowersOfHanoi.m:
 
<lang objc>#import "TowersOfHanoi.h"
@implementation TowersOfHanoi
Line 1,213 ⟶ 1,168:
 
@end</lang>
 
Test code: TowersTest.m:
 
<lang objc>#import <stdio.h>
#import "TowersOfHanoi.h"
Line 1,237 ⟶ 1,190:
 
=={{header|OCaml}}==
 
<lang ocaml>let rec hanoi n a b c =
if n <> 0 then begin
Line 1,249 ⟶ 1,201:
 
=={{header|Octave}}==
 
<lang octave>function hanoimove(ndisks, from, to, via)
if ( ndisks == 1 )
Line 1,275 ⟶ 1,226:
 
=={{header|Pascal}}==
'''Compiler:'''{{works [[with|Free Pascal]] (|2.0.4)}}
 
I think it is standard pascal, except for the constant array "strPole". I am not sure if constant arrays are part of the standard. However, as far as I know, they are a "de facto" standard in every compiler.
 
<lang pascal>program Hanoi;
type
Line 1,297 ⟶ 1,246:
MoveStack(4,tpLeft,tpCenter,tpRight);
end.</lang>
 
A little longer, but clearer for my taste
<lang pascal>program Hanoi;
Line 1,340 ⟶ 1,288:
=={{header|Perl 6}}==
{{works with|Rakudo|#22 "Thousand Oaks"}}
 
<lang perl6>subset Peg of Int where * == 1|2|3;
 
Line 1,370 ⟶ 1,317:
 
=={{header|Pop11}}==
 
<lang pop11>define hanoi(n, src, dst, via);
if n > 0 then
Line 1,382 ⟶ 1,328:
 
=={{header|PL/I}}==
{{trans|Fortran}}
<lang PL/I>
<lang PL/I>tower: proc options (main);
/* From Rosetta Fortran */
tower: proc options (main);
 
call Move (4,1,2,3);
Line 1,402 ⟶ 1,347:
end Move;
 
end tower;</lang>
</lang>
 
=={{header|PostScript}}==
Line 1,458 ⟶ 1,402:
=={{header|Prolog}}==
From Programming in Prolog by W.F. Clocksin & C.S. Mellish
<lang prolog>hanoi(N) :- move(N,left,center,right).
hanoi(N) :- move(N,left,center,right).
 
move(0,_,_,_) :- !.
Line 1,468 ⟶ 1,411:
move(M,C,B,A).
 
inform(X,Y) :- write([move,a,disk,from,the,X,pole,to,Y,pole]), nl.</lang>
</lang>
 
=={{header|PureBasic}}==
 
Algorithm according to http://en.wikipedia.org/wiki/Towers_of_Hanoi
<lang PureBasic>Procedure Hanoi(n, A.s, C.s, B.s)
Line 1,481 ⟶ 1,422:
EndIf
EndProcedure</lang>
 
Full program
<lang PureBasic>Procedure Hanoi(n, A.s, C.s, B.s)
Line 1,497 ⟶ 1,437:
PrintN(#CRLF$+"Press ENTER to exit."): Input()
EndIf</lang>
{{out}}
 
Outputs
Moving 3 pegs.
Line 1,512 ⟶ 1,451:
 
=={{header|Python}}==
 
<lang python>def hanoi(ndisks, startPeg=1, endPeg=3):
if ndisks:
Line 1,559 ⟶ 1,497:
 
hanoi 4</lang>
{{out}}
 
Output:
 
<pre>left -> right
left -> middle
Line 1,579 ⟶ 1,515:
 
=={{header|Retro}}==
<lang Retro>4 elements a b c n
4 elements a b c n
 
: vars !c !b !a !n ;
Line 1,594 ⟶ 1,529:
] ifTrue ;
 
4 1 3 2 hanoi</lang>
</lang>
 
=={{header|REXX}}==
===version 1===
<lang rexx>/*REXX program to show the moves to solve the Tower of Hanoi (3 disks). */
<lang rexx>
/*REXX program to show the moves to solve the Tower of Hanoi (3 disks). */
 
arg z .
Line 1,625 ⟶ 1,558:
dsk: move=move+1
say 'step' right(move,length(moves))": move disk " arg(1) '-->' arg(2)
return</lang>
{{out}}
</lang>
<pre>
Output:
<pre style="height:30ex;overflow:scroll">
step 1: move disk 1 --> 3
step 2: move disk 1 --> 2
Line 1,639 ⟶ 1,571:
The minimum number of moves to solve a 3 ring Tower of Hanoi is 7.
</pre>
Output when the following was entered (to solve with four disks): <tt>4</tt>
<br><br>
4
<pre style="height:30ex;overflow:scroll">
step 1: move disk 1 --> 2
Line 1,661 ⟶ 1,591:
The minimum number of moves to solve a 4 ring Tower of Hanoi is 15.
</pre>
<!-- etc for 5 towers… we don't need to have that much boring output do we? -->
Output when the following was entered (to solve with five disks):
<br><br>
5
<pre style="height:30ex;overflow:scroll">
step 1: move disk 1 --> 3
step 2: move disk 1 --> 2
step 3: move disk 3 --> 2
step 4: move disk 1 --> 3
step 5: move disk 2 --> 1
step 6: move disk 2 --> 3
step 7: move disk 1 --> 3
step 8: move disk 1 --> 2
step 9: move disk 3 --> 2
step 10: move disk 3 --> 1
step 11: move disk 2 --> 1
step 12: move disk 3 --> 2
step 13: move disk 1 --> 3
step 14: move disk 1 --> 2
step 15: move disk 3 --> 2
step 16: move disk 1 --> 3
step 17: move disk 2 --> 1
step 18: move disk 2 --> 3
step 19: move disk 1 --> 3
step 20: move disk 2 --> 1
step 21: move disk 3 --> 2
step 22: move disk 3 --> 1
step 23: move disk 2 --> 1
step 24: move disk 2 --> 3
step 25: move disk 1 --> 3
step 26: move disk 1 --> 2
step 27: move disk 3 --> 2
step 28: move disk 1 --> 3
step 29: move disk 2 --> 1
step 30: move disk 2 --> 3
step 31: move disk 1 --> 3
 
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).
 
towers with the disks on them, and the movement of the disk (the move).
In addition, it shows each move in a countdown manner (the last move is move #1).
<br>
 
In addition, it shows each move in a countdown manner (the last move is
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.
move #1).
<lang rexx>/*REXX program shows pictorial moves to solve Tower of Hanoi (3 disks). */
<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>
/*REXX program shows pictorial moves to solve Tower of Hanoi (3 disks). */
 
arg z .
Line 1,822 ⟶ 1,710:
call showtowers
return
 
 
 
 
Line 1,831 ⟶ 1,717:
if _p\='' then say _p
end
return</lang>
{{out}}
</lang>
Output:
<pre style="height:50ex;overflow:scroll">
░░
Line 1,881 ⟶ 1,766:
 
The minimum number of moves for a 3 ring Tower of Hanoi is 7
 
</pre>
 
=={{header|Ruby}}==
 
<lang ruby>def move(num_disks, starting_stick, target_stick, using_stick)
if num_disks == 1
Line 1,917 ⟶ 1,800:
 
=={{header|Scala}}==
 
<lang scala>def move(n: int, from: int, to: int, via: int) = {
if (n == 1) {
Line 1,927 ⟶ 1,809:
}
}</lang>
 
This next example is from http://gist.github.com/66925 it is a translation to Scala of a Prolog solution and solves the problem at compile time
<lang scala>object TowersOfHanoi {
Line 1,967 ⟶ 1,848:
 
=={{header|Scheme}}==
 
<lang scheme>(define (hanoi n a b c)
(if (> n 0)
Line 1,982 ⟶ 1,862:
 
=={{header|Seed7}}==
 
<lang seed7>const proc: hanoi (in integer: disk, in string: source, in string: dest, in string: via) is func
begin
Line 1,993 ⟶ 1,872:
 
=={{header|SNOBOL4}}==
 
<lang SNOBOL4>* # Note: count is global
 
Line 2,007 ⟶ 1,885:
hanoi(4,'A','C','B')
end</lang>
{{out}}
 
Output:
<pre>1: Move disc from A to B
2: Move disc from A to C
Line 2,042 ⟶ 1,919:
 
hanoi 4</lang>
{{out}}
produces
<pre>1: move from A to B
2: move from A to C
Line 2,060 ⟶ 1,937:
 
=={{header|Toka}}==
 
<lang toka>value| sa sb sc n |
[ to sc to sb to sa to n ] is vars!
Line 2,074 ⟶ 1,950:
] ifTrue
] is hanoi</lang>
 
 
=={{header|TSE SAL}}==
<lang TSESAL>// library: program: run: towersofhanoi: recursive: sub <description></description> <version>1.0.0.0.0</version> <version control></version control> (filenamemacro=runprrsu.s) [kn, ri, tu, 07-02-2012 19:54:23]
<lang TSE SAL>
// library: program: run: towersofhanoi: recursive: sub <description></description> <version>1.0.0.0.0</version> <version control></version control> (filenamemacro=runprrsu.s) [kn, ri, tu, 07-02-2012 19:54:23]
PROC PROCProgramRunTowersofhanoiRecursiveSub( INTEGER totalDiskI, STRING fromS, STRING toS, STRING viaS, INTEGER bufferI )
IF ( totalDiskI == 0 )
Line 2,102 ⟶ 1,976:
IF ( NOT ( Ask( "program: run: towersofhanoi: recursive: totalDiskI = ", s1, _EDIT_HISTORY_ ) ) AND ( Length( s1 ) > 0 ) ) RETURN() ENDIF
PROCProgramRunTowersofhanoiRecursive( Val( s1 ), "source", "target", "via" )
END</lang>
</lang>
 
=={{header|UNIX Shell}}==
 
{{works with|bash}}
 
<lang bash>#!/bin/bash
 
Line 2,138 ⟶ 2,009:
 
main = ^|T(~&,' -> '--)* move/4 <'start','end','middle'></lang>
{{out}}
output:
<pre>start -> middle
start -> end
Line 2,184 ⟶ 2,055:
 
=={{header|Visual Basic .NET}}==
 
<lang vbnet>Module TowersOfHanoi
Sub MoveTowerDisks(ByVal disks As Integer, ByVal fromTower As Integer, ByVal toTower As Integer, ByVal viaTower As Integer)
Line 2,230 ⟶ 2,100:
 
=={{header|XQuery}}==
<lang xquery>declare function local:hanoi($disk as xs:integer, $from as xs:integer,
<lang xquery>
declare function local:hanoi($disk as xs:integer, $from as xs:integer,
$to as xs:integer, $via as xs:integer) as element()*
{
Line 2,247 ⟶ 2,116:
local:hanoi(4, 1, 2, 3)
}
</hanoi></lang>
{{out}}
</lang>
<lang xml><?xml version="1.0" encoding="UTF-8"?>
 
Result is:
<lang xml>
<?xml version="1.0" encoding="UTF-8"?>
<hanoi>
<move disk="1">
Line 2,314 ⟶ 2,180:
<to>2</to>
</move>
</hanoi></lang>
</lang>
Anonymous user