Towers of Hanoi: Difference between revisions
Added Quite BASIC
(Added PL/M) |
(Added Quite BASIC) |
||
(46 intermediate revisions by 27 users not shown) | |||
Line 10:
{{trans|Python}}
<
I ndisks
hanoi(ndisks - 1, startPeg, 6 - startPeg - endPeg)
Line 16:
hanoi(ndisks - 1, 6 - startPeg - endPeg, endPeg)
hanoi(ndisks' 3)</
{{out}}
Line 31:
=={{header|360 Assembly}}==
{{trans|PL/I}}
<
HANOITOW CSECT
USING HANOITOW,R12 r12 : base register
Line 102:
STACKLEN EQU *-STACKDS
YREGS
END HANOITOW</
{{out}}
<pre style="height:18ex">
Line 121:
15 Move disc from pole 3 to pole 2
</pre>
=={{header|6502 Assembly}}==
{{works with|Commodore}}
This should work on any Commodore 8-bit computer; just set `temp` to an appropriate zero-page location.
<syntaxhighlight lang="assembly">temp = $FB ; this works on a VIC-20 or C-64; adjust for other machines. Need two bytes zero-page space unused by the OS.
; kernal print-char routine
chrout = $FFD2
; Main Towers of Hanoi routine. To call, load the accumulator with the number of disks to move,
; the X register with the source peg (1-3), and the Y register with the target peg.
hanoi: cmp #$00 ; do nothing if the number of disks to move is zero
bne nonzero
rts
nonzero: pha ; save registers on stack
txa
pha
tya
pha
pha ; and make room for the spare peg number
; Parameters are now on the stack at these offsets:
count = $0104
source = $0103
target = $0102
spare = $0101
; compute spare rod number (6 - source - dest)
tsx
lda #6
sec
sbc source, x
sec
sbc target, x
sta spare, x
; prepare for first recursive call
tay ; target is the spare peg
tsx
lda source, x ; source is the same
sta temp ; we're using X to access the stack, so save its value here for now
lda count, x ; move count - 1 disks
sec
sbc #1
ldx temp ; now load X for call
; and recurse
jsr hanoi
; restore X and Y for print call
tsx
ldy target, x
lda source, x
tax
; print instructions to move the last disk
jsr print_move
; prepare for final recursive call
tsx
lda spare, x ; source is now spare
sta temp
lda target, x ; going to the original target
tay
lda count, x ; and again moving count-1 disks
sec
sbc #1
ldx temp
jsr hanoi
; pop our stack frame, restore registers, and return
pla
pla
tay
pla
tax
pla
rts
; constants for printing
prelude: .asciiz "MOVE DISK FROM "
interlude: .asciiz " TO "
postlude: .byte 13,0
; print instructions: move disk from (X) to (Y)
print_move:
pha
txa
pha
tya
pha
; Parameters are now on the stack at these offsets:
from = $0102
to = $0101
lda #<prelude
ldx #>prelude
jsr print_string
tsx
lda from,x
clc
adc #$30
jsr chrout
lda #<interlude
ldx #>interlude
jsr print_string
tsx
lda to,x
clc
adc #$30
jsr chrout
lda #<postlude
ldx #>postlude
jsr print_string
pla
tay
pla
tax
pla
rts
; utility routine: print null-terminated string at address AX
print_string:
sta temp
stx temp+1
ldy #0
loop: lda (temp),y
beq done_print
jsr chrout
iny
bne loop
done_print:
rts</syntaxhighlight>
{{Out}}
<pre>MOVE DISK FROM 1 TO 2
MOVE DISK FROM 1 TO 3
MOVE DISK FROM 2 TO 3
MOVE DISK FROM 1 TO 2
MOVE DISK FROM 3 TO 1
MOVE DISK FROM 3 TO 2
MOVE DISK FROM 1 TO 2
MOVE DISK FROM 1 TO 3
MOVE DISK FROM 2 TO 3
MOVE DISK FROM 2 TO 1
MOVE DISK FROM 3 TO 1
MOVE DISK FROM 2 TO 3
MOVE DISK FROM 1 TO 2
MOVE DISK FROM 1 TO 3
MOVE DISK FROM 2 TO 3</pre>
=={{header|8080 Assembly}}==
<
lhld 6 ; Top of CP/M usable memory
sphl ; Put the stack there
Line 165 ⟶ 322:
outstr: db 'Move disk from pole '
out1: db '* to pole '
out2: db '*',13,10,'$'</
{{out}}
Line 188 ⟶ 345:
=={{header|8086 Assembly}}==
<
bits 16
org 100h
Line 218 ⟶ 375:
outstr: db 'Move disk from pole '
out1: db '* to pole '
out2: db '*',13,10,'$'</
{{out}}
Line 240 ⟶ 397:
=={{header|8th}}==
<
5 var, disks
var sa
Line 261 ⟶ 418:
disks @ 1 2 3 hanoi cr bye
</syntaxhighlight>
=={{header|ABC}}==
<syntaxhighlight lang="ABC">HOW TO MOVE n DISKS FROM src VIA via TO dest:
IF n>0:
MOVE n-1 DISKS FROM src VIA dest TO via
WRITE "Move disk from pole", src, "to pole", dest/
MOVE n-1 DISKS FROM via VIA dest TO src
MOVE 4 DISKS FROM 1 VIA 2 TO 3</syntaxhighlight>
{{out}}
<pre>Move disk from pole 1 to pole 2
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 1
Move disk from pole 1 to pole 2
Move disk from pole 3 to pole 2
Move disk from pole 3 to pole 1
Move disk from pole 2 to pole 3
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 1
Move disk from pole 2 to pole 3
Move disk from pole 1 to pole 2
Move disk from pole 2 to pole 1
Move disk from pole 3 to pole 1
Move disk from pole 3 to pole 2
Move disk from pole 1 to pole 3</pre>
=={{header|Action!}}==
{{Trans|Tiny BASIC}}...via PL/M
<syntaxhighlight lang="action!">
;;; Iterative Towers of Hanoi; translated from Tiny BASIC via PL/M
;;;
DEFINE NUMBER_OF_DISCS = "4"
PROC Main()
INT d, n, x
n = 1
FOR d = 1 TO NUMBER_OF_DISCS DO
n = n + n
OD
FOR x = 1 TO n - 1 DO
; as with Algol W, PL/M, Action! has bit and MOD operators
Print( "Move disc on peg " )
Put( '1 + ( ( x AND ( x - 1 ) ) MOD 3 ) )
Print( " to peg " )
Put( '1 + ( ( ( x OR ( x - 1 ) ) + 1 ) MOD 3 ) )
PutE()
OD
RETURN
</syntaxhighlight>
{{out}}
<pre>
Move disc on peg 1 to peg 3
Move disc on peg 1 to peg 2
Move disc on peg 3 to peg 2
Move disc on peg 1 to peg 3
Move disc on peg 2 to peg 1
Move disc on peg 2 to peg 3
Move disc on peg 1 to peg 3
Move disc on peg 1 to peg 2
Move disc on peg 3 to peg 2
Move disc on peg 3 to peg 1
Move disc on peg 2 to peg 1
Move disc on peg 3 to peg 2
Move disc on peg 1 to peg 3
Move disc on peg 1 to peg 2
Move disc on peg 3 to peg 2
</pre>
=={{header|ActionScript}}==
<
{
if (n > 0)
Line 272 ⟶ 499:
move(n - 1, via, to, from);
}
}</
=={{header|Ada}}==
<
procedure Towers is
Line 289 ⟶ 516:
begin
Hanoi(4);
end Towers;</
=={{header|Agena}}==
<
if n > 0 then
move(n - 1, src, via, dst)
Line 300 ⟶ 527:
end
move(4, 1, 2, 3)</
=={{header|ALGOL 60}}==
<
procedure movedisk(n, f, t);
integer n, f, t;
Line 329 ⟶ 556:
dohanoi(4, 1, 2, 3);
outstring(1,"Towers of Hanoi puzzle completed!")
end</
{{out}}
<pre>Move disk from 1 to 3
Line 350 ⟶ 577:
=={{header|ALGOL 68}}==
<
IF n > 0 THEN
move(n - 1, from, via, to);
Line 360 ⟶ 587:
main: (
move(4, 1,2,3)
)</
COMMENT Disk number is also printed in this code (works with a68g): COMMENT
<
PROC move = (INT n, from, to, via) VOID:
IF n > 0 THEN
Line 375 ⟶ 602:
move(4, 1,2,3)
)
</syntaxhighlight>
=={{header|ALGOL-M}}==
<
procedure move(n, src, via, dest);
integer n;
Line 395 ⟶ 622:
move(4, "1", "2", "3");
end</
{{out}}
<pre>Move disk from pole 1 to pole 2
Line 416 ⟶ 643:
===Recursive===
Following Agena, Algol 68, AmigaE...
<
procedure move ( integer value n, from, to, via ) ;
if n > 0 then begin
Line 425 ⟶ 652:
move( 4, 1, 2, 3 )
end.</
===Iterative===
{{Trans|Tiny BASIC}}
<
integer d, n;
while begin writeon( "How many disks? " );
Line 449 ⟶ 676:
write( i_w := 1, s_w := 0, "Move disc on peg ", s + 1, " to peg ", t + 1 )
end
end.</
=={{header|AmigaE}}==
<
IF n > 0
move(n-1, from, via, to)
Line 462 ⟶ 689:
PROC main()
move(4, 1,2,3)
ENDPROC</
=={{header|Amazing Hopper}}==
<syntaxhighlight lang="amazing hopper">
#include <hopper.h>
#proto hanoi(_X_,_Y_,_Z_,_W_)
Line 481 ⟶ 708:
_hanoi({discos}minus(1), aux, inicio, fin))
back
</syntaxhighlight>
{{out}}
<pre>
Line 505 ⟶ 732:
{{works with|Dyalog APL}}
<
move←{
n from to via←⍵
Line 514 ⟶ 741:
}
'⊂Move disk from pole ⊃,I1,⊂ to pole ⊃,I1'⎕FMT↑move ⍵
}</
{{out}}
Line 536 ⟶ 763:
=={{header|AppleScript}}==
<
-- hanoi :: Int -> (String, String, String) -> [(String, String)]
Line 613 ⟶ 840:
set my text item delimiters to dlm
str
end unlines</
{{Out}}
<pre>left -> right
Line 627 ⟶ 854:
''(I've now eliminated the recursive ''|move|()'' handler's tail calls. So it's now only called 2 ^ (n - 1) times as opposed to 2 ^ (n + 1) - 1 with full recursion. The maximum call depth of n is only reached once, whereas with full recursion, the maximum depth was n + 1 and this was reached 2 ^ n times.)''
<
set t1 to tab & "tower 1: " & tab
set t2 to tab & "tower 2: " & tab
Line 690 ⟶ 917:
set sourceTower to 1
set destinationTower to 2
hanoi(numberOfDiscs, sourceTower, destinationTower)</
{{Out}}
Line 728 ⟶ 955:
=={{header|ARM Assembly}}==
<syntaxhighlight lang="text">.text
.global _start
_start: mov r0,#4 @ 4 disks,
Line 771 ⟶ 998:
spole: .ascii "* to pole "
dpole: .ascii "*\n"
mlen = . - moves</
{{out}}
Line 795 ⟶ 1,022:
{{trans|D}}
<
if n>0 [
hanoi n-1 f via dir
Line 803 ⟶ 1,030:
]
hanoi 3 'L 'M 'R</
{{out}}
Line 814 ⟶ 1,041:
Move disk 2 from R to M
Move disk 1 from L to M</pre>
=={{header|Asymptote}}==
<syntaxhighlight lang="Asymptote">void hanoi(int n, string origen, string auxiliar, string destino) {
if (n == 1) {
write("Move disk 1 from " + origen + " to " + destino);
} else {
hanoi(n - 1, origen, destino, auxiliar);
write("Move disk " + string(n) + " from " + origen + " to " + destino);
hanoi(n - 1, auxiliar, origen, destino);
}
}
hanoi(3, "pole 1", "pole 2", "pole 3");
write("Towers of Hanoi puzzle completed!");</syntaxhighlight>
{{out}}
<pre>Move disk 1 from pole 1 to pole 3
Move disk 2 from pole 1 to pole 2
Move disk 1 from pole 3 to pole 2
Move disk 3 from pole 1 to pole 3
Move disk 1 from pole 2 to pole 1
Move disk 2 from pole 2 to pole 3
Move disk 1 from pole 1 to pole 3
Towers of Hanoi puzzle completed!</pre>
=={{header|AutoHotkey}}==
<
{
if (n = 1)
Line 829 ⟶ 1,079:
}
}
move(64, 1, 3, 2)</
=={{header|AutoIt}}==
<
If ($n = 1) Then
ConsoleWrite(StringFormat("Move disk from pole "&$from&" To pole "&$to&"\n"))
Line 842 ⟶ 1,092:
EndFunc
move(4, 1,2,3)</
=={{header|AWK}}==
{{trans|Logo}}
<
BEGIN{hanoi(4,"left","middle","right")}'</
{{out}}
<pre>left -> right
Line 869 ⟶ 1,119:
{{works with|FreeBASIC}}
{{works with|RapidQ}}
<
IF n>0 THEN
move n-1, fromPeg, viaPeg, toPeg
Line 877 ⟶ 1,127:
END SUB
move 4,1,2,3</
===Using <code>GOSUB</code>s===
Here's an example of implementing recursion in an old BASIC that only has global variables:
{{works with|Applesoft BASIC}}
{{works with|Chipmunk Basic}}
{{works with|Commodore BASIC}}
{{works with|GW-BASIC}}
{{works with|MSX_BASIC}}
<syntaxhighlight lang="gwbasic">10 DEPTH=4: REM SHOULD EQUAL NUMBER OF DISKS
20 DIM N(DEPTH), F(DEPTH), T(DEPTH), V(DEPTH): REM STACK PER PARAMETER
60 T(SP) = 2: REM MOVE TO PEG 2
70 V(SP) = 3: REM VIA PEG 3
80 GOSUB 100
90 END
99 REM MOVE SUBROUTINE
100 IF N(SP) = 0 THEN RETURN
110 OS = SP: REM STORE STACK POINTER
Line 909 ⟶ 1,162:
240 GOSUB 100
250 SP = SP - 1 : REM RESTORE STACK POINTER FOR CALLER
260 RETURN</
===Using binary method===
{{works with|Chipmunk Basic}}
{{works with|Commodore BASIC}}
Very fast version in BASIC V2 on Commodore C-64
{{works with|MSX_BASIC}}
<syntaxhighlight lang="gwbasic"> 10 DEF FNM3(X)=X-INT(X/3)*3:REM MODULO 3
100 :FOR M=1 TO 2^N-1
110 ::PRINT MID$(STR$(M),2);":",FNM3(M AND M-1)+1;"TO";FNM3((M OR M-1)+1)+1
130 :NEXT M
140 RETURN</syntaxhighlight>
{{out}}
<pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
==={{header|BASIC256}}===
<
print "Towers of Hanoi puzzle completed!"
end
Line 950 ⟶ 1,205:
call move(n-1, viaPeg, toPeg, fromPeg)
end if
end subroutine</
{{out}}
Line 971 ⟶ 1,226:
Towers of Hanoi puzzle completed!
</pre>
==={{header|IS-BASIC}}===
<syntaxhighlight lang="is-basic">100 PROGRAM "Hanoi.bas"
110 CALL HANOI(4,1,3,2)
120 DEF HANOI(DISK,FRO,TO,WITH)
130 IF DISK>0 THEN
140 CALL HANOI(DISK-1,FRO,WITH,TO)
150 PRINT "Move disk";DISK;"from";FRO;"to";TO
160 CALL HANOI(DISK-1,WITH,TO,FRO)
170 END IF
180 END DEF</syntaxhighlight>
==={{header|Quite BASIC}}===
{{trans|BASIC}}
<syntaxhighlight lang="qbasic">100 CLS
120 LET D = 4 : REM SHOULD EQUAL NUMBER OF DISKS
130 ARRAY N: ARRAY F: ARRAY T: ARRAY V: REM STACK PER PARAMETER
140 LET S = 0 : REM STACK POINTER
150 LET N(S) = 4: REM START WITH 4 DISCS
160 LET F(S) = 1: REM ON PEG 1
170 LET T(S) = 2: REM MOVE TO PEG 2
180 LET V(S) = 3: REM VIA PEG 3
190 GOSUB 220
200 END
210 REM MOVE SUBROUTINE
220 IF N(S) = 0 THEN RETURN
230 LET O = S : REM STORE STACK POINTER
240 LET S = S + 1 : REM INCREMENT STACK POINTER
250 LET N(S) = N(O) - 1: REM MOVE N-1 DISCS
260 LET F(S) = F(O) : REM FROM START PEG
270 LET T(S) = V(O) : REM TO VIA PEG
280 LET V(S) = T(O) : REM VIA TO PEG
290 GOSUB 220
300 LET O = S - 1 : REM O WILL HAVE CHANGED
310 PRINT "MOVE DISC FROM "; F(O); " TO "; T(O)
320 LET N(S) = N(O) - 1: REM MOVE N-1 DISCS
330 LET F(S) = V(O) : REM FROM VIA PEG
340 LET T(S) = T(O) : REM TO DEST PEG
350 LET V(S) = F(O) : REM VIA FROM PEG
360 GOSUB 220
370 LET S = S - 1 : REM RESTORE STACK POINTER FOR CALLER
380 RETURN
390 END</syntaxhighlight>
{{out}}
<pre>MOVE DISC FROM 1 TO 3
MOVE DISC FROM 1 TO 2
MOVE DISC FROM 3 TO 2
MOVE DISC FROM 1 TO 3
MOVE DISC FROM 2 TO 1
MOVE DISC FROM 2 TO 3
MOVE DISC FROM 1 TO 3
MOVE DISC FROM 1 TO 2
MOVE DISC FROM 3 TO 2
MOVE DISC FROM 3 TO 1
MOVE DISC FROM 2 TO 1
MOVE DISC FROM 3 TO 2
MOVE DISC FROM 1 TO 3
MOVE DISC FROM 1 TO 2
MOVE DISC FROM 3 TO 2</pre>
=={{header|Batch File}}==
<
setlocal enabledelayedexpansion
Line 1,000 ⟶ 1,314:
call :move !x! %via% %to% %from%
)
exit /b 0</
{{Out}}
<pre>Move top disk from pole START to pole HELPER.
Line 1,022 ⟶ 1,336:
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<
FOR disc% = 1 TO 13
Disc$(disc%) = STRING$(disc%," ")+STR$disc%+STRING$(disc%," ")
Line 1,057 ⟶ 1,371:
Size%(peg%) = Size%(peg%)-1
PRINTTAB(13+26*(peg%-1)-disc%,20-Size%(peg%))STRING$(2*disc%+1," ");
ENDPROC</
=={{header|BCPL}}==
<
let start() be move(4, 1, 2, 3)
Line 1,067 ⟶ 1,381:
writef("Move disk from pole %N to pole %N*N", src, dest);
move(n-1, via, src, dest)
$)</
{{out}}
<pre>Move disk from pole 1 to pole 2
Line 1,086 ⟶ 1,400:
=={{header|Befunge}}==
This is loosely based on the [[Towers_of_Hanoi#Python|Python]] sample. The number of disks is specified by the first integer on the stack (the initial character <tt>4</tt> in the example below). If you want the program to prompt the user for that value, you can replace the <tt>4</tt> with a <tt>&</tt> (the read integer command).
<
>8v8:<$#<+9-+*2%3\*3/3:,+55.+1%3:$_,#!>#:<
: >/!#^_:0\:8/1-8vv,_$8%:3/1+.>0" gep ot"^
^++3-%3\*2/3:%8\*<>:^:"from peg "0\*8-1<</
{{out}}
Line 1,114 ⟶ 1,427:
'''Based on:''' [[APL]]
<
𝕩⊑⊸≤0 ? ⟨⟩;
𝕊 n‿from‿to‿via:
Line 1,121 ⟶ 1,434:
l∾(<from‿to)∾r
}
{"Move disk from pole "∾(•Fmt 𝕨)∾" to pole "∾•Fmt 𝕩}´˘>Move 4‿1‿2‿3</
<syntaxhighlight lang="text">┌─
╵"Move disk from pole 1 to pole 3
Move disk from pole 1 to pole 2
Line 1,138 ⟶ 1,451:
Move disk from pole 1 to pole 2
Move disk from pole 3 to pole 2"
┘</
=={{header|Bracmat}}==
<
= n from to via
. !arg:(?n,?from,?to,?via)
Line 1,152 ⟶ 1,465:
)
& move$(4,1,2,3)
);</
{{out}}
<pre>Move disk from pole 1 to pole 3
Line 1,172 ⟶ 1,485:
=={{header|Brainf***}}==
<
This implementation is recursive and uses
a stack, consisting of frames that are 8
Line 1,324 ⟶ 1,637:
>>[<<+>>-]<< step = next
<
]</
=={{header|Bruijn}}==
{{trans|Python}}
<syntaxhighlight lang="bruijn">
:import std/Combinator .
:import std/Number .
:import std/String .
hanoi y [[[[=?2 empty go]]]]
go [(4 --3 2 0) ++ str ++ (4 --3 0 1)] ((+6) - 1 - 0)
str "Move " ++ disk ++ " from " ++ source ++ " to " ++ destination ++ "\n"
disk number→string 3
source number→string 2
destination number→string 1
</syntaxhighlight>
=={{header|C}}==
<
void move(int n, int from, int via, int to)
Line 1,343 ⟶ 1,671:
move(4, 1,2,3);
return 0;
}</
Animate it for fun:<
#include <stdlib.h>
#include <unistd.h>
Line 1,404 ⟶ 1,732:
text(1, 0, 1, "\n");
return 0;
}</
=={{header|C sharp|C#}}==
<
if (n == 1) {
System.Console.WriteLine("Move disk from pole " + from + " to pole " + to);
Line 1,415 ⟶ 1,743:
move(n - 1, via, to, from);
}
}</
=={{header|C++}}==
{{works with|g++}}
<
if (n == 1) {
std::cout << "Move disk from pole " << from << " to pole " << to << std::endl;
Line 1,427 ⟶ 1,755:
move(n - 1, via, to, from);
}
}</
==={{header|Chipmunk Basic}}===
{{works with|Chipmunk Basic|3.6.4}}
{{trans|FreeBASIC}}
<syntaxhighlight lang="qbasic">100 cls
110 print "Three disks" : print
120 hanoi(3,1,2,3)
130 print chr$(10)"Four disks" chr$(10)
140 hanoi(4,1,2,3)
150 print : print "Towers of Hanoi puzzle completed!"
160 end
170 sub hanoi(n,desde,hasta,via)
180 if n > 0 then
190 hanoi(n-1,desde,via,hasta)
200 print "Move disk " n "from pole " desde "to pole " hasta
210 hanoi(n-1,via,hasta,desde)
220 endif
230 end sub</syntaxhighlight>
=={{header|Clojure}}==
===Side-Effecting Solution===
<
(when (pos? n)
(towers-of-hanoi (dec n) from via to)
(printf "Move from %s to %s\n" from to)
(recur (dec n) via to from)))</
===Lazy Solution===
<
(when (pos? n)
(lazy-cat (towers-of-hanoi (dec n) from via to)
(cons [from '-> to]
(towers-of-hanoi (dec n) via to from)))))</
=={{header|CLU}}==
<
po: stream := stream$primary_output()
if n > 0 then
Line 1,458 ⟶ 1,804:
start_up = proc ()
move(4, 1, 2, 3)
end start_up</
{{out}}
<pre>Move disk from pole 1 to pole 2
Line 1,479 ⟶ 1,825:
{{trans|C}}
{{works with|OpenCOBOL|2.0}}
<
IDENTIFICATION DIVISION.
PROGRAM-ID. towers-of-hanoi.
Line 1,506 ⟶ 1,852:
END-IF
.
END PROGRAM move-disk.</
{{ Number of disks also }}
<
IDENTIFICATION DIVISION.
PROGRAM-ID. towers-of-hanoi.
Line 1,539 ⟶ 1,885:
.
END PROGRAM move-disk.
</syntaxhighlight>
=== ANSI-74 solution ===
Line 1,547 ⟶ 1,893:
{{works with|CIS COBOL|4.2}}{{works with|GnuCOBOL|3.0-rc1.0}}
<
PROGRAM-ID. ITERATIVE-TOWERS-OF-HANOI.
AUTHOR. SOREN ROUG.
Line 1,638 ⟶ 1,984:
MOVE FROM-POLE TO VIA-POLE.
MOVE TMP-P TO FROM-POLE.
</syntaxhighlight>
=={{header|CoffeeScript}}==
<
if ndisks
staging_peg = 1 + 2 + 3 - start_peg - end_peg
Line 1,648 ⟶ 1,994:
hanoi(ndisks-1, staging_peg, end_peg)
hanoi(4)</
=={{header|Common Lisp}}==
<
(cond ((= n 1)
(format t "Move from ~A to ~A.~%" from to))
Line 1,657 ⟶ 2,003:
(move (- n 1) from via to)
(format t "Move from ~A to ~A.~%" from to)
(move (- n 1) via to from))))</
=={{header|D}}==
===Recursive Version===
<
void hanoi(in int n, in char from, in char to, in char via) {
Line 1,673 ⟶ 2,019:
void main() {
hanoi(3, 'L', 'M', 'R');
}</
{{out}}
<pre>Move disk 1 from L to M
Line 1,684 ⟶ 2,030:
===Fast Iterative Version===
See: [http://hanoitower.mkolar.org/shortestTHalgo.html The shortest and "mysterious" TH algorithm]
<
// then some more by M. Kolar (2000).
void main(in string[] args) {
Line 1,726 ⟶ 2,072:
'\n'.putchar;
}
}</
{{out}}
<pre>| 3 2 1
Line 1,762 ⟶ 2,108:
=={{header|Dart}}==
<
moveit(from,to) {
print("move ${from} ---> ${to}");
Line 1,776 ⟶ 2,122:
hanoi(3,3,1,2);
}</
The same as above, with optional static type annotations and styled according to http://www.dartlang.org/articles/style-guide/
<
String say(String from, String to) => "$from ---> $to";
Line 1,791 ⟶ 2,137:
hanoi(3, 3, 1, 2);
}</
{{out}}
Line 1,889 ⟶ 2,235:
=={{header|Draco}}==
<
if n>0 then
move(n-1, src, dest, via);
Line 1,899 ⟶ 2,245:
proc nonrec main() void:
move(4, 1, 2, 3)
corp</
{{out}}
<pre>Move disk from pole 1 to pole 2
Line 1,921 ⟶ 2,267:
{{trans|Swift}}
<
if n > 0 {
hanoi(n - 1, a, c, b)
Line 1,929 ⟶ 2,275:
}
hanoi(4, "A", "B", "C")</
{{out}}
Line 1,950 ⟶ 2,296:
=={{header|E}}==
<
if (n.aboveZero()) {
move(out, n.previous(), fromPeg, viaPeg, toPeg)
Line 1,958 ⟶ 2,304:
}
move(stdout, 4, def left {}, def right {}, def middle {})</
=={{header|EasyLang}}==
<syntaxhighlight lang="text">
proc hanoi n src dst aux . .
hanoi n - 1 aux dst src
.
.
</syntaxhighlight>
=={{header|EDSAC order code}}==
The Wikipedia article on EDSAC says "recursive calls were forbidden", and this is true if the standard "Wheeler jump" is used.
The program has a maximum of 9 discs, so as to simplify the printout of the disc numbers. Discs are numbered 1, 2, 3, ... in increasing order of size. The program could be speeded up by shortening the messages, which at present take up most of the runtime.
<
[Towers of Hanoi task for Rosetta Code.]
[EDSAC program, Initial Orders 2.]
Line 2,130 ⟶ 2,478:
PF [acc = 0 on entry]
[end]
</syntaxhighlight>
{{out}}
<pre>
Line 2,144 ⟶ 2,492:
=={{header|Eiffel}}==
<
APPLICATION
Line 2,171 ⟶ 2,519:
end
end
end</
=={{header|Ela}}==
{{trans|Haskell}}
<
:::IO
Line 2,191 ⟶ 2,539:
hanoiM' (n - 1) a c b
putStrLn $ "Move " ++ show a ++ " to " ++ show b
hanoiM' (n - 1) c b a</
=={{header|Elena}}==
ELENA 4.x :
<
{
if (n == 1)
Line 2,207 ⟶ 2,555:
move(n-1,via,to,from)
}
};</
=={{header|Elixir}}==
<
def hanoi(n) when 0<n and n<10, do: hanoi(n, 1, 2, 3)
Line 2,223 ⟶ 2,571:
end
RC.hanoi(3)</
{{out}}
Line 2,238 ⟶ 2,586:
=={{header|Emacs Lisp}}==
{{Trans|Common Lisp}}
<
(if (= n 1)
(message "Move from %S to %S" from to)
(move (- n 1) from via to)
(message "Move from %S to %S" from to)
(move (- n 1) via to from)))</
=={{header|EMal}}==
{{trans|C#}}
<syntaxhighlight lang="emal">
fun move = void by int n, int from, int to, int via
if n == 1
writeLine("Move disk from pole " + from + " to pole " + to)
return
end
move(n - 1, from, via, to)
move(1, from, to, via)
move(n - 1, via, to, from)
end
move(3, 1, 2, 3)
</syntaxhighlight>
{{out}}
<pre>
Move disk from pole 1 to pole 2
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 3
Move disk from pole 1 to pole 2
Move disk from pole 3 to pole 1
Move disk from pole 3 to pole 2
Move disk from pole 1 to pole 2
</pre>
=={{header|Erlang}}==
<
io:format("Move from ~p to ~p~n", [F, T]);
move(N, F, T, V) ->
move(N-1, F, V, T),
move(1 , F, T, V),
move(N-1, V, T, F).</
=={{header|ERRE}}==
<
!-----------------------------------------------------------
! HANOI.R : solve tower of Hanoi puzzle using a recursive
Line 2,310 ⟶ 2,683:
MOVE
END PROGRAM
</syntaxhighlight>
{{out}}
<pre>
Line 2,333 ⟶ 2,706:
{{Works with| Office 365 Betas 2021}}
<
=LAMBDA(n,
FILTERP(
Line 2,366 ⟶ 2,739:
)
)
)</
And assuming that these generic lambdas are also bound to the following names in Name Manager:
<
=LAMBDA(xs,
LAMBDA(ys,
Line 2,395 ⟶ 2,768:
FILTER(xs, p(xs))
)
)</
In the output below, the expression in B2 defines an array of strings which additionally populate the following cells.
Line 2,443 ⟶ 2,816:
=={{header|Ezhil}}==
<syntaxhighlight lang="python">
# (C) 2013 Ezhil Language Project
# Tower of Hanoi – recursive solution
Line 2,471 ⟶ 2,844:
ஹோனாய்(4,”அ”,”ஆ”,0)
</syntaxhighlight>
=={{header|F_Sharp|F#}}==
<
let rec hanoi num start finish =
match num with
Line 2,485 ⟶ 2,858:
(hanoi 4 1 2) |> List.iter (fun pair -> match pair with
| a, b -> printf "Move disc from %A to %A\n" a b)
0</
=={{header|Factor}}==
<
IN: rosettacode.hanoi
Line 2,498 ⟶ 2,871:
from to move
n 1 - other to from hanoi
] when ;</
In the REPL:
<pre>( scratchpad ) 3 1 3 2 hanoi
Line 2,510 ⟶ 2,883:
=={{header|FALSE}}==
<
"]p: { to from }
[n;0>[n;1-n: @\ h;! @\ p;! \@ h;! \@ n;1+n:]?]h: { via to from }
4n:["right"]["middle"]["left"]h;!%%%</
=={{header|Fermat}}==
<
if n = 0 then
!'';
Line 2,523 ⟶ 2,896:
!f;!' -> ';!t;!', ';
Hanoi(n - 1, v, t, f)
fi.</
{{out}}<pre>1 -> 3, 1 -> 2, 3 -> 2, 1 -> 3, 2 -> 1, 2 -> 3, 1 -> 3, 1 -> 2, 3 -> 2, 3 -> 1, 2 -> 1, 3 -> 2, 1 -> 3, 1 -> 2, 3 -> 2,</pre>
=={{header|FOCAL}}==
<
01.20 D 2
01.30 Q
Line 2,543 ⟶ 2,916:
03.10 T %1,"MOVE DISK FROM POLE",S(D)
03.20 T " TO POLE",T(D),!</
{{out}}
Line 2,565 ⟶ 2,938:
=={{header|Forth}}==
With locals:
<
CREATE peg2 ," middle "
CREATE peg3 ," right "
Line 2,577 ⟶ 2,950:
1 from to via RECURSE
n 1- via to from RECURSE
THEN ;</
Without locals, executable pegs:
<
: right ." right" ;
: middle ." middle" ;
Line 2,592 ⟶ 2,965:
swap rot ;
: hanoi ( n -- )
1 max >R ['] right ['] middle ['] left R> move-disk drop drop drop ;</
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<
CALL Move(4, 1, 2, 3)
Line 2,614 ⟶ 2,987:
END SUBROUTINE Move
END PROGRAM TOWER</
{{ More informative version }}
<
PROGRAM TOWER2
Line 2,636 ⟶ 3,009:
END SUBROUTINE Move
END PROGRAM TOWER2 </
=={{header|FreeBASIC}}==
<
Sub move(n As Integer, from As Integer, to_ As Integer, via As Integer)
Line 2,655 ⟶ 3,028:
move 4, 1, 2, 3
Print "Press any key to quit"
Sleep</
{{out}}
Line 2,689 ⟶ 3,062:
=={{header|Frink}}==
<
/** Set up the recursive call for n disks */
hanoi[n] := hanoi[n, 1, 3, 2]
Line 2,705 ⟶ 3,078:
hanoi[7]
</syntaxhighlight>
=={{header|FutureBasic}}==
<
void local fn Move( n as long, fromPeg as long, toPeg as long, viaPeg as long )
Line 2,722 ⟶ 3,095:
print "Towers of Hanoi puzzle solved."
HandleEvents</
Output:
Line 2,747 ⟶ 3,120:
=={{header|Fōrmulæ}}==
{{FormulaeEntry|page=https://formulae.org/?script=examples/Tower_of_Hanoi}}
'''Solution'''
[[File:Fōrmulæ - Tower of Hanoi 01.png]]
'''Test case'''
[[File:Fōrmulæ - Tower of Hanoi 02.png]]
[[File:Fōrmulæ - Tower of Hanoi 03.png]]
=={{header|Gambas}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang="vbnet">Public Sub Main()
Print "Three disks\n"
move_(3, 1, 2, 3)
Print
Print "Four disks\n"
move_(4, 1, 2, 3)
End
Public Sub move_(n As Integer, from As Integer, to As Integer, via As Integer)
If n > 0 Then
move_(n - 1, from, via, to)
Print "Move disk "; n; " from pole "; from; " to pole "; to
move_(n - 1, via, to, from)
End If
End Sub </syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
=={{header|GAP}}==
<
local move;
move := function(n, a, b, c) # from, through, to
Line 2,783 ⟶ 3,186:
# B -> A
# B -> C
# A -> C</
=={{header|Go}}==
<
import "fmt"
Line 2,827 ⟶ 3,230:
func (t *towers) move1(from, to int) {
fmt.Println("move disk from rod", from, "to rod", to)
}</
In other words:
<
import "fmt"
Line 2,845 ⟶ 3,248:
move(n-1, b, a, c)
}
}</
=={{header|Groovy}}==
Unlike most solutions here this solution manipulates more-or-less actual stacks of more-or-less actual rings.
<
final STACK = [A:[],B:[],C:[]].asImmutable()
Line 2,865 ⟶ 3,268:
moveRing(from, to)
moveStack(tail(using, n-1), to, from)
}</
Test program:
<
S('°'), M('o'), L('O'), XL('( )');
private sym
Line 2,880 ⟶ 3,283:
report()
check(STACK.A)
moveStack(STACK.A, STACK.C)</
{{out}}
Line 2,951 ⟶ 3,354:
(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:
<
hanoi 0 _ _ _ = []
hanoi n a b c = hanoi (n-1) a c b ++ [(a,b)] ++ hanoi (n-1) c b a</
You can also do the above with one tail-recursion call:
<
hanoi n a b c = hanoiToList n a b c []
where
hanoiToList 0 _ _ _ l = l
hanoiToList n a b c l = hanoiToList (n-1) a c b ((a, b) : hanoiToList (n-1) c b a l)</
One can use this function to produce output, just like the other programs:
<
f (x,y) = putStrLn $ "Move " ++ show x ++ " to " ++ show y</
or, instead, one can of course also program imperatively, using the IO monad directly:
<
hanoiM n = hanoiM' n 1 2 3 where
hanoiM' 0 _ _ _ = return ()
Line 2,973 ⟶ 3,376:
hanoiM' (n-1) a c b
putStrLn $ "Move " ++ show a ++ " to " ++ show b
hanoiM' (n-1) c b a</
or, defining it as a monoid, and adding some output:
<
hanoi ::
Line 3,005 ⟶ 3,408:
justifyRight :: Int -> Char -> String -> String
justifyRight n c = (drop . length) <*> (replicate n c <>)</
{{Out}}
<pre> left -> right
Line 3,041 ⟶ 3,444:
=={{header|HolyC}}==
{{trans|C}}
<
if (n > 0) {
Move(n - 1, from, via, to);
Line 3,049 ⟶ 3,452:
}
Move(4, 1, 2, 3);</
=={{header|Icon}} and {{header|Unicon}}==
The following is based on a solution in the Unicon book.
<
hanoi(arglist[1]) | stop("Usage: hanoi n\n\rWhere n is the number of disks to move.")
end
Line 3,075 ⟶ 3,478:
}
return
end</
=={{header|Imp77}}==
<syntaxhighlight lang="Imp77">
%begin
%routine do hanoi(%integer n, f, t, u)
do hanoi(n - 1, f, u, t) %if n >= 2
print string("Move disk from ".itos(f,0)." to ".itos(t,0).to string(nl))
do hanoi(n - 1, u, t, f) %if n >= 2
%end
do hanoi(4, 1, 2, 3)
print string("Towers of Hanoi puzzle completed!".to string(nl))
%end %of %program
</syntaxhighlight>
{{out}}
<pre>
Move disk from 1 to 3
Move disk from 1 to 2
Move disk from 3 to 2
Move disk from 1 to 3
Move disk from 2 to 1
Move disk from 2 to 3
Move disk from 1 to 3
Move disk from 1 to 2
Move disk from 3 to 2
Move disk from 3 to 1
Move disk from 2 to 1
Move disk from 3 to 2
Move disk from 1 to 3
Move disk from 1 to 2
Move disk from 3 to 2
Towers of Hanoi puzzle completed!
</pre>
=={{header|Inform 7}}==
<
A post is a kind of supporter. A post is always fixed in place.
Line 3,102 ⟶ 3,537:
if a topmost disk (called TD) is enclosed by TP, now D is on TD;
otherwise now D is on TP;
move N - 1 disks from VP to TP via FP.</
=={{header|Io}}==
<
if (n == 1) then (
writeln("Move from ", from, " to ", to)
Line 3,113 ⟶ 3,548:
hanoi(n - 1, via , to , from)
)
)</
=={{header|Ioke}}==
<
if(n < 2,
"#{f} --> #{t}" println,
Line 3,128 ⟶ 3,563:
hanoi = method(n,
H(n, 1, 2, 3)
)</
=={{header|J}}==
'''Solutions'''
<
{{out|Example use}}
<
0 2
0 1
Line 3,152 ⟶ 3,576:
1 2
1 0
2 0</
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:
<
if. y do.
({&0 2 1 , 0 2 , {&1 0 2) H1 y-1
Line 3,161 ⟶ 3,585:
i.0 2
end.
)</
The usage here is the same:
<pre> H1 2
Line 3,169 ⟶ 3,593:
;Alternative solution
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):
<
moves=. H y
disks=. $~` ((],[,]) $:@<:) @.* y
('move disk ';' from peg ';' to peg ');@,."1 ":&.>disks,.1+moves
)</
{{out|Demonstration}}
<
move disk 1 from peg 1 to peg 3
move disk 2 from peg 1 to peg 2
Line 3,182 ⟶ 3,606:
move disk 1 from peg 2 to peg 1
move disk 2 from peg 2 to peg 3
move disk 1 from peg 1 to peg 3</
=={{header|Java}}==
<
if (n == 1) {
System.out.println("Move disk from pole " + from + " to pole " + to);
Line 3,193 ⟶ 3,617:
move(n - 1, via, to, from);
}
}</
Where n is the number of disks to move and from, to, and via are the poles.
{{out|Example use}}
<syntaxhighlight lang="java">move(3, 1, 2, 3);</syntaxhighlight>
{{Out}}
<syntaxhighlight lang="java">Move disk from pole 1 to pole 2
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 3
Move disk from pole 1 to pole 2
Move disk from pole 3 to pole 1
Move disk from pole 3 to pole 2
Move disk from pole 1 to pole 2</syntaxhighlight>
=={{header|JavaScript}}==
===ES5===
<
if (n > 0) {
move(n-1, a, c, b);
Line 3,204 ⟶ 3,642:
}
}
move(4, "A", "B", "C");</
Or, as a functional expression, rather than a statement with side effects:
<
// hanoi :: Int -> String -> String -> String -> [[String, String]]
Line 3,224 ⟶ 3,662:
return d[0] + ' -> ' + d[1];
});
})();</
{{Out}}
<
"right -> mid", "left -> right",
"mid -> left", "mid -> right",
"left -> right"]</
===ES6===
<
"use strict";
Line 3,244 ⟶ 3,682:
const go = hanoi(n - 1);
return
...
[a, b],
};
Line 3,256 ⟶ 3,694:
// ---------------------- TEST -----------------------
return hanoi(3)("left", "right", "mid")
})();</
{{Out}}
<pre>left -> right
Line 3,269 ⟶ 3,707:
=={{header|Joy}}==
<syntaxhighlight lang="joy">DEFINE hanoi == [[rolldown] infra] dip
[[[null] [pop pop] ]
[[dup2 [[rotate] infra] dip pred]
[[dup rest put] dip
[]]]
condnestrec.</syntaxhighlight>
Using it (5 is the number of disks.)
<
=={{header|jq}}==
Line 3,294 ⟶ 3,731:
The truth of (b) follows from the fact that the algorithm emits an instruction of what to do when moving a single disk.
<
def move(n; From; To; Via):
if n > 0 then
Line 3,304 ⟶ 3,741:
move(n-1; Via; To; From)
else empty
end;</
'''Example''':
move(5; "A"; "B"; "C")
Line 3,310 ⟶ 3,747:
=={{header|Jsish}}==
From Javascript ES5 entry.
<
function move(n, a, b, c) {
Line 3,340 ⟶ 3,777:
Move disk from B to C
=!EXPECTEND!=
*/</
{{out}}
Line 3,348 ⟶ 3,785:
=={{header|Julia}}==
{{trans|R}}
<
function solve(n::Integer, from::Integer, to::Integer, via::Integer)
if n == 1
Line 3,360 ⟶ 3,797:
solve(4, 1, 2, 3)
</syntaxhighlight>
{{out}}
Line 3,382 ⟶ 3,819:
=={{header|K}}==
<
h[4;1;2;3]
1:1->3
Line 3,398 ⟶ 3,835:
1:1->3
2:1->2
1:3->2</
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.
<
1 2 1 3 1 2 1 4 1 2 1 3 1 2 1
1_{*1+&|x}'a:(2_vs!_2^4)
1 2 1 3 1 2 1 4 1 2 1 3 1 2 1</
=={{header|Klingphix}}==
{{trans|MiniScript}}
<
:moveDisc %B !B %C !C %A !A %n !n { n A C B }
Line 3,421 ⟶ 3,858:
3 1 3 2 moveDisc
" " input</
{{out}}
<pre>Move disc 1 from pole 1 to pole 3
Line 3,432 ⟶ 3,869:
=={{header|Kotlin}}==
<
class Hanoi(disks: Int) {
Line 3,456 ⟶ 3,893:
Hanoi(3)
Hanoi(4)
}</
{{out}}
Line 3,493 ⟶ 3,930:
</pre>
=={{header|
<
PSEUDO-CODE:
hanoi disks from A to B via C
if
then stop
else hanoi upper
hanoi upper disks from C to B via A
CODE:
{def hanoi
{lambda {:disks :a :b :c}
{if {A.empty? :disks}
then
else {hanoi {A.rest :disks} :a :c :b}
{div > move
{hanoi {A.rest :disks} :c :b :a} }}}
-> hanoi
{hanoi {A.new ==== === == =} A B C}
->
> move
> move
> move = from C to B
> move === from A to C
> move = from B to A
> move == from B to C
> move = from A to C
> move ==== from A to B
> move = from C to B
> move == from C to A
> move = from B to A
> move === from C to B
> move = from A to C
> move == from A to B
> move = from C to B
</syntaxhighlight>
=={{header|Lasso}}==
<
define towermove(
Line 3,536 ⟶ 3,986:
}
towermove((integer($argv -> second || 3)), "A", "B", "C")</
Called from command line:
<syntaxhighlight lang
{{out}}
<pre>Move disk from A to C
Line 3,548 ⟶ 3,998:
Move disk from A to C</pre>
Called from command line:
<syntaxhighlight lang
{{out}}
<pre>Move disk from A to B
Line 3,568 ⟶ 4,018:
=={{header|Liberty BASIC}}==
This looks much better with a GUI interface.
<
via$ ="B"
target$ ="C"
Line 3,586 ⟶ 4,036:
end sub
end</
=={{header|Lingo}}==
<
if n > 0 then
hanoi(n-1, a, c, b)
Line 3,595 ⟶ 4,045:
hanoi(n-1, b, a, c)
end if
end</
<
-- "Move disk from A to C"
-- "Move disk from A to B"
Line 3,603 ⟶ 4,053:
-- "Move disk from B to A"
-- "Move disk from B to C"
-- "Move disk from A to C"</
=={{header|Logo}}==
<
if :n = 0 [stop]
move :n-1 :from :via :to
Line 3,612 ⟶ 4,062:
move :n-1 :via :to :from
end
move 4 "left "middle "right</
=={{header|Logtalk}}==
<
:- public(run/1).
Line 3,643 ⟶ 4,093:
nl.
:- end_object.</
=={{header|LOLCODE}}==
<
HOW IZ I HANOI YR N AN YR SRC AN YR DST AN YR VIA
Line 3,665 ⟶ 4,115:
KTHXBYE
</syntaxhighlight>
=={{header|Lua}}==
<
if n > 0 then
move(n - 1, src, via, dst)
Line 3,676 ⟶ 4,126:
end
move(4, 1, 2, 3)</
{{More informative version }}
<syntaxhighlight lang="lua">
function move(n, src, via, dst)
Line 3,692 ⟶ 4,142:
move(4, 1, 2, 3)
</syntaxhighlight>
===Hanoi Iterative===
<
#!/usr/bin/env luajit
local function printf(fmt, ...) io.write(string.format(fmt, ...)) end
Line 3,736 ⟶ 4,186:
hanoi(num)
</syntaxhighlight>
{{out}}
<pre>
Line 3,744 ⟶ 4,194:
===Hanoi Bitwise Fast===
<
#!/usr/bin/env luajit
-- binary solution
Line 3,759 ⟶ 4,209:
hanoi(num)
</syntaxhighlight>
{{out}}
<pre>
Line 3,770 ⟶ 4,220:
=={{header|M2000 Interpreter}}==
{{trans|FreeBasic}}
<syntaxhighlight lang="m2000 interpreter">
Module Hanoi {
Rem HANOI TOWERS
Line 3,788 ⟶ 4,238:
}
Hanoi
</syntaxhighlight>
{{out}}
same as in FreeBasic
=={{header|MACRO-11}}==
<syntaxhighlight lang="macro11"> .TITLE HANOI
.MCALL .PRINT,.EXIT
HANOI:: MOV #4,R2
MOV #61,R3
MOV #62,R4
MOV #63,R5
JSR PC,MOVE
.EXIT
MOVE: DEC R2
BLT 1$
MOV R2,-(SP)
MOV R3,-(SP)
MOV R4,-(SP)
MOV R5,-(SP)
MOV R5,R0
MOV R4,R5
MOV R0,R4
JSR PC,MOVE
MOV (SP)+,R5
MOV (SP)+,R4
MOV (SP)+,R3
MOV (SP)+,R2
MOVB R3,3$
MOVB R4,4$
.PRINT #2$
MOV R3,R0
MOV R4,R3
MOV R5,R4
MOV R0,R5
BR MOVE
1$: RTS PC
2$: .ASCII /MOVE DISK FROM PEG /
3$: .ASCII /* TO PEG /
4$: .ASCIZ /*/
.EVEN
.END HANOI</syntaxhighlight>
{{out}}
<pre>MOVE DISK FROM PEG 1 TO PEG 3
MOVE DISK FROM PEG 1 TO PEG 2
MOVE DISK FROM PEG 2 TO PEG 3
MOVE DISK FROM PEG 1 TO PEG 3
MOVE DISK FROM PEG 3 TO PEG 1
MOVE DISK FROM PEG 3 TO PEG 2
MOVE DISK FROM PEG 2 TO PEG 1
MOVE DISK FROM PEG 1 TO PEG 2
MOVE DISK FROM PEG 2 TO PEG 3
MOVE DISK FROM PEG 2 TO PEG 1
MOVE DISK FROM PEG 1 TO PEG 3
MOVE DISK FROM PEG 2 TO PEG 3
MOVE DISK FROM PEG 3 TO PEG 2
MOVE DISK FROM PEG 3 TO PEG 1
MOVE DISK FROM PEG 1 TO PEG 2</pre>
=={{header|MAD}}==
<
DIMENSION LIST(100)
SET LIST TO LIST
Line 3,831 ⟶ 4,335:
END OF PROGRAM
</syntaxhighlight>
{{out}}
Line 3,850 ⟶ 4,354:
MOVE DISK FROM POLE 1 TO POLE 3
MOVE DISK FROM POLE 2 TO POLE 3</pre>
=={{header|Maple}}==
<syntaxhighlight lang="maple">
Hanoi := proc(n::posint,a,b,c)
if n = 1 then
Line 3,866 ⟶ 4,369:
printf("Moving 2 disks from tower A to tower C using tower B.\n");
Hanoi(2,A,B,C);
</syntaxhighlight>
{{out}}
Line 3,879 ⟶ 4,382:
=={{header|Mathematica}}/{{header|Wolfram Language}}==
<
Hanoi[n_Integer, from_, to_, via_] := (Hanoi[n-1, from, via, to];Print["Move disk from pole ", from, " to ", to, "."];Hanoi[n-1, via, to, from])</
=={{header|MATLAB}}==
This is a direct translation from the Python example given in the Wikipedia entry for the Tower of Hanoi puzzle.
<
if (n~=0)
towerOfHanoi(n-1,A,B,C);
Line 3,890 ⟶ 4,393:
towerOfHanoi(n-1,B,C,A);
end
end</
{{out|Sample output}}
<pre>towerOfHanoi(3,1,3,2)
Line 3,902 ⟶ 4,405:
=={{header|MiniScript}}==
<
if n == 0 then return
moveDisc n-1, A, B, C
Line 3,910 ⟶ 4,413:
// Move disc 3 from pole 1 to pole 3, with pole 2 as spare
moveDisc 3, 1, 3, 2</
{{out}}
<pre>Move disc 1 from pole 1 to pole 3
Line 3,919 ⟶ 4,422:
Move disc 2 from pole 2 to pole 3
Move disc 1 from pole 1 to pole 3</pre>
=={{header|Miranda}}==
<syntaxhighlight lang="miranda">main :: [sys_message]
main = [Stdout (lay (map showmove (move 4 1 2 3)))]
showmove :: (num,num)->[char]
showmove (src,dest)
= "Move disk from pole " ++ show src ++ " to pole " ++ show dest
move :: num->*->*->*->[(*,*)]
move n src via dest
= [], if n=0
= left ++ [(src,dest)] ++ right, otherwise
where left = move (n-1) src dest via
right = move (n-1) via src dest</syntaxhighlight>
{{out}}
<pre>Move disk from pole 1 to pole 2
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 3
Move disk from pole 1 to pole 2
Move disk from pole 3 to pole 1
Move disk from pole 3 to pole 2
Move disk from pole 1 to pole 2
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 3
Move disk from pole 2 to pole 1
Move disk from pole 3 to pole 1
Move disk from pole 2 to pole 3
Move disk from pole 1 to pole 2
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 3</pre>
=={{header|MIPS Assembly}}==
Line 3,934 ⟶ 4,468:
hanoi(3)
--><
# Towers of Hanoi
# MIPS assembly implementation (tested with MARS)
Line 4,036 ⟶ 4,570:
beq $s0, $t1, exithanoi
j recur2
</syntaxhighlight>
=={{header|МК-61/52}}==
<syntaxhighlight lang="text">^ 2 x^y П0 <-> 2 / {x} x#0 16
3 П3 2 П2 БП 20 3 П2 2 П3
1 П1 ПП 25 КППB ПП 28 КППA ПП 31
Line 4,047 ⟶ 4,581:
ИП2 ИП1 КППC ИП1 ИП2 ИП3 П1 -> П3 ->
П2 В/О 1 0 / + С/П КИП0 ИП0 x=0
89 3 3 1 ИНВ ^ ВП 2 С/П В/О</
Instruction: РA = 56; РB = 60; РC = 72; N В/О С/П, where 2 <= N <= 7.
=={{header|Modula-2}}==
<
FROM FormatString IMPORT FormatString;
FROM Terminal IMPORT WriteString,ReadChar;
Line 4,071 ⟶ 4,605:
ReadChar
END Towers.</
=={{header|Modula-3}}==
<
FROM IO IMPORT Put;
Line 4,090 ⟶ 4,624:
BEGIN
doHanoi(4, 1, 2, 3);
END Hanoi.</
=={{header|Monte}}==
<
if (n > 0):
move(n.previous(), fromPeg, viaPeg, toPeg)
Line 4,099 ⟶ 4,633:
move(n.previous(), viaPeg, toPeg, fromPeg)
move(3, "left", "right", "middle")</
=={{header|MoonScript}}==
<
if n > 1
hanoi n-1, src, via, dest
Line 4,109 ⟶ 4,643:
hanoi n-1, via, dest, src
hanoi 4,1,3,2</
{{Out}}
<pre>1 -> 2
Line 4,127 ⟶ 4,661:
2 -> 3</pre>
=={{header|Nemerle}}==
<
using System.Console;
Line 4,146 ⟶ 4,680:
Hanoi(4)
}
}</
=={{header|NetRexx}}==
<
options replace format comments java crossref symbols binary
Line 4,155 ⟶ 4,689:
return
-- 09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)~~
method runSample(arg) private static
parse arg discs .
Line 4,164 ⟶ 4,698:
return
-- 09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)09:02, 27 August 2022 (UTC)~~
method move(discs = int 4, towerFrom = int 1, towerTo = int 2, towerVia = int 3, moves = int 0) public static
if discs == 1 then do
Line 4,176 ⟶ 4,710:
end
return moves
</syntaxhighlight>
{{out}}
<pre>
Line 4,199 ⟶ 4,733:
=={{header|NewLISP}}==
<
(if (> n 0)
(move (- n 1) from via to
Line 4,205 ⟶ 4,739:
(move (- n 1) via to from))))
(move 4 1 2 3)</
=={{header|Nim}}==
<
if disks != 0:
hanoi(disks - 1, fromTower, viaTower, toTower)
Line 4,214 ⟶ 4,748:
hanoi(disks - 1, viaTower, toTower, fromTower)
hanoi(4, "1", "2", "3")</
{{out}}
<pre>Move disk 1 from 1 to 3
Line 4,231 ⟶ 4,765:
Move disk 2 from 1 to 2
Move disk 1 from 3 to 2</pre>
=={{header|Oberon-2}}==
{{trans|C}}
<syntaxhighlight lang="oberon2">MODULE Hanoi;
IMPORT Out;
PROCEDURE Move(n,from,via,to:INTEGER);
BEGIN
IF n > 1 THEN
Move(n-1,from,to,via);
Out.String("Move disk from pole ");
Out.Int(from,0);
Out.String(" to pole ");
Out.Int(to,0);
Out.Ln;
Move(n-1,via,from,to);
ELSE
Out.String("Move disk from pole ");
Out.Int(from,0);
Out.String(" to pole ");
Out.Int(to,0);
Out.Ln;
END;
END Move;
BEGIN
Move(4,1,2,3);
END Hanoi.
</syntaxhighlight>
{{out}}
<pre>Move disk from pole 1 to pole 2
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 3
Move disk from pole 1 to pole 2
Move disk from pole 3 to pole 1
Move disk from pole 3 to pole 2
Move disk from pole 1 to pole 2
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 3
Move disk from pole 2 to pole 1
Move disk from pole 3 to pole 1
Move disk from pole 2 to pole 3
Move disk from pole 1 to pole 2
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 3
</pre>
=={{header|Objeck}}==
<
function : Main(args : String[]) ~ Nil {
Move(4, 1, 2, 3);
Line 4,248 ⟶ 4,830:
};
}
}</
=={{header|Objective-C}}==
Line 4,257 ⟶ 4,839:
The Interface - TowersOfHanoi.h:
<
@interface TowersOfHanoi: NSObject {
Line 4,268 ⟶ 4,850:
-(void) setPegFrom: (int) from andSetPegTo: (int) to andSetPegVia: (int) via andSetNumDisks: (int) disks;
-(void) movePegFrom: (int) from andMovePegTo: (int) to andMovePegVia: (int) via andWithNumDisks: (int) disks;
@end</
The Implementation - TowersOfHanoi.m:
<
@implementation TowersOfHanoi
Line 4,290 ⟶ 4,872:
}
@end</
Test code: TowersTest.m:
<
#import "TowersOfHanoi.h"
Line 4,311 ⟶ 4,893:
}
return 0;
}</
=={{header|OCaml}}==
<
if n <> 0 then begin
hanoi (pred n) a c b;
Line 4,322 ⟶ 4,904:
let () =
hanoi 4 1 2 3</
=={{header|Octave}}==
<
if ( ndisks == 1 )
printf("Move disk from pole %d to pole %d\n", from, to);
Line 4,335 ⟶ 4,917:
endfunction
hanoimove(4, 1, 2, 3);</
=={{header|Oforth}}==
<
n 0 > ifTrue: [
move(n 1-, from, via, to)
Line 4,346 ⟶ 4,928:
] ;
5 $left $middle $right) move </
=={{header|Oz}}==
<
proc {TowersOfHanoi N From To Via}
if N > 0 then
Line 4,358 ⟶ 4,940:
end
in
{TowersOfHanoi 4 left middle right}</
=={{header|PARI/GP}}==
{{trans|Python}}
<
\\ 8/19/2016 aev
\\ Where: n - number of disks, sp - start pole, ep - end pole.
Line 4,374 ⟶ 4,956:
}
\\ Testing n=3:
HanoiTowers(3,1,3);</
{{Output}}
Line 4,391 ⟶ 4,973:
{{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.
<
type
TPole = (tpLeft, tpCenter, tpRight);
Line 4,408 ⟶ 4,990:
begin
MoveStack(4,tpLeft,tpCenter,tpRight);
end.</
A little longer, but clearer for my taste
<
type
TPole = (tpLeft, tpCenter, tpRight);
Line 4,434 ⟶ 5,016:
begin
MoveStack(4,tpLeft,tpCenter,tpRight);
end.</
=={{header|PascalABC.NET}}==
<syntaxhighlight lang="delphi">
## procedure Hanoi(n,rfrom,rto,rwork: integer);
begin
if n = 0 then
exit;
Hanoi(n-1,rfrom,rwork,rto);
Print($'{rfrom}→{rto} ');
Hanoi(n-1,rwork,rto,rfrom);
end;
Hanoi(5,1,3,2);
</syntaxhighlight>
{{out}}
<pre>
1→3 1→2 3→2 1→3 2→1 2→3 1→3 1→2 3→2 3→1 2→1 3→2 1→3 1→2 3→2 1→3 2→1 2→3 1→3 2→1 3→2 3→1 2→1 2→3 1→3 1→2 3→2 1→3 2→1 2→3 1→3 </pre>
=={{header|Perl}}==
<
my ($n, $from, $to, $via) = (@_, 1, 2, 3);
Line 4,447 ⟶ 5,045:
hanoi($n - 1, $via, $to, $from);
};
};</
=={{header|Phix}}==
<!--<
<span style="color: #008080;">constant</span> <span style="color: #000000;">poles</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"left"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"middle"</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"right"</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">enum</span> <span style="color: #000000;">left</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">middle</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">right</span>
Line 4,485 ⟶ 5,083:
<span style="color: #000000;">hanoi</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span> <span style="color: #000080;font-style:italic;">-- (output of 4,5,6 also shown)</span>
<!--</
{{Out}}
<pre style="float:left">
Line 4,616 ⟶ 5,214:
{{trans|C}}
<
extern printf;
Line 4,631 ⟶ 5,229:
move(4, 1,2,3);
return 0;
]</
=={{header|PHP}}==
{{trans|Java}}
<
if ($n === 1) {
print("Move disk from pole $from to pole $to");
Line 4,643 ⟶ 5,241:
move($n-1,$via,$to,$from);
}
}</
=={{header|Picat}}==
<
hanoi(3, left, center, right).
Line 4,654 ⟶ 5,252:
printf("Move disk %w from pole %w to pole %w\n", N, From, To),
hanoi(N - 1, Via, To, From).
</syntaxhighlight>
{{out}}
Line 4,668 ⟶ 5,266:
===Fast counting===
<
hanoi(64).
Line 4,682 ⟶ 5,280:
Count2 = move(N - 1, Via, To, From),
Count = Count1+Count2+1.
</syntaxhighlight>
{{out}}
<pre>
Line 4,689 ⟶ 5,287:
=={{header|PicoLisp}}==
<
(unless (=0 N)
(move (dec N) A C B)
(println 'Move 'disk 'from A 'to B)
(move (dec N) C B A) ) )</
=={{header|PL/I}}==
{{trans|Fortran}}
<
call Move (4,1,2,3);
Line 4,715 ⟶ 5,313:
end Move;
end tower;</
=={{header|PL/M}}==
Line 4,721 ⟶ 5,319:
Iterative solution as PL/M doesn't do recursion.
{{works with|8080 PL/M Compiler}} ... under CP/M (or an emulator)
<
/* CP/M BDOS SYSTEM CALL */
Line 4,745 ⟶ 5,343:
CALL PR$STRING( .( 0DH, 0AH, '$' ) );
END;
EOF</
{{out}}
<pre>
Line 4,767 ⟶ 5,365:
=={{header|PlainTeX}}==
<
\def\hanoi#1{%
\hanoidepth = #1
Line 4,785 ⟶ 5,383:
\hanoi{5}
\end</
=={{header|Pop11}}==
<
if n > 0 then
hanoi(n - 1, src, via, dst);
Line 4,796 ⟶ 5,394:
enddefine;
hanoi(4, "left", "middle", "right");</
=={{header|PostScript}}==
A million-page document, each page showing one move.
<
%%BoundingBox: 0 0 300 300
Line 4,847 ⟶ 5,445:
drawtower 0 1 2 n hanoi
%%EOF</
=={{header|PowerShell}}==
{{works with|PowerShell|4.0}}
<syntaxhighlight lang="powershell">
function hanoi($n, $a, $b, $c) {
if($n -eq 1) {
Line 4,863 ⟶ 5,461:
}
hanoi 3 "A" "B" "C"
</syntaxhighlight>
<b>Output:</b>
<pre>
Line 4,877 ⟶ 5,475:
=={{header|Prolog}}==
From Programming in Prolog by W.F. Clocksin & C.S. Mellish
<
move(0,_,_,_) :- !.
Line 4,886 ⟶ 5,484:
move(M,C,B,A).
inform(X,Y) :- write([move,a,disk,from,the,X,pole,to,Y,pole]), nl.</
Using DCGs and separating core logic from IO
<
hanoi(N, Src, Aux, Dest, Moves-NMoves) :-
NMoves is 2^N - 1,
Line 4,907 ⟶ 5,505:
move(1, Src, Aux, Dest),
move(N0, Aux, Src, Dest).
</syntaxhighlight>
=={{header|PureBasic}}==
Algorithm according to http://en.wikipedia.org/wiki/Towers_of_Hanoi
<
If n
Hanoi(n-1, A, B, C)
Line 4,917 ⟶ 5,515:
Hanoi(n-1, B, C, A)
EndIf
EndProcedure</
Full program
<
If n
Hanoi(n-1, A, B, C)
Line 4,932 ⟶ 5,530:
Hanoi(n,"Left Peg","Middle Peg","Right Peg")
PrintN(#CRLF$+"Press ENTER to exit."): Input()
EndIf</
{{out}}
Moving 3 pegs.
Line 4,948 ⟶ 5,546:
=={{header|Python}}==
===Recursive===
<
if ndisks:
hanoi(ndisks-1, startPeg, 6-startPeg-endPeg)
print
hanoi(ndisks-1, 6-startPeg-endPeg, endPeg)
hanoi(
{{out}} for ndisks=2
<pre>
Line 4,965 ⟶ 5,563:
Or, separating the definition of the data from its display:
{{Works with|Python|3.7}}
<
Line 4,992 ⟶ 5,590:
print(__doc__ + ':\n\n' + '\n'.join(
map(fromTo, hanoi(4)('left')('right')('mid'))
))</
{{Out}}
<pre>Towers of Hanoi:
Line 5,016 ⟶ 5,614:
Refactoring the version above to recursively generate a simple visualisation:
{{Works with|Python|3.7}}
<
from itertools import accumulate, chain, repeat
Line 5,212 ⟶ 5,810:
# TEST ----------------------------------------------------
if __name__ == '__main__':
main()</
<pre>Hanoi sequence for 3 disks:
Line 5,261 ⟶ 5,859:
=={{header|Quackery}}==
<
[ rings share
Line 5,281 ⟶ 5,879:
say 'How to solve a three ring Towers of Hanoi puzzle:' cr cr
3 hanoi cr</
{{out}}
Line 5,308 ⟶ 5,906:
'This is implemented on the Quite BASIC website
'http://www.quitebasic.com/prj/puzzle/towers-of-hanoi/
<
1010 REM Quite BASIC Puzzle Project
1020 CLS
Line 5,481 ⟶ 6,079:
9110 REM Restore N before returning
9120 LET N = N + 1
9130 RETURN</
=={{header|R}}==
{{trans|Octave}}
<
if (ndisks == 1) {
cat("move disk from", from, "to", to, "\n")
Line 5,495 ⟶ 6,093:
}
hanoimove(4, 1, 2, 3)</
=={{header|Racket}}==
<
#lang racket
(define (hanoi n a b c)
Line 5,506 ⟶ 6,104:
(hanoi (- n 1) c b a)))
(hanoi 4 'left 'middle 'right)
</syntaxhighlight>
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku"
multi hanoi (0, Peg $a, Peg $b, Peg $c) { }
Line 5,517 ⟶ 6,115:
say "Move $a to $b.";
hanoi $n - 1, $c, $b, $a;
}</
=={{header|Rascal}}==
{{trans|Python}}
<
if(ndisks>0){
hanoi(ndisks-1, startPeg, 6 - startPeg - endPeg);
Line 5,527 ⟶ 6,125:
hanoi(ndisks-1, 6 - startPeg - endPeg, endPeg);
}
}</
{{out}}
<
Move disk 1 from peg 1 to peg 2
Move disk 2 from peg 1 to peg 3
Line 5,545 ⟶ 6,143:
Move disk 2 from peg 1 to peg 3
Move disk 1 from peg 2 to peg 3
ok</
=={{header|Raven}}==
{{trans|Python}}
<
ndisks 0 > if
6 startpeg - endpeg - startpeg ndisks 1 - hanoi
Line 5,561 ⟶ 6,159:
# 4 disks
4 dohanoi
</syntaxhighlight>
{{out}}
<pre>raven hanoi.rv
Line 5,582 ⟶ 6,180:
=={{header|REBOL}}==
<
Title: "Towers of Hanoi"
URL: http://rosettacode.org/wiki/Towers_of_Hanoi
Line 5,602 ⟶ 6,200:
]
hanoi 4</
{{out}}
<pre>left -> right
Line 5,619 ⟶ 6,217:
left -> middle
right -> middle</pre>
=={{header|Refal}}==
<syntaxhighlight lang="refal">$ENTRY Go {
= <Move 4 1 2 3>;
};
Move {
0 e.X = ;
s.N s.Src s.Via s.Dest, <- s.N 1>: s.Next =
<Move s.Next s.Src s.Dest s.Via>
<Prout "Move disk from pole" s.Src "to pole" s.Dest>
<Move s.Next s.Via s.Src s.Dest>;
};</syntaxhighlight>
{{out}}
<pre>Move disk from pole 1 to pole 2
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 3
Move disk from pole 1 to pole 2
Move disk from pole 3 to pole 1
Move disk from pole 3 to pole 2
Move disk from pole 1 to pole 2
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 3
Move disk from pole 2 to pole 1
Move disk from pole 3 to pole 1
Move disk from pole 2 to pole 3
Move disk from pole 1 to pole 2
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 3</pre>
=={{header|Retro}}==
<syntaxhighlight lang="retro">[[User:Wodan58|Wodan58]] ([[User talk:Wodan58|talk]])
{ 'Num 'From 'To 'Via } [ var ] a:for-each
Line 5,634 ⟶ 6,261:
#3 #1 #3 #2 hanoi nl
[[User:Wodan58|Wodan58]] ([[User talk:Wodan58|talk]])</syntaxhighlight>
=={{header|REXX}}==
===simple text moves===
<
parse arg N . /*get optional number of disks from CL.*/
if N=='' | N=="," then N=3 /*Not specified? Then use the default.*/
Line 5,656 ⟶ 6,283:
call mov 6 - @1 - @2, @2, @3 -1
end
return /* [↑] this subroutine uses recursion.*/</
{{out|output|text= when using the default input:}}
<pre>
Line 5,700 ⟶ 6,327:
Also, since the pictorial showing of the moves may be voluminous (especially for a larger number of disks), the move counter is started with the maximum and is the count shown is decremented so the viewer can see how many moves are left to display.
<
parse arg N . /*get optional number of disks from CL.*/
if N=='' | N=="," then N=3 /*Not specified? Then use the default.*/
Line 5,761 ⟶ 6,388:
return /*it uses no variables, is uses BIFs instead*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
showTowers: do j=N by -1 for N; _=@.1.j @.2.j @.3.j; if _\='' then say _; end; return</
{{out|output|text= when using the default input:}}
<pre>
Line 5,813 ⟶ 6,440:
=={{header|Ring}}==
<
move(4, 1, 2, 3)
Line 5,820 ⟶ 6,447:
see "" + src + " to " + dst + nl
move(n - 1, via, dst, src) ok
</syntaxhighlight>
=={{header|RPL}}==
{{trans|Python}}
{{works with|Halcyon Calc|4.2.7}}
≪ → ndisks start end
≪ '''IF''' ndisks '''THEN'''
ndisks 1 - start 6 start - end - '''HANOI'''
start →STR " → " + end →STR +
ndisks 1 - 6 start - end - end '''HANOI'''
'''END'''
≫ ≫ ''''HANOI'''' STO
3 1 3 '''HANOI'''
{{out}}
<pre>
7: "1 → 3"
6: "1 → 2"
5: "3 → 2"
4: "1 → 3"
3: "2 → 1"
2: "2 → 3"
1: "1 → 3"
</pre>
=={{header|Ruby}}==
===version 1===
<
if num_disks == 1
@towers[target] << @towers[start].pop
Line 5,837 ⟶ 6,487:
n = 5
@towers = [[*1..n].reverse, [], []]
move(n)</
{{out}}
Line 5,875 ⟶ 6,525:
===version 2===
<
# Example:
# solve([5, 4, 3, 2, 1], [], [])
Line 5,903 ⟶ 6,553:
end
solve([5, 4, 3, 2, 1], [], [])</
{{out}}
<pre>
Line 5,941 ⟶ 6,591:
=={{header|Run BASIC}}==
<
function move(n, a$, b$, c$)
if n > 0 then
Line 5,948 ⟶ 6,598:
a = move(n-1, b$, a$, c$)
end if
end function</
<pre>Move disk from 1 to 3
Move disk from 1 to 2
Line 5,967 ⟶ 6,617:
=={{header|Rust}}==
{{trans|C}}
<
if n > 0 {
move_(n - 1, from, via, to);
Line 5,977 ⟶ 6,627:
fn main() {
move_(4, 1,2,3);
}</
=={{header|SASL}}==
Copied from SAL manual, Appendix II, answer (3)
<
WHERE
hanoi 0 (a,b,c,) = ()
Line 5,987 ⟶ 6,637:
‘move a disc from " , a , ‘ to " , b , NL ,
hanoi (n-1) (c,b,a)
?</
=={{header|Sather}}==
{{trans|Fortran}}
<
move(ndisks, from, to, via:INT) is
Line 6,006 ⟶ 6,656:
move(4, 1, 2, 3);
end;
end;</
=={{header|Scala}}==
<
if (n == 1) {
Console.println("Move disk from pole " + from + " to pole " + to)
Line 6,017 ⟶ 6,667:
move(n - 1, via, to, from)
}
}</
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
<
import scala.reflect.Manifest
Line 6,054 ⟶ 6,704:
run[_2,Left,Right,Center]
}
}</
=={{header|Scheme}}==
Recursive Process
<
(define (print-move from to)
(display "Move[")
Line 6,072 ⟶ 6,722:
(towers-of-hanoi (- n 1) spare to from))))
(towers-of-hanoi 3 "A" "B" "C")</
{{out}}
<pre>Move[A, B]
Line 6,084 ⟶ 6,734:
=={{header|Seed7}}==
<
begin
if disk > 0 then
Line 6,091 ⟶ 6,741:
hanoi(pred(disk), via, dest, source);
end if;
end func;</
=={{header|SETL}}==
<syntaxhighlight lang="setl">program hanoi;
loop for [src, dest] in move(4, 1, 2, 3) do
print("Move disk from pole " + src + " to pole " + dest);
end loop;
proc move(n, src, via, dest);
if n=0 then return []; end if;
return move(n-1, src, dest, via)
+ [[src, dest]]
+ move(n-1, via, src, dest);
end proc;
end program;</syntaxhighlight>
{{out}}
<pre>Move disk from pole 1 to pole 2
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 3
Move disk from pole 1 to pole 2
Move disk from pole 3 to pole 1
Move disk from pole 3 to pole 2
Move disk from pole 1 to pole 2
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 3
Move disk from pole 2 to pole 1
Move disk from pole 3 to pole 1
Move disk from pole 2 to pole 3
Move disk from pole 1 to pole 2
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 3</pre>
=={{header|Sidef}}==
{{trans|Perl}}
<
if (n == 1) {
say "Move disk from pole #{from} to pole #{to}.";
Line 6,105 ⟶ 6,785:
}
hanoi(4);</
=={{header|SNOBOL4}}==
<
define('hanoi(n,src,trg,tmp)') :(hanoi_end)
Line 6,120 ⟶ 6,800:
* # Test with 4 discs
hanoi(4,'A','C','B')
end</
{{out}}
<pre>1: Move disc from A to B
Line 6,137 ⟶ 6,817:
14: Move disc from A to C
15: Move disc from B to C</pre>
=={{header|SparForte}}==
As a structured script.
<syntaxhighlight lang="ada">#!/usr/local/bin/spar
pragma annotate( summary, "hanoi" )
@( description, "Solve the Towers of Hanoi problem with recursion." )
@( see_also, "https://rosettacode.org/wiki/Towers_of_Hanoi" )
@( author, "Ken O. Burtch" );
pragma license( unrestricted );
pragma restriction( no_external_commands );
procedure hanoi is
type pegs is (left, center, right);
-- Determine the moves
procedure solve( num_disks : natural; start_peg : pegs; end_peg : pegs; via_peg : pegs ) is
begin
if num_disks > 0 then
solve( num_disks - 1, start_peg, via_peg, end_peg );
put( "Move disk" )@( num_disks )@( " from " )@( start_peg )@( " to " )@( end_peg );
new_line;
solve( num_disks - 1, via_peg, end_peg, start_peg );
end if;
end solve;
begin
-- solve with 4 disks at the left
--solve( 4, left, right, center );
solve( 4, left, right, center );
put_line( "Towers of Hanoi puzzle completed" );
end hanoi;</syntaxhighlight>
=={{header|Standard ML}}==
Line 6,144 ⟶ 6,857:
=={{header|Stata}}==
<
if (n>0) {
hanoi(n-1, a, c, b)
Line 6,160 ⟶ 6,873:
Move from 3 to 1
Move from 3 to 2
Move from 1 to 2</
=={{header|Swift}}==
{{trans|JavaScript}}
<
if (n > 0) {
hanoi(n - 1, a, c, b)
Line 6,172 ⟶ 6,885:
}
hanoi(4, "A", "B", "C")</
'''Swift 2.1'''
<
if (n > 0) {
hanoi(n - 1, a: a, b: c, c: b)
Line 6,183 ⟶ 6,896:
}
hanoi(4, a:"A", b:"B", c:"C")</
=={{header|Tcl}}==
The use of <code>interp alias</code> shown is a sort of closure: keep track of the number of moves required
<
proc do_hanoi {count n {from A} {to C} {via B}} {
Line 6,201 ⟶ 6,914:
}
hanoi 4</
{{out}}
<pre>1: move from A to B
Line 6,221 ⟶ 6,934:
=={{header|TI-83 BASIC}}==
TI-83 BASIC lacks recursion, so technically this task is impossible, however here is a version that uses an iterative method.
<
0→A
1→B
Line 6,302 ⟶ 7,015:
End
</syntaxhighlight>
=={{header|Tiny BASIC}}==
Line 6,309 ⟶ 7,022:
But as if by magic, it turns out that the source and destination pegs on iteration number n are given by (n&n-1) mod 3 and ((n|n-1) + 1) mod 3 respectively, where & and | are the bitwise and and or operators. Line 40 onward is dedicated to implementing those bitwise operations, since Tiny BASIC hasn't got them natively.
<
INPUT D
IF D < 1 THEN GOTO 5
Line 6,353 ⟶ 7,066:
LET Z = Z / 2
IF Z = 0 THEN RETURN
GOTO 55</
{{out}}<pre>
Line 6,376 ⟶ 7,089:
=={{header|Toka}}==
<
[ to sc to sb to sa to n ] is vars!
[ ( num from to via -- )
Line 6,388 ⟶ 7,101:
n 1- sc sb sa recurse
] ifTrue
] is hanoi</
=={{header|True BASIC}}==
{{trans|FreeBASIC}}
<
DECLARE SUB hanoi
Line 6,414 ⟶ 7,127:
PRINT "Pulsa un tecla para salir"
END
</syntaxhighlight>
=={{header|TSE SAL}}==
<
PROC PROCProgramRunTowersofhanoiRecursiveSub( INTEGER totalDiskI, STRING fromS, STRING toS, STRING viaS, INTEGER bufferI )
IF ( totalDiskI == 0 )
Line 6,442 ⟶ 7,155:
IF ( NOT ( Ask( "program: run: towersofhanoi: recursive: totalDiskI = ", s1, _EDIT_HISTORY_ ) ) AND ( Length( s1 ) > 0 ) ) RETURN() ENDIF
PROCProgramRunTowersofhanoiRecursive( Val( s1 ), "source", "target", "via" )
END</
=={{header|uBasic/4tH}}==
{{trans|C}}
<syntaxhighlight lang="text">Proc _Move(4, 1,2,3) ' 4 disks, 3 poles
End
Line 6,455 ⟶ 7,168:
Proc _Move (a@ - 1, d@, c@, b@)
EndIf
Return</
=={{header|
{{works with|
<syntaxhighlight lang
F ← |1.0 (
⟨
&p ⊏[1 2] &pf "Move disc [from to]: "
| F⍜(⊡0|-1)⍜(⊏[2 3]|⇌).
F⍜(⊡0|1◌).
F⍜(⊡0|-1)⍜(⊏[1 3]|⇌)
⟩≠1⊢.
)
F [4 1 2 3]
</syntaxhighlight>
{{out}}
<pre>
Move disc [from to]: [1 3]
Move disc [from to]: [1 2]
Move disc [from to]: [3 2]
Move disc [from to]: [1 3]
Move disc [from to]: [2 1]
Move disc [from to]: [2 3]
Move disc [from to]: [1 3]
Move disc [from to]: [1 2]
Move disc [from to]: [3 2]
Move disc [from to]: [3 1]
Move disc [from to]: [2 1]
Move disc [from to]: [3 2]
Move disc [from to]: [1 3]
Move disc [from to]: [1 2]
Move disc [from to]: [3 2]
</pre>
=={{header|UNIX Shell}}==
{{works with|Bourne Again SHell}}
{{works with|Korn Shell}}
{{works with|Z Shell}}
<syntaxhighlight lang="bash">function move {
typeset from=$2
typeset to=$3
typeset via=$4
if
move $(( n - 1 )) "$from" "$via" "$to"
echo "Move disk from pole $from to pole $to"
move $(( n - 1 )) "$via" "$to" "$from"
fi
}
move "$
A strict POSIX (or just really old) shell has no subprogram capability, but scripts are naturally reentrant, so:
{{works with|Bourne Shell}}
{{works with|Almquist Shell}}
<syntaxhighlight lang="bash">#!/bin/sh
if [ "$1" -gt 0 ]; then
"$0" "`expr $1 - 1`" "$2" "$4" "$3"
echo "Move disk from pole $2 to pole $3"
"$0" "`expr $1 - 1`" "$4" "$3" "$2"
fi
</syntaxhighlight>
Output from any of the above:
{{Out}}
<pre>$ hanoi 4 1 3 2
Move disk from pole 1 to pole 2
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 3
Move disk from pole 1 to pole 2
Move disk from pole 3 to pole 1
Move disk from pole 3 to pole 2
Move disk from pole 1 to pole 2
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 3
Move disk from pole 2 to pole 1
Move disk from pole 3 to pole 1
Move disk from pole 2 to pole 3
Move disk from pole 1 to pole 2
Move disk from pole 1 to pole 3
Move disk from pole 2 to pole 3</pre>
=={{header|Ursala}}==
<
move = ~&al^& ^rlPlrrPCT/~&arhthPX ^|W/~& ^|G/predecessor ^/~&htxPC ~&zyxPC
Line 6,487 ⟶ 7,258:
#show+
main = ^|T(~&,' -> '--)* move/4 <'start','end','middle'></
{{out}}
<pre>start -> middle
Line 6,504 ⟶ 7,275:
start -> end
middle -> end</pre>
=={{header|Uxntal}}==
<syntaxhighlight lang="Uxntal">|10 @Console &vector $2 &read $1 &pad $4 &type $1 &write $1 &error $1
|0100 ( -> )
#0102 [ LIT2 03 &count 04 ] hanoi
POP2 POP2 BRK
@hanoi ( from spare to count -: from spare to count )
( moving 0 disks is no-op )
DUP ?{ JMP2r }
( move disks 1..count-1 to the spare peg )
#01 SUB ROT SWP hanoi
( from to spare count-1 )
( print the current move )
;dict/move print-str
INCk #30 ORA .Console/write DEO
STH2
;dict/from print-str
OVR #30 ORA .Console/write DEO
;dict/to print-str
DUP #30 ORA .Console/write DEO
[ LIT2 0a -Console/write ] DEO
STH2r
( move disks 1..count-1 from the spare peg to the goal peg )
STH ROT ROT STHr hanoi
( restore original parameters for convenient recursion )
STH2 SWP STH2r INC
JMP2r
@print-str
&loop
LDAk .Console/write DEO
INC2 LDAk ?&loop
POP2 JMP2r
@dict
&move "Move 20 "disk 2000
&from 20 "from 20 "pole 2000
&to 20 "to 20 "pole 2000</syntaxhighlight>
=={{header|VBScript}}==
Derived from the BASIC256 version.
<
If n > 0 Then
Move n-1, fromPeg, viaPeg, toPeg
Line 6,517 ⟶ 7,333:
Move 4,1,2,3
WScript.StdOut.Write("Towers of Hanoi puzzle completed!")</
{{out}}
Line 6,539 ⟶ 7,355:
=={{header|Vedit macro language}}==
This implementation outputs the results in current edit buffer.
<
Call("MOVE_DISKS")
Return
Line 6,563 ⟶ 7,379:
Num_Pop(1,4)
}
Return</
=={{header|Vim Script}}==
<
if (a:n > 1)
call TowersOfHanoi(a:n-1, a:from, a:via, a:to)
Line 6,576 ⟶ 7,392:
endfunction
call TowersOfHanoi(4, 1, 3, 2)</
{{Out}}
Line 6,596 ⟶ 7,412:
=={{header|Visual Basic .NET}}==
<
Sub MoveTowerDisks(ByVal disks As Integer, ByVal fromTower As Integer, ByVal toTower As Integer, ByVal viaTower As Integer)
If disks > 0 Then
Line 6,608 ⟶ 7,424:
MoveTowerDisks(4, 1, 2, 3)
End Sub
End Module</
=={{header|V (Vlang)}}==
<syntaxhighlight lang="Zig">
fn main() {
hanoi(4, "A", "B", "C")
}
fn hanoi(n u64, a string, b string, c string) {
if n > 0 {
hanoi(n - 1, a, c, b)
println("Move disk from ${a} to ${c}")
hanoi(n - 1, b, a, c)
}
}
</syntaxhighlight>
{{out}}
<pre>
Move disk from A to B
Move disk from A to C
Move disk from B to C
Move disk from A to B
Move disk from C to A
Move disk from C to B
Move disk from A to B
Move disk from A to C
Move disk from B to C
Move disk from B to A
Move disk from C to A
Move disk from B to C
Move disk from A to B
Move disk from A to C
Move disk from B to C
</pre>
=={{header|VTL-2}}==
VTL-2 doesn't have procedure parameters, so this stacks and unstacks the return line number and parameters as reuired. The "move" routune starts at line 2000, the routine at 4000 stacks the return line number and parameters for "move" and the routine at 5000 unstacks the return line number and parameters.
<
1010 F=1
1020 T=2
Line 6,662 ⟶ 7,512:
5080 R=:S)
5090 S=S-1
5100 #=!</
{{out}}
<pre>
Line 6,684 ⟶ 7,534:
=={{header|Wren}}==
{{trans|Kotlin}}
<
construct new(disks) {
_moves = 0
Line 6,703 ⟶ 7,553:
Hanoi.new(3)
Hanoi.new(4)</
{{out}}
Line 6,739 ⟶ 7,589:
Completed in 15 moves
</pre>
=={{header|XBasic}}==
{{works with|Windows XBasic}}
<syntaxhighlight lang="qbasic">PROGRAM "Hanoi"
VERSION "0.0000"
DECLARE FUNCTION Entry ()
DECLARE FUNCTION Hanoi(n, desde , hasta, via)
FUNCTION Entry ()
PRINT "Three disks\n"
Hanoi (3, 1, 2, 3)
PRINT "\nFour discks\n"
Hanoi (4, 1, 2, 3)
PRINT "\nTowers of Hanoi puzzle completed!"
END FUNCTION
FUNCTION Hanoi (n, desde , hasta, via)
IF n > 0 THEN
Hanoi (n - 1, desde, via, hasta)
PRINT "Move disk"; n; " from pole"; desde; " to pole"; hasta
Hanoi (n - 1, via, hasta, desde)
END IF
END FUNCTION
END PROGRAM</syntaxhighlight>
{{out}}
<pre>Same as FreeBASIC entry.</pre>
=={{header|XPL0}}==
<
proc MoveTower(Discs, From, To, Using);
Line 6,753 ⟶ 7,630:
];
MoveTower(3, "left", "right", "center")</
{{out}}
Line 6,767 ⟶ 7,644:
=={{header|XQuery}}==
<
$to as xs:integer, $via as xs:integer) as element()*
{
Line 6,783 ⟶ 7,660:
local:hanoi(4, 1, 2, 3)
}
</hanoi></
{{out}}
<
<hanoi>
<move disk="1">
Line 6,847 ⟶ 7,724:
<to>2</to>
</move>
</hanoi></
=={{header|XSLT}}==
<
<xsl:param name="n"/>
<xsl:param name="from">left</xsl:param>
Line 6,875 ⟶ 7,752:
</xsl:call-template>
</xsl:if>
</xsl:template></
<xsl:call-template name="hanoi"><xsl:with-param name="n" select="4"/></xsl:call-template>
=={{header|Yabasic}}==
<
if ndisks then
hanoi(ndisks-1, startPeg, 6-startPeg-endPeg)
Line 6,909 ⟶ 7,786:
print "Hanoi 2 ellapsed ... ";
hanoi2(22, 1, 3, 2)
print peek("millisrunning") - t2, " ms"</
=={{header|Z80 Assembly}}==
{{works with|CP/M 3.1|YAZE-AG-2.51.2 Z80 emulator}}
{{works with|ZSM4 macro assembler|YAZE-AG-2.51.2 Z80 emulator}}
Use the /S8 switch on the ZSM4 assembler for 8 significant characters for labels and names<br><br>
<syntaxhighlight lang="z80">
;
; Towers of Hanoi using Z80 assembly language
;
; Runs under CP/M 3.1 on YAZE-AG-2.51.2 Z80 emulator
; Assembled with zsm4 on same emulator/OS, uses macro capabilities of said assembler
; Created with vim under Windows
;
; 2023-05-29 Xorph
;
;
; Useful definitions
;
bdos equ 05h ; Call to CP/M BDOS function
strdel equ 6eh ; Set string delimiter
wrtstr equ 09h ; Write string to console
nul equ 00h ; ASCII control characters
cr equ 0dh
lf equ 0ah
cnull equ '0' ; ASCII character constants
ca equ 'A'
cb equ 'B'
cc equ 'C'
disks equ 4 ; Number of disks to move
;
; Macros for BDOS calls
;
setdel macro char ; Set string delimiter to char
ld c,strdel
ld e,char
call bdos
endm
print macro msg ; Output string to console
ld c,wrtstr
ld de,msg
call bdos
endm
pushall macro ; Save required registers to stack
push af
push bc
push de
endm
popall macro ; Recall required registers from stack
pop de
pop bc
pop af
endm
;
; =====================
; Start of main program
; =====================
;
cseg
setdel nul ; Set string delimiter to 00h
ld a,disks ; Initialization:
ld b,ca ; Tower A is source
ld c,cb ; Tower B is target
ld d,cc ; Tower C is intermediate
hanoi:
;
; Parameters in registers:
; Move a disks from b (source) to c (target) via d (intermediate)
;
or a ; If 0 disks to move, return
ret z
dec a ; Move all but lowest disk from source to intermediate via target
pushall ; Save registers
ld e,c ; Exchange c and d (target and intermediate)
ld c,d
ld d,e
call hanoi ; First recursion
popall ; Restore registers
ld hl,source ; Print move of lowest disk from source to target, save registers during BDOS call
ld (hl),b ; Source is still in b
ld hl,target
ld (hl),c ; Target is back in c due to popall
pushall
print movement
popall
ld e,b ; Now move stack from intermediate to target via source
ld b,d ; Source is still in b, target in c and intermediate in d
ld d,e
jr hanoi ; Optimize tail recursion
;
; ================
; Data definitions
; ================
;
dseg
movement:
defb 'Move disk from tower '
source:
defs 1
defb ' to tower '
target:
defs 1
crlf:
defb cr,lf,nul
</syntaxhighlight>
{{out}}
<pre>
E>hanoi
Move disk from tower A to tower C
Move disk from tower A to tower B
Move disk from tower C to tower B
Move disk from tower A to tower C
Move disk from tower B to tower A
Move disk from tower B to tower C
Move disk from tower A to tower C
Move disk from tower A to tower B
Move disk from tower C to tower B
Move disk from tower C to tower A
Move disk from tower B to tower A
Move disk from tower C to tower B
Move disk from tower A to tower C
Move disk from tower A to tower B
Move disk from tower C to tower B
E>
</pre>
=={{header|Zig}}==
{{trans|C}}
<
pub fn print(from: u32, to: u32) void {
Line 6,933 ⟶ 7,960:
}
</syntaxhighlight>
=={{header|zkl}}==
{{trans|C}}
<
if (n>0){
move(n-1, from,via,to);
Line 6,944 ⟶ 7,971:
}
}
move(3, 1,2,3);</
{{out}}
<pre>
|