I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

# Towers of Hanoi

Towers of Hanoi
You are encouraged to solve this task according to the task description, using any language you may know.

Solve the   Towers of Hanoi   problem with recursion.

## 360 Assembly

Translation of: PL/I
*        Towers of Hanoi           08/09/2015HANOITOW CSECT         USING  HANOITOW,R12       r12 : base register         LR     R12,R15            establish base register         ST     R14,SAVE14         save r14BEGIN    LH     R2,=H'4'           n <===         L      R3,=C'123 '        stating position         BAL    R14,MOVE           r1=move(m,n)RETURN   L      R14,SAVE14         restore r14         BR     R14                return to callerSAVE14   DS     F                  static save r14PG       DC     CL44'xxxxxxxxxxxx Move disc from pole X to pole Y' NN       DC     F'0'POLEX    DS     F                  current polesPOLEN    DS     F                  new poles*        ....   recursive          subroutine move(n, poles)  [r2,r3]MOVE     LR     R10,R11            save stackptr (r11) in r10 temp         LA     R1,STACKLEN        amount of storage required         GETMAIN RU,LV=(R1)        allocate storage for stack         USING  STACKDS,R11        make storage addressable         LR     R11,R1             establish stack addressability         ST     R14,SAVE14M        save previous r14         ST     R10,SAVE11M        save previous r11         LR     R1,R5              restore saved argument r5BEGINM   STM    R2,R3,STACK        push arguments to stack         ST     R3,POLEX         CH     R2,=H'1'           if n<>1         BNE    RECURSE            then goto recurse         L      R1,NN         LA     R1,1(R1)           nn=nn+1         ST     R1,NN         XDECO  R1,PG              nn         MVC    PG+33(1),POLEX+0   from         MVC    PG+43(1),POLEX+1   to         XPRNT  PG,44              print "move disk from to"         B      RETURNMRECURSE  L      R2,N               n         BCTR   R2,0               n=n-1         MVC    POLEN+0(1),POLES+0 from         MVC    POLEN+1(1),POLES+2 via         MVC    POLEN+2(1),POLES+1 to         L      R3,POLEN           new poles         BAL    R14,MOVE           call move(n-1,from,via,to)         LA     R2,1               n=1         MVC    POLEN,POLES          L      R3,POLEN           new poles         BAL    R14,MOVE           call move(1,from,to,via)         L      R2,N               n         BCTR   R2,0               n=n-1         MVC    POLEN+0(1),POLES+2 via         MVC    POLEN+1(1),POLES+1 to         MVC    POLEN+2(1),POLES+0 from         L      R3,POLEN           new poles         BAL    R14,MOVE           call move(n-1,via,to,from)RETURNM  LM     R2,R3,STACK        pull arguments from stack         LR     R1,R11             current stack         L      R14,SAVE14M        restore r14         L      R11,SAVE11M        restore r11         LA     R0,STACKLEN        amount of storage to free         FREEMAIN A=(R1),LV=(R0)   free allocated storage         BR     R14                return to caller         LTORG         DROP   R12                base no longer neededSTACKDS  DSECT                     dynamic areaSAVE14M  DS     F                  saved r14SAVE11M  DS     F                  saved r11STACK    DS     0F                 stackN        DS     F                  r2 nPOLES    DS     F                  r3 polesSTACKLEN EQU    *-STACKDS         YREGS           END    HANOITOW
Output:
           1 Move disc from pole 1 to pole 3
2 Move disc from pole 1 to pole 2
3 Move disc from pole 3 to pole 2
4 Move disc from pole 1 to pole 3
5 Move disc from pole 2 to pole 1
6 Move disc from pole 2 to pole 3
7 Move disc from pole 1 to pole 3
8 Move disc from pole 1 to pole 2
9 Move disc from pole 3 to pole 2
10 Move disc from pole 3 to pole 1
11 Move disc from pole 2 to pole 1
12 Move disc from pole 3 to pole 2
13 Move disc from pole 1 to pole 3
14 Move disc from pole 1 to pole 2
15 Move disc from pole 3 to pole 2


## 8th

 5 var, disksvar savar sbvar sc : save sc ! sb ! sa ! disks ! ;: get sa @ sb @ sc @ ;: get2 get swap ;: hanoi	save disks @ not if ;; then	disks @ get	disks @ n:1- get2 hanoi save	cr 	" move a ring from " .  sa @ . " to " . sb @ .	disks @ n:1- get2 rot hanoi; " Tower of Hanoi, with " . disks @ . " rings: " . disks @ 1 2 3 hanoi cr bye

## ActionScript

public function move(n:int, from:int, to:int, via:int):void{    if (n > 0)    {        move(n - 1, from, via, to);        trace("Move disk from pole " + from + " to pole " + to);        move(n - 1, via, to, from);    }}

with Ada.Text_Io; use Ada.Text_Io; procedure Towers is   type Pegs is (Left, Center, Right);   procedure Hanoi (Ndisks : Natural; Start_Peg : Pegs := Left; End_Peg : Pegs := Right; Via_Peg : Pegs := Center) is   begin      if Ndisks > 0 then         Hanoi(Ndisks - 1, Start_Peg, Via_Peg, End_Peg);         Put_Line("Move disk" & Natural'Image(Ndisks) & " from " & Pegs'Image(Start_Peg) & " to " & Pegs'Image(End_Peg));         Hanoi(Ndisks - 1, Via_Peg, End_Peg, Start_Peg);      end if;   end Hanoi;begin   Hanoi(4);end Towers;

## Agena

move := proc(n::number, src::number, dst::number, via::number) is   if n > 0 then      move(n - 1, src, via, dst)      print(src & ' to ' & dst)      move(n - 1, via, dst, src)   fiend move(4, 1, 2, 3)

## ALGOL 68

PROC move = (INT n, from, to, via) VOID:  IF n > 0 THEN    move(n - 1, from, via, to);    printf(($"Move disk from pole "g" to pole "gl$, from, to));    move(n - 1, via, to, from)  FI; 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    move(n - 1, from, via, to);    printf(($"Move disk "g" from pole "g" to pole "gl$, n,  from, to));    move(n - 1, via, to, from)  FI ;main: (  move(4, 1,2,3))

## ALGOL W

Following Agena, Algol 68, AmigaE...

begin    procedure move ( integer value n, from, to, via ) ;        if n > 0 then begin            move( n - 1, from, via, to );            write( i_w := 1, s_w := 0, "Move disk from peg: ", from, " to peg: ", to );            move( n - 1, via, to, from )        end move ;     move( 4, 1, 2, 3 )end.

## AmigaE

PROC move(n, from, to, via)  IF n > 0    move(n-1, from, via, to)    WriteF('Move disk from pole \d to pole \d\n', from, to)    move(n-1, via, to, from)  ENDIFENDPROC PROC main()  move(4, 1,2,3)ENDPROC

## AppleScript

-- hanoi :: Int -> (String, String, String) -> [(String, String)]on hanoi(n, abc)    script go        on |λ|(n, {x, y, z})            if n > 0 then                |λ|(n - 1, {x, z, y}) & ¬                    {{x, y}} & |λ|(n - 1, {z, y, x})            else                {}            end if        end |λ|    end script    go's |λ|(n, abc)end hanoi -- TEST ---------------------------------------------------on run    script arrow        on |λ|(abc)            item 1 of abc & " -> " & item 2 of abc        end |λ|    end script     unlines(map(arrow, ¬        hanoi(3, {"left", "right", "mid"})))end run  -- GENERIC FUNCTIONS -------------------------------------- -- Lift 2nd class handler function into 1st class script wrapper -- mReturn :: First-class m => (a -> b) -> m (a -> b)on mReturn(f)    if class of f is script then        f    else        script            property |λ| : f        end script    end ifend mReturn -- map :: (a -> b) -> [a] -> [b]on map(f, xs)    tell mReturn(f)        set lng to length of xs        set lst to {}        repeat with i from 1 to lng            set end of lst to |λ|(item i of xs, i, xs)        end repeat        return lst    end tellend map -- unlines :: [String] -> Stringon unlines(xs)    set {dlm, my text item delimiters} to ¬        {my text item delimiters, linefeed}    set str to xs as text    set my text item delimiters to dlm    strend unlines
Output:
left -> right
left -> mid
right -> mid
left -> right
mid -> left
mid -> right
left -> right

More illustratively:

(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.)

on hanoi(n, source, target)    set t1 to tab & "tower 1: " & tab    set t2 to tab & "tower 2: " & tab    set t3 to tab & "tower 3: " & tab     script o        property m : 0        property tower1 : {}        property tower2 : {}        property tower3 : {}        property towerRefs : {a reference to tower1, a reference to tower2, a reference to tower3}        property process : missing value         on |move|(n, source, target)            set aux to 6 - source - target            repeat with n from n to 2 by -1 -- Tail call elimination repeat.                |move|(n - 1, source, aux)                set end of item target of my towerRefs to n                tell item source of my towerRefs to set its contents to reverse of rest of its reverse                set m to m + 1                set end of my process to ¬                    {(m as text) & ". move disc " & n & (" from tower " & source) & (" to tower " & target & ":"), ¬                        t1 & tower1, ¬                        t2 & tower2, ¬                        t3 & tower3}                tell source                    set source to aux                    set aux to it                end tell            end repeat            -- Specific code for n = 1:            set end of item target of my towerRefs to 1            tell item source of my towerRefs to set its contents to reverse of rest of its reverse            set m to m + 1            set end of my process to ¬                {(m as text) & ". move disc 1 from tower " & source & (" to tower " & target & ":"), ¬                    t1 & tower1, ¬                    t2 & tower2, ¬                    t3 & tower3}        end |move|    end script     repeat with i from n to 1 by -1        set end of item source of o's towerRefs to i    end repeat     set astid to AppleScript's text item delimiters    set AppleScript's text item delimiters to ", "    set o's process to {"Starting with " & n & (" discs on tower " & (source & ":")), ¬        t1 & o's tower1, t2 & o's tower2, t3 & o's tower3}    if (n > 0) then tell o to |move|(n, source, target)    set end of o's process to "That's it!"    set AppleScript's text item delimiters to linefeed    set process to o's process as text    set AppleScript's text item delimiters to astid     return processend hanoi -- Test:set numberOfDiscs to 3set sourceTower to 1set destinationTower to 2hanoi(numberOfDiscs, sourceTower, destinationTower)
Output:
"Starting with 3 discs on tower 1:
tower 1:     3, 2, 1
tower 2:
tower 3:
1. move disc 1 from tower 1 to tower 2:
tower 1:     3, 2
tower 2:     1
tower 3:
2. move disc 2 from tower 1 to tower 3:
tower 1:     3
tower 2:     1
tower 3:     2
3. move disc 1 from tower 2 to tower 3:
tower 1:     3
tower 2:
tower 3:     2, 1
4. move disc 3 from tower 1 to tower 2:
tower 1:
tower 2:     3
tower 3:     2, 1
5. move disc 1 from tower 3 to tower 1:
tower 1:     1
tower 2:     3
tower 3:     2
6. move disc 2 from tower 3 to tower 2:
tower 1:     1
tower 2:     3, 2
tower 3:
7. move disc 1 from tower 1 to tower 2:
tower 1:
tower 2:     3, 2, 1
tower 3:
That's it!"

## Arturo

Translation of: D
hanoi: @(n from to via){	if n>0 {		hanoi n-1 from via to		print "Move disk " + n + " from " + from + " to " + to		hanoi n-1 via to from	}} hanoi 3 "L" "M" "R"
Output:
Move disk 1 from L to M
Move disk 2 from L to R
Move disk 1 from M to R
Move disk 3 from L to M
Move disk 1 from R to L
Move disk 2 from R to M
Move disk 1 from L to M

## AutoHotkey

move(n, from, to, via)  ;n = # of disks, from = start pole, to = end pole, via = remaining pole {  if (n = 1)  {    msgbox , Move disk from pole %from% to pole %to%   }  else  {    move(n-1, from, via, to)    move(1, from, to, via)    move(n-1, via, to, from)  }}move(64, 1, 3, 2)

## AutoIt

Func move($n,$from, $to,$via)	If ($n = 1) Then ConsoleWrite(StringFormat("Move disk from pole "&$from&" To pole "&$to&"\n")) Else move($n - 1, $from,$via, $to) move(1,$from, $to,$via)		move($n - 1,$via, $to,$from)	EndIfEndFunc move(4, 1,2,3)

## AWK

Translation of: Logo

## Befunge

This is loosely based on the Python sample. The number of disks is specified by the first integer on the stack (the initial character 4 in the example below). If you want the program to prompt the user for that value, you can replace the 4 with a & (the read integer command).

48*2+1>#v_:!#@_0" ksid evoM">:#,_$:8/:.v>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<
Output:
Move disk 1 from peg 1 to peg 2
Move disk 2 from peg 1 to peg 3
Move disk 1 from peg 2 to peg 3
Move disk 3 from peg 1 to peg 2
Move disk 1 from peg 3 to peg 1
Move disk 2 from peg 3 to peg 2
Move disk 1 from peg 1 to peg 2
Move disk 4 from peg 1 to peg 3
Move disk 1 from peg 2 to peg 3
Move disk 2 from peg 2 to peg 1
Move disk 1 from peg 3 to peg 1
Move disk 3 from peg 2 to peg 3
Move disk 1 from peg 1 to peg 2
Move disk 2 from peg 1 to peg 3
Move disk 1 from peg 2 to peg 3

## Bracmat

( ( move  =   n from to via    .   !arg:(?n,?from,?to,?via)      & (   !n:>0          & move$(!n+-1,!from,!via,!to) & out$("Move disk from pole " !from " to pole " !to)          & move$(!n+-1,!via,!to,!from) | ) )& move$(4,1,2,3));
Output:
Move disk from pole  1  to pole  3
Move disk from pole  1  to pole  2
Move disk from pole  3  to pole  2
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  3
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  1
Move disk from pole  3  to pole  2
Move disk from pole  1  to pole  3
Move disk from pole  1  to pole  2
Move disk from pole  3  to pole  2

## Brainf***

[This implementation is recursive and usesa stack, consisting of frames that are 8bytes long. The layout is as follows: Byte   Description   0   recursion flag       (the program stops if the flag is        zero)   1   the step which is currently       executed       4 means a call to               move(a, c, b, n - 1)       3 means a call to               move(a, b, c, 1)       2 means a call to               move(b, a, c, n - 1)       1 prints the source and dest pile   2   flag to check whether the current       step has already been done or if       it still must be executed   3   the step which will be executed       in the next loop   4   the source pile   5   the helper pile   6   the destination pile   7   the number of disks to move The first stack frame (0 0 0 0 0 0 0 0)is used to abort the recursion.] >>>>>>>> These are the parameters for the program(1 4 1 0 'a 'b 'c 5)+>++++>+>>>>>>++++++++[<++++++++++++>-]<[<<<+>+>+>-]<<<+>++>+++>+++++><<<<<<<< [> while (recurse)  [- if (step gt 0)    >[-]+< todo = 1    [- if (step gt 1)      [- if (step gt 2)        [- if (step gt 3)          >>+++<< next = 3          >-< todo = 0          >>>>>>[>+>+<<-]>[<+>-]> n dup          -          [[-] if (sub(n 1) gt 0)            <+>>>++++> push (1 0 0 4)             copy and push a            <<<<<<<<[>>>>>>>>+>+            <<<<<<<<<-]>>>>>>>>            >[<<<<<<<<<+>>>>>>>>>-]< >             copy and push c            <<<<<<<[>>>>>>>+>+            <<<<<<<<-]>>>>>>>            >[<<<<<<<<+>>>>>>>>-]< >             copy and push b            <<<<<<<<<[>>>>>>>>>+>+            <<<<<<<<<<-]>>>>>>>>>            >[<<<<<<<<<<+>>>>>>>>>>-]< >             copy n and push sub(n 1)            <<<<<<<<[>>>>>>>>+>+            <<<<<<<<<-]>>>>>>>>            >[<<<<<<<<<+>>>>>>>>>-]< -            >>          ]          <<<<<<<<        ]        >[-< if ((step gt 2) and todo)          >>++<< next = 2          >>>>>>>          +>>>+> push 1 0 0 1 a b c 1          <<<<<<<<[>>>>>>>>+>+          <<<<<<<<<-]>>>>>>>>          >[<<<<<<<<<+>>>>>>>>>-]< > a          <<<<<<<<[>>>>>>>>+>+          <<<<<<<<<-]>>>>>>>>          >[<<<<<<<<<+>>>>>>>>>-]< > b          <<<<<<<<[>>>>>>>>+>+          <<<<<<<<<-]>>>>>>>>          >[<<<<<<<<<+>>>>>>>>>-]< > c          + >>        >]<      ]      >[-< if ((step gt 1) and todo)        >>>>>>[>+>+<<-]>[<+>-]> n dup        -        [[-] if (n sub 1 gt 0)          <+>>>++++> push (1 0 0 4)           copy and push b          <<<<<<<[>>>>>>>+          <<<<<<<-]>>>>>>>          >[<<<<<<<<+>>>>>>>>-]< >           copy and push a          <<<<<<<<<[>>>>>>>>>+          <<<<<<<<<-]>>>>>>>>>          >[<<<<<<<<<<+>>>>>>>>>>-]< >           copy and push c          <<<<<<<<[>>>>>>>>+          <<<<<<<<-]>>>>>>>>          >[<<<<<<<<<+>>>>>>>>>-]< >           copy n and push sub(n 1)          <<<<<<<<[>>>>>>>>+>+          <<<<<<<<<-]>>>>>>>>          >[<<<<<<<<<+>>>>>>>>>-]< -          >>        ]        <<<<<<<<      >]<    ]    >[-< if ((step gt 0) and todo)      >>>>>>>      >++++[<++++++++>-]<      >>++++++++[<+++++++++>-]<++++      >>++++++++[<++++++++++++>-]<+++++      >>+++++++++[<++++++++++++>-]<+++      <<<      >.+++++++>.++.--.<<.      >>-.+++++.----.<<.      >>>.<---.+++.>+++.+.+.<.<<.      >.>--.+++++.---.++++.        -------.+++.<<.      >>>++.-------.-.<<<.      >+.>>+++++++.---.-----.<<<.      <<<<.>>>>.      >>----.>++++++++.<+++++.<<.      >.>>.---.-----.<<<.      <<.>>++++++++++++++.      >>>[-]<[-]<[-]<[-]      +++++++++++++.---.[-]      <<<<<<<    >]<    >>[<<+>>-]<< step = next  ]  return with clear stack frame  <[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<  <<<<<<<<  >>[<<+>>-]<< step = next  <]

## C

#include <stdio.h> void move(int n, int from, int via, int to){  if (n > 1) {    move(n - 1, from, to, via);    printf("Move disk from pole %d to pole %d\n", from, to);    move(n - 1, via, from, to);  } else {    printf("Move disk from pole %d to pole %d\n", from, to);  }}int main(){  move(4, 1,2,3);  return 0;}
Animate it for fun:
#include <stdio.h>#include <stdlib.h>#include <unistd.h> typedef struct { int *x, n; } tower;tower *new_tower(int cap){	tower *t = calloc(1, sizeof(tower) + sizeof(int) * cap);	t->x = (int*)(t + 1);	return t;} tower *t;int height; void text(int y, int i, int d, const char *s){	printf("\033[%d;%dH", height - y + 1, (height + 1) * (2 * i + 1) - d);	while (d--) printf("%s", s);} void add_disk(int i, int d){	t[i]->x[t[i]->n++] = d;	text(t[i]->n, i, d, "=="); 	usleep(100000);	fflush(stdout);} int remove_disk(int i){	int d = t[i]->x[--t[i]->n];	text(t[i]->n + 1, i, d, "  ");	return d;} void move(int n, int from, int to, int via){	if (!n) return; 	move(n - 1, from, via, to);	add_disk(to, remove_disk(from));	move(n - 1, via, to, from);} int main(int c, char *v[]){	puts("\033[H\033[J"); 	if (c <= 1 || (height = atoi(v)) <= 0)		height = 8;	for (c = 0; c < 3; c++)	 t[c] = new_tower(height);	for (c = height; c; c--) add_disk(0, c); 	move(height, 0, 2, 1); 	text(1, 0, 1, "\n");	return 0;}

## C#

public  void move(int n, int from, int to, int via) {   if (n == 1) {     System.Console.WriteLine("Move disk from pole " + from + " to pole " + to);   } else {     move(n - 1, from, via, to);     move(1, from, to, via);     move(n - 1, via, to, from);   } }

## C++

Works with: g++
void move(int n, int from, int to, int via) {  if (n == 1) {    std::cout << "Move disk from pole " << from << " to pole " << to << std::endl;  } else {    move(n - 1, from, via, to);    move(1, from, to, via);    move(n - 1, via, to, from);  }}

## Clojure

### Side-Effecting Solution

(defn towers-of-hanoi [n from to via]  (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

(defn towers-of-hanoi [n from to via]  (when (pos? n)    (lazy-cat (towers-of-hanoi (dec n) from via to)              (cons [from '-> to]                    (towers-of-hanoi (dec n) via to from)))))

## COBOL

Translation of: C
Works with: OpenCOBOL version 2.0
       >>SOURCE FREEIDENTIFICATION DIVISION.PROGRAM-ID. towers-of-hanoi. PROCEDURE DIVISION.    CALL "move-disk" USING 4, 1, 2, 3    .END PROGRAM towers-of-hanoi. IDENTIFICATION DIVISION.PROGRAM-ID. move-disk RECURSIVE. DATA DIVISION.LINKAGE SECTION.01  n                         PIC 9 USAGE COMP.01  from-pole                 PIC 9 USAGE COMP.01  to-pole                   PIC 9 USAGE COMP.01  via-pole                  PIC 9 USAGE COMP. PROCEDURE DIVISION USING n, from-pole, to-pole, via-pole.    IF n > 0       SUBTRACT 1 FROM n       CALL "move-disk" USING CONTENT n, from-pole, via-pole, to-pole       DISPLAY "Move disk from pole " from-pole " to pole " to-pole       CALL "move-disk" USING CONTENT n, via-pole, to-pole, from-pole    END-IF    .END PROGRAM move-disk.
 IDENTIFICATION DIVISION.PROGRAM-ID. towers-of-hanoi. PROCEDURE DIVISION.    CALL "move-disk" USING 4, 1, 2, 3    .END PROGRAM towers-of-hanoi. IDENTIFICATION DIVISION.PROGRAM-ID. move-disk RECURSIVE. DATA DIVISION.LINKAGE SECTION.01  n                         PIC 9 USAGE COMP.01  from-pole                 PIC 9 USAGE COMP.01  to-pole                   PIC 9 USAGE COMP.01  via-pole                  PIC 9 USAGE COMP. PROCEDURE DIVISION USING n, from-pole, to-pole, via-pole.    IF n > 0       SUBTRACT 1 FROM n       CALL "move-disk" USING CONTENT n, from-pole, via-pole, to-pole       ADD 1 TO n       DISPLAY "Move disk number "n " from pole " from-pole " to pole " to-pole       SUBTRACT 1 FROM n       CALL "move-disk" USING CONTENT n, via-pole, to-pole, from-pole    END-IF    .END PROGRAM move-disk.

### ANSI-74 solution

Early versions of COBOL did not have recursion. There are no locally-scoped variables and the call of a procedure does not have to use a stack to save return state. Recursion would cause undefined results. It is therefore necessary to use an iterative algorithm. This solution is an adaptation of Kolar's Hanoi Tower algorithm no. 1.

Works with: CIS COBOL version 4.2
Works with: GnuCOBOL version 3.0-rc1.0
       IDENTIFICATION DIVISION.       PROGRAM-ID. ITERATIVE-TOWERS-OF-HANOI.       AUTHOR. SOREN ROUG.       DATE-WRITTEN. 2019-06-28.       ENVIRONMENT DIVISION.       CONFIGURATION SECTION.       SOURCE-COMPUTER. LINUX.       OBJECT-COMPUTER. KAYPRO4.       INPUT-OUTPUT SECTION.       FILE-CONTROL.       DATA DIVISION.       WORKING-STORAGE SECTION.       77  NUM-DISKS                   PIC 9 VALUE 4.       77  N1                          PIC 9 COMP.       77  N2                          PIC 9 COMP.       77  FROM-POLE                   PIC 9 COMP.       77  TO-POLE                     PIC 9 COMP.       77  VIA-POLE                    PIC 9 COMP.       77  FP-TMP                      PIC 9 COMP.       77  TO-TMP                      PIC 9 COMP.       77  P-TMP                       PIC 9 COMP.       77  TMP-P                       PIC 9 COMP.       77  I                           PIC 9 COMP.       77  DIV                         PIC 9 COMP.       01  STACKNUMS.           05  NUMSET OCCURS 3 TIMES.               10  DNUM                PIC 9 COMP.       01  GAMESET.           05  POLES OCCURS 3 TIMES.               10  STACK OCCURS 10 TIMES.                   15  POLE            PIC 9 USAGE COMP.        PROCEDURE DIVISION.       HANOI.           DISPLAY "TOWERS OF HANOI PUZZLE WITH ", NUM-DISKS, " DISKS.".           ADD NUM-DISKS, 1 GIVING N1.           ADD NUM-DISKS, 2 GIVING N2.           MOVE 1 TO DNUM (1).           MOVE N1 TO DNUM (2), DNUM (3).           MOVE N1 TO POLE (1, N1), POLE (2, N1), POLE (3, N1).           MOVE 1 TO POLE (1, N2).           MOVE 2 TO POLE (2, N2).           MOVE 3 TO POLE (3, N2).           MOVE 1 TO I.           PERFORM INIT-PUZZLE UNTIL I = N1.           MOVE 1 TO FROM-POLE.           DIVIDE 2 INTO NUM-DISKS GIVING DIV.           MULTIPLY 2 BY DIV.           IF DIV NOT = NUM-DISKS PERFORM INITODD ELSE PERFORM INITEVEN.           PERFORM MOVE-DISK UNTIL DNUM (3) NOT > 1.           DISPLAY "TOWERS OF HANOI PUZZLE COMPLETED!".           STOP RUN.       INIT-PUZZLE.           MOVE I TO POLE (1, I).           MOVE 0 TO POLE (2, I), POLE (3, I).           ADD 1 TO I.       INITEVEN.           MOVE 2 TO TO-POLE.           MOVE 3 TO VIA-POLE.       INITODD.           MOVE 3 TO TO-POLE.           MOVE 2 TO VIA-POLE.       MOVE-DISK.           MOVE DNUM (FROM-POLE) TO FP-TMP.           MOVE POLE (FROM-POLE, FP-TMP) TO I.           DISPLAY "MOVE DISK FROM ", POLE (FROM-POLE, N2),               " TO ", POLE (TO-POLE, N2).           ADD 1 TO DNUM (FROM-POLE).           MOVE VIA-POLE TO TMP-P.           SUBTRACT 1 FROM DNUM (TO-POLE).           MOVE DNUM (TO-POLE) TO TO-TMP.           MOVE I TO POLE (TO-POLE, TO-TMP).           DIVIDE 2 INTO I GIVING DIV.           MULTIPLY 2 BY DIV.           IF I NOT = DIV PERFORM MOVE-TO-VIA ELSE               PERFORM MOVE-FROM-VIA.       MOVE-TO-VIA.           MOVE TO-POLE TO VIA-POLE.           MOVE DNUM (FROM-POLE) TO FP-TMP.           MOVE DNUM (TMP-P) TO P-TMP.           IF POLE (FROM-POLE, FP-TMP) > POLE (TMP-P, P-TMP)               PERFORM MOVE-FROM-TO           ELSE MOVE TMP-P TO TO-POLE.       MOVE-FROM-TO.           MOVE FROM-POLE TO TO-POLE.           MOVE TMP-P TO FROM-POLE.           MOVE DNUM (FROM-POLE) TO FP-TMP.           MOVE DNUM (TMP-P) TO P-TMP.       MOVE-FROM-VIA.           MOVE FROM-POLE TO VIA-POLE.           MOVE TMP-P TO FROM-POLE.

## CoffeeScript

hanoi = (ndisks, start_peg=1, end_peg=3) ->  if ndisks    staging_peg = 1 + 2 + 3 - start_peg - end_peg    hanoi(ndisks-1, start_peg, staging_peg)    console.log "Move disk #{ndisks} from peg #{start_peg} to #{end_peg}"    hanoi(ndisks-1, staging_peg, end_peg) hanoi(4)

## Common Lisp

(defun move (n from to via)  (cond ((= n 1)         (format t "Move from ~A to ~A.~%" from to))        (t         (move (- n 1) from via to)         (format t "Move from ~A to ~A.~%" from to)         (move (- n 1) via to from))))

## D

### Recursive Version

import std.stdio; void hanoi(in int n, in char from, in char to, in char via) {    if (n > 0) {        hanoi(n - 1, from, via, to);        writefln("Move disk %d from %s to %s", n, from, to);        hanoi(n - 1, via, to, from);    }} void main() {    hanoi(3, 'L', 'M', 'R');}
Output:
Move disk 1 from L to M
Move disk 2 from L to R
Move disk 1 from M to R
Move disk 3 from L to M
Move disk 1 from R to L
Move disk 2 from R to M
Move disk 1 from L to M

### Fast Iterative Version

// Code found and then improved by Glenn C. Rhoads,// then some more by M. Kolar (2000).void main(in string[] args) {    import core.stdc.stdio, std.conv, std.typetuple;     immutable size_t n = (args.length > 1) ? args.to!size_t : 3;    size_t p = [(1 << n) - 1, 0, 0];     // Show the start configuration of the pegs.    '|'.putchar;    foreach_reverse (immutable i; 1 .. n + 1)        printf(" %d", i);    "\n|\n|".puts;     foreach (immutable size_t x; 1 .. (1 << n)) {        {            immutable size_t i1 = x & (x - 1);            immutable size_t fr = (i1 + i1 / 3) & 3;            immutable size_t i2 = (x | (x - 1)) + 1;            immutable size_t to = (i2 + i2 / 3) & 3;             size_t j = 1;            for (size_t w = x; !(w & 1); w >>= 1, j <<= 1) {}             // Now j is not the number of the disk to move,            // it contains the single bit to be moved:            p[fr] &= ~j;            p[to] |= j;        }         // Show the current configuration of pegs.        foreach (immutable size_t k; TypeTuple!(0, 1, 2)) {            "\n|".printf;            size_t j = 1 << n;            foreach_reverse (immutable size_t w; 1 .. n + 1) {                j >>= 1;                if (j & p[k])                    printf(" %zd", w);            }        }        '\n'.putchar;    }}
Output:
| 3 2 1
|
|

| 3 2
|
| 1

| 3
| 2
| 1

| 3
| 2 1
|

|
| 2 1
| 3

| 1
| 2
| 3

| 1
|
| 3 2

|
|
| 3 2 1


## Dart

main() {   moveit(from,to) {    print("move ${from} --->${to}");  }   hanoi(height,toPole,fromPole,usePole) {    if (height>0) {      hanoi(height-1,usePole,fromPole,toPole);        moveit(fromPole,toPole);      hanoi(height-1,toPole,usePole,fromPole);    }  }   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/

main() {  String say(String from, String to) => "$from --->$to";    hanoi(int height, int toPole, int fromPole, int usePole) {    if (height > 0) {      hanoi(height - 1, usePole, fromPole, toPole);        print(say(fromPole.toString(), toPole.toString()));      hanoi(height - 1, toPole, usePole, fromPole);    }  }   hanoi(3, 3, 1, 2);}
Output:
move 1 ---> 3
move 1 ---> 2
move 3 ---> 2
move 1 ---> 3
move 2 ---> 1
move 2 ---> 3
move 1 ---> 3


## Dc

From Here

 [ # move(from, to)
n           # print from
[ --> ]n    # print " --> "
p           # print to\n
sw          # p doesn't pop, so get rid of the value
]sm

[ # init(n)
sw          # tuck n away temporarily
9           # sentinel as bottom of stack
lw          # bring n back
1           # "from" tower's label
3           # "to" tower's label
0           # processed marker
]si

[ # Move()
lt          # push to
lf          # push from
lmx         # call move(from, to)
]sM

[ # code block <d>
ln          # push n
lf          # push from
lt          # push to
1           # push processed marker 1
ln          # push n
1           # push 1
-           # n - 1
lf          # push from
ll          # push left
0           # push processed marker 0
]sd

[ # code block <e>
ln          # push n
1           # push 1
-           # n - 1
ll          # push left
lt          # push to
0           # push processed marker 0
]se

[ # code block <x>
ln 1 =M
ln 1 !=d
]sx

[ # code block <y>
lMx
lex
]sy

[ # quit()
q           # exit the program
]sq

[ # run()
d 9 =q      # if stack empty, quit()
sp          # processed
st          # to
sf          # from
sn          # n
6           #
lf          #
-           #
lt          #
-           # 6 - from - to
sl          #
lp 0 =x     #
lp 0 !=y    #
lrx         # loop
]sr

5lix # init(n)
lrx # run()


## Dyalect

Translation of: Swift
func hanoi(n, a, b, c) {    if n > 0 {        hanoi(n - 1, a, c, b)        print("Move disk from \(a) to \(c)")        hanoi(n - 1, b, a, c)    }} hanoi(4, "A", "B", "C")
Output:
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

## Elena

ELENA 4.x :

move = (n,from,to,via){    if (n == 1)    {        console.printLine("Move disk from pole ",from," to pole ",to)    }    else    {        move(n-1,from,via,to);        move(1,from,to,via);        move(n-1,via,to,from)    }};

## Elixir

defmodule RC do  def hanoi(n) when 0<n and n<10, do: hanoi(n, 1, 2, 3)   defp hanoi(1, f, _, t), do: move(f, t)  defp hanoi(n, f, u, t) do    hanoi(n-1, f, t, u)    move(f, t)    hanoi(n-1, u, f, t)  end   defp move(f, t), do: IO.puts "Move disk from #{f} to #{t}"end RC.hanoi(3)
Output:
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


## Emacs Lisp

Translation of: Common Lisp
 (defun move (n from to via)  (cond ((= n 1)         (print (format "Move from %S to %S" from to)))        (t	 (progn	   (move (- n 1) from via to)	   (print (format "Move from %S to %S" from to))	   (move (- n 1) via to from)))))

## Erlang

move(1, F, T, _V) ->   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).

## ERRE

 !-----------------------------------------------------------! HANOI.R : solve tower of Hanoi puzzle using a recursive ! modified algorithm.!----------------------------------------------------------- PROGRAM HANOI !$INTEGER !VAR I,J,MOSSE,NUMBER PROCEDURE PRINTMOVE LOCAL SOURCE$,DEST$MOSSE=MOSSE+1 CASE I OF 1-> SOURCE$="Left" END ->     2-> SOURCE$="Center" END -> 3-> SOURCE$="Right" END ->  END CASE  CASE J OF     1-> DEST$="Left" END -> 2-> DEST$="Center" END ->     3-> DEST$="Right" END -> END CASE PRINT("I move a disk from ";SOURCE$;" to ";DEST$)END PROCEDURE PROCEDURE MOVE IF NUMBER<>0 THEN NUMBER=NUMBER-1 J=6-I-J MOVE J=6-I-J PRINTMOVE I=6-I-J MOVE I=6-I-J NUMBER=NUMBER+1 END IFEND PROCEDURE BEGIN MAXNUM=12 MOSSE=0 PRINT(CHR$(12);TAB(25);"--- TOWERS OF HANOI ---")  REPEAT     PRINT("Number of disks ";)     INPUT(NUMBER)  UNTIL NUMBER>1 AND NUMBER<=MAXNUM  PRINT  PRINT("For ";NUMBER;"disks the total number of moves is";2^NUMBER-1)  I=1  ! number of source pole  J=3  ! number of destination pole  MOVEEND PROGRAM
Output:
                        --- TOWER OF HANOI ---
Number of disks ? 3

For  3 disks the total number of moves is 7
I move a disk from Left to Right
I move a disk from Left to Center
I move a disk from Right to Center
I move a disk from Left to Right
I move a disk from Center to Left
I move a disk from Center to Right
I move a disk from Left to Right


## Ezhil

 # (C) 2013 Ezhil Language Project# Tower of Hanoi – recursive solution நிரல்பாகம் ஹோனாய்(வட்டுகள், முதல்அச்சு, இறுதிஅச்சு,வட்டு)   @(வட்டுகள் == 1 ) ஆனால்     பதிப்பி  “வட்டு ” + str(வட்டு) + “ஐ \t  (” + str(முதல்அச்சு) + “  —> ” +  str(இறுதிஅச்சு)+ “) அச்சிற்கு நகர்த்துக.”  இல்லை   @( ["இ", "அ",  "ஆ"]  இல் அச்சு ) ஒவ்வொன்றாக          @( (முதல்அச்சு != அச்சு)  && (இறுதிஅச்சு  != அச்சு) ) ஆனால்              நடு = அச்சு          முடி  முடி     # solve problem for n-1 again between src and temp pegs                          ஹோனாய்(வட்டுகள்-1,   முதல்அச்சு,நடு,வட்டுகள்-1)     # move largest disk from src to destination    ஹோனாய்(1, முதல்அச்சு, இறுதிஅச்சு,வட்டுகள்)     # solve problem for n-1 again between different pegs    ஹோனாய்(வட்டுகள்-1, நடு, இறுதிஅச்சு,வட்டுகள்-1)  முடிமுடி ஹோனாய்(4,”அ”,”ஆ”,0)

## F#

#lightlet rec hanoi num start finish =  match num with  | 0 -> [ ]  | _ -> let temp = (6 - start - finish)         (hanoi (num-1) start temp) @ [ start, finish ] @ (hanoi (num-1) temp finish) [<EntryPoint>]let main args =  (hanoi 4 1 2) |> List.iter (fun pair -> match pair with                                          | a, b -> printf "Move disc from %A to %A\n" a b)  0

## Factor

USING: formatting kernel locals math ;IN: rosettacode.hanoi : move ( from to -- )    "%d->%d\n" printf ;:: hanoi ( n from to other -- )    n 0 > [        n 1 - from other to hanoi        from to move        n 1 - other to from hanoi    ] when ;

In the REPL:

( scratchpad ) 3 1 3 2 hanoi
1->3
1->2
3->2
1->3
2->1
2->3
1->3

## FALSE

["Move disk from "$!\" to "$!\""]p:  { to from }[n;0>[n;1-n: @\ h;! @\ p;! \@ h;! \@ n;1+n:]?]h:  { via to from }4n:["right"]["middle"]["left"]h;!%%%

With locals:

CREATE peg1 ," left "   CREATE peg2 ," middle " CREATE peg3 ," right "  : .$COUNT TYPE ;: MOVE-DISK LOCALS| via to from n | n 1 = IF CR ." Move disk from " from .$ ." to " to .$ELSE n 1- from via to RECURSE 1 from to via RECURSE n 1- via to from RECURSE THEN ; Without locals, executable pegs: : left ." left" ;: right ." right" ;: middle ." middle" ; : move-disk ( v t f n -- v t f ) dup 0= if drop exit then 1- >R rot swap [email protected] ( t v f n-1 ) recurse rot swap 2dup cr ." Move disk from " execute ." to " execute swap rot R> ( f t v n-1 ) recurse swap rot ;: hanoi ( n -- ) 1 max >R ['] right ['] middle ['] left R> move-disk drop drop drop ; ## Fortran Works with: Fortran version 90 and later PROGRAM TOWER CALL Move(4, 1, 2, 3) CONTAINS RECURSIVE SUBROUTINE Move(ndisks, from, to, via) INTEGER, INTENT (IN) :: ndisks, from, to, via IF (ndisks == 1) THEN WRITE(*, "(A,I1,A,I1)") "Move disk from pole ", from, " to pole ", to ELSE CALL Move(ndisks-1, from, via, to) CALL Move(1, from, to, via) CALL Move(ndisks-1, via, to, from) END IF END SUBROUTINE Move END PROGRAM TOWER ## FreeBASIC ' FB 1.05.0 Win64 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 IfEnd Sub Print "Three disks" : Printmove 3, 1, 2, 3 Print Print "Four disks" : Printmove 4, 1, 2, 3Print "Press any key to quit"Sleep Output: Three disks Move disk 1 from pole 1 to pole 2 Move disk 2 from pole 1 to pole 3 Move disk 1 from pole 2 to pole 3 Move disk 3 from pole 1 to pole 2 Move disk 1 from pole 3 to pole 1 Move disk 2 from pole 3 to pole 2 Move disk 1 from pole 1 to pole 2 Four disks 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 Move disk 4 from pole 1 to pole 2 Move disk 1 from pole 3 to pole 2 Move disk 2 from pole 3 to pole 1 Move disk 1 from pole 2 to pole 1 Move disk 3 from pole 3 to pole 2 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  ## Frink  /** Set up the recursive call for n disks */hanoi[n] := hanoi[n, 1, 3, 2] /** The recursive call. */hanoi[n, source, target, aux] :={ if n > 0 { hanoi[n-1, source, aux, target] println["Move from$source to $target"] hanoi[n-1, aux, target, source] }} hanoi  ## FutureBasic  include "ConsoleWindow" void local fn move( n as long, fromPeg as long, toPeg as long, viaPeg as long )if n > 0 fn move( n-1, fromPeg, viaPeg, toPeg ) print "Move disk from "; fromPeg; " to "; toPeg fn move( n-1, viaPeg, toPeg, fromPeg )end ifend fn fn move( 4, 1, 2, 3 )printprint "Towers of Hanoi puzzle solved."end  Output: 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 solved.  ## Fōrmulæ In this page you can see the solution of this task. Fōrmulæ programs are not textual, visualization/edition of programs is done showing/manipulating structures but not text (more info). Moreover, there can be multiple visual representations of the same program. Even though it is possible to have textual representation —i.e. XML, JSON— they are intended for transportation effects more than visualization and edition. The option to show Fōrmulæ programs and their results is showing images. Unfortunately images cannot be uploaded in Rosetta Code. ## GAP Hanoi := function(n) local move; move := function(n, a, b, c) # from, through, to if n = 1 then Print(a, " -> ", c, "\n"); else move(n - 1, a, c, b); move(1, a, b, c); move(n - 1, b, a, c); fi; end; move(n, "A", "B", "C");end; Hanoi(1);# A -> C Hanoi(2);# A -> B# A -> C# B -> C Hanoi(3);# A -> C# A -> B# C -> B# A -> C# B -> A# B -> C# A -> C ## Go package main import "fmt" // a towers of hanoi solver just has one method, playtype solver interface { play(int)} func main() { var t solver // declare variable of solver type t = new(towers) // type towers must satisfy solver interface t.play(4)} // towers is example of type satisfying solver interfacetype towers struct { // an empty struct. some other solver might fill this with some // data representation, maybe for algorithm validation, or maybe for // visualization.} // play is sole method required to implement solver typefunc (t *towers) play(n int) { // drive recursive solution, per task description t.moveN(n, 1, 2, 3)} // recursive algorithmfunc (t *towers) moveN(n, from, to, via int) { if n > 0 { t.moveN(n-1, from, via, to) t.move1(from, to) t.moveN(n-1, via, to, from) }} // example function prints actions to screen.// enhance with validation or visualization as needed.func (t *towers) move1(from, to int) { fmt.Println("move disk from rod", from, "to rod", to)} In other words: package main import "fmt" func main() { move(3, "A", "B", "C")} func move(n uint64, a, b, c string) { if n > 0 { move(n-1, a, c, b) fmt.Println("Move disk from " + a + " to " + c) move(n-1, b, a, c) }} ## Groovy Unlike most solutions here this solution manipulates more-or-less actual stacks of more-or-less actual rings. def tail = { list, n -> def m = list.size(); list.subList([m - n, 0].max(),m) } final STACK = [A:[],B:[],C:[]].asImmutable() def report = { it -> }def check = { it -> } def moveRing = { from, to -> to << from.pop(); report(); check(to) } def moveStackmoveStack = { from, to, using = STACK.values().find { !(it.is(from) || it.is(to)) } -> if (!from) return def n = from.size() moveStack(tail(from, n-1), using, to) moveRing(from, to) moveStack(tail(using, n-1), to, from)} Test program: enum Ring { S('°'), M('o'), L('O'), XL('( )'); private sym private Ring(sym) { this.sym=sym } String toString() { sym }} report = { STACK.each { k, v -> println "${k}: ${v}" }; println() }check = { to -> assert to == ([] + to).sort().reverse() } Ring.values().reverseEach { STACK.A << it }report()check(STACK.A)moveStack(STACK.A, STACK.C) Output: A: [( ), O, o, °] B: [] C: [] A: [( ), O, o] B: [°] C: [] A: [( ), O] B: [°] C: [o] A: [( ), O] B: [] C: [o, °] A: [( )] B: [O] C: [o, °] A: [( ), °] B: [O] C: [o] A: [( ), °] B: [O, o] C: [] A: [( )] B: [O, o, °] C: [] A: [] B: [O, o, °] C: [( )] A: [] B: [O, o] C: [( ), °] A: [o] B: [O] C: [( ), °] A: [o, °] B: [O] C: [( )] A: [o, °] B: [] C: [( ), O] A: [o] B: [°] C: [( ), O] A: [] B: [°] C: [( ), O, o] A: [] B: [] C: [( ), O, o, °] ## 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: 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 You can also do the above with one tail-recursion call: hanoi :: Integer -> a -> a -> a -> [(a, a)] 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: hanoiIO n = mapM_ f$ hanoi n 1 2 3 where  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 :: Integer -> IO ()hanoiM n = hanoiM' n 1 2 3 where hanoiM' 0 _ _ _ = return () hanoiM' n a b c = do 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:

import Data.Monoid ((<>), mempty)import Data.List (intercalate, transpose) hanoi :: Int -> t -> t -> t -> [[t]]hanoi 0 _ _ _ = memptyhanoi n l r m = hanoi (n - 1) l m r <> [[l, r]] <> hanoi (n - 1) m r l showHanoi :: Int -> StringshowHanoi n =  unlines $intercalate " -> " <$>  transpose    ((justifyLeft 6 ' ' <$>) <$> transpose (hanoi n "left" "right" "mid")) justifyLeft :: Int -> Char -> String -> StringjustifyLeft n c s = take n (s <> replicate n c) -- TEST -------------------------------------------------------------main :: IO ()main = putStrLn $showHanoi 5 Output: left -> right left -> mid right -> mid left -> right mid -> left mid -> right left -> right left -> mid right -> mid right -> left mid -> left right -> mid left -> right left -> mid right -> mid left -> right mid -> left mid -> right left -> right mid -> left right -> mid right -> left mid -> left mid -> right left -> right left -> mid right -> mid left -> right mid -> left mid -> right left -> right ## HolyC Translation of: C U0 Move(U8 n, U8 from, U8 to, U8 via) { if (n > 0) { Move(n - 1, from, via, to); Print("Move disk from pole %d to pole %d\n", from, to); Move(n - 1, via, to, from); }} Move(4, 1, 2, 3); ## Icon and Unicon The following is based on a solution in the Unicon book. procedure main(arglist)hanoi(arglist) | stop("Usage: hanoi n\n\rWhere n is the number of disks to move.")end #procedure hanoi(n:integer, needle1:1, needle2:2) # unicon shorthand for icon code 1,2,3 below procedure hanoi(n, needle1, needle2) #: solve towers of hanoi by moving n disks from needle 1 to needle2 via otherlocal other n := integer(0 < n) | runerr(n,101) # 1 ensure integer (this also ensures it's positive too)/needle1 := 1 # 2 default/needle2 := 2 # 3 default if n = 1 then write("Move disk from ", needle1, " to ", needle2)else { other := 6 - needle1 - needle2 # clever but somewhat un-iconish way to find other hanoi(n-1, needle1, other) write("Move disk from ", needle1, " to ", needle2) hanoi(n-1, other, needle2) }returnend ## Inform 7 Hanoi is a room. A post is a kind of supporter. A post is always fixed in place. The left post, the middle post, and the right post are posts in Hanoi. A disk is a kind of supporter.The red disk is a disk on the left post.The orange disk is a disk on the red disk.The yellow disk is a disk on the orange disk.The green disk is a disk on the yellow disk. Definition: a disk is topmost if nothing is on it. When play begins: move 4 disks from the left post to the right post via the middle post. To move (N - number) disk/disks from (FP - post) to (TP - post) via (VP - post): if N > 0: move N - 1 disks from FP to VP via TP; say "Moving a disk from [FP] to [TP]..."; let D be a random topmost disk enclosed by FP; 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. ## Io hanoi := method(n, from, to, via, if (n == 1) then ( writeln("Move from ", from, " to ", to) ) else ( hanoi(n - 1, from, via, to ) hanoi(1 , from, to , via ) hanoi(n - 1, via , to , from) )) ## Ioke  = method(n, f, u, t, if(n < 2, "#{f} --> #{t}" println, H(n - 1, f, t, u) "#{f} --> #{t}" println H(n - 1, u, f, t) )) hanoi = method(n, H(n, 1, 2, 3)) ## IS-BASIC 100 PROGRAM "Hanoi.bas"110 CALL HANOI(4,1,3,2)120 DEF HANOI(DISK,FRO,TO,WITH)130 IF DISK>0 THEN140 CALL HANOI(DISK-1,FRO,WITH,TO)150 PRINT "Move disk";DISK;"from";FRO;"to";TO160 CALL HANOI(DISK-1,WITH,TO,FRO)170 END IF180 END DEF ## J Solutions H =: [email protected],&2  (({&0 2 1,0 2,{&1 0 2)@$:@<:) @. *    NB. tacit using anonymous recursion
Example use:
   H 30 20 12 10 21 21 02 0

The result is a 2-column table; a row i,j is interpreted as: move a disk (the top disk) from peg i to peg j . Or, using explicit rather than implicit code:

H1=: monad define                                   NB. explicit equivalent of H  if. y do.    ({&0 2 1 , 0 2 , {&1 0 2) H1 y-1  else.    i.0 2  end.)

The usage here is the same:

   H1 2
0 1
0 2
1 2
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):

hanoi=: monad define  moves=. H y  disks=.  $~ ((],[,])$:@<:) @.* y  ('move disk ';' from peg ';' to peg ');@,."1 ":&.>disks,.1+moves)
Demonstration:
   hanoi 3move disk 1 from peg 1 to peg 3move disk 2 from peg 1 to peg 2move disk 1 from peg 3 to peg 2move disk 3 from peg 1 to peg 3move disk 1 from peg 2 to peg 1move disk 2 from peg 2 to peg 3move disk 1 from peg 1 to peg 3

## Java

public void move(int n, int from, int to, int via) {  if (n == 1) {    System.out.println("Move disk from pole " + from + " to pole " + to);  } else {    move(n - 1, from, via, to);    move(1, from, to, via);    move(n - 1, via, to, from);  }}

## JavaScript

### ES5

function move(n, a, b, c) {  if (n > 0) {    move(n-1, a, c, b);    console.log("Move disk from " + a + " to " + c);    move(n-1, b, a, c);  }}move(4, "A", "B", "C");

Or, as a functional expression, rather than a statement with side effects:

(function () {     // hanoi :: Int -> String -> String -> String -> [[String, String]]    function hanoi(n, a, b, c) {        return n ? hanoi(n - 1, a, c, b)            .concat([                [a, b]            ])            .concat(hanoi(n - 1, c, b, a)) : [];    }     return hanoi(3, 'left', 'right', 'mid')        .map(function (d) {            return d + ' -> ' + d;        });})();
Output:
["left -> right", "left -> mid", "right -> mid", "left -> right",  "mid -> left", "mid -> right",  "left -> right"]

### ES6

(() => {    'use strict';     // hanoi :: Int -> String -> String -> String -> [[String, String]]    const hanoi = (n, a, b, c) =>        n ? hanoi(n - 1, a, c, b)        .concat([            [a, b]        ])        .concat(hanoi(n - 1, c, b, a)) : [];     // show :: a -> String    const show = x => JSON.stringify(x, null, 2);     return show(        hanoi(3, 'left', 'right', 'mid')        .map(d => d + ' -> ' + d)    );})();
Output:
[
"left -> right",
"left -> mid",
"right -> mid",
"left -> right",
"mid -> left",
"mid -> right",
"left -> right"
]

## Joy

From here

DEFINE hanoi == [[rolldown] infra] dip                 [ [ [null] [pop pop] ]                   [ [dup2 [[rotate] infra] dip pred]                     [ [dup rest put] dip                       [[swap] infra] dip pred ]                     [] ] ]                 condnestrec.

Using it (5 is the number of disks.)

[source destination temp] 5 hanoi.

## jq

Works with: jq version 1.4

The algorithm used here is used elsewhere on this page but it is worthwhile pointing out that it can also be read as a proof that:

(a) move(n;"A";"B";"C") will logically succeed for n>=0; and

(b) move(n;"A";"B";"C") will generate the sequence of moves, assuming sufficient computing resources.

The proof of (a) is by induction:

• As explained in the comments, the algorithm establishes that move(n;x;y;z) is possible for all n>=0 and distinct x,y,z if move(n-1;x;y;z)) is possible;
• Since move(0;x;y;z) evidently succeeds, (a) is established by induction.

The truth of (b) follows from the fact that the algorithm emits an instruction of what to do when moving a single disk.

# n is the number of disks to move from From to Todef move(n; From; To; Via):  if n > 0 then     # move all but the largest at From to Via (according to the rules):     move(n-1; From; Via; To),     # ... so the largest disk at From is now free to move to its final destination:     "Move disk from \(From) to \(To)",     # Move the remaining disks at Via to To:     move(n-1; Via; To; From)  else empty  end;

Example:

move(5; "A"; "B"; "C")


## Jsish

From Javascript ES5 entry.

/* Towers of Hanoi, in Jsish */ function move(n, a, b, c) {  if (n > 0) {    move(n-1, a, c, b);    puts("Move disk from " + a + " to " + c);    move(n-1, b, a, c);  }} if (Interp.conf('unitTest')) move(4, "A", "B", "C"); /*=!EXPECTSTART!=Move disk from A to BMove disk from A to CMove disk from B to CMove disk from A to BMove disk from C to AMove disk from C to BMove disk from A to BMove disk from A to CMove disk from B to CMove disk from B to AMove disk from C to AMove disk from B to CMove disk from A to BMove disk from A to CMove disk from B to C=!EXPECTEND!=*/
Output:
prompt$jsish -u towersOfHanoi.jsi [PASS] towersOfHanoi.jsi ## Julia Translation of: R  function solve(n::Integer, from::Integer, to::Integer, via::Integer) if n == 1 println("Move disk from$from to $to") else solve(n - 1, from, via, to) solve(1, from, to, via) solve(n - 1, via, to, from) endend solve(4, 1, 2, 3)  Output: 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  ## K  h:{[n;a;b;c]if[n>0;_f[n-1;a;c;b];0:,//$($n,":",$a,"->",$b,"\n");_f[n-1;c;b;a]]} h[4;1;2;3]1:1->32:1->21:3->23:1->31:2->12:2->31:1->34:1->21:3->22:3->11:2->13:3->21:1->32:1->21: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.  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];s1 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 ## Kotlin // version 1.1.0 class Hanoi(disks: Int) { private var moves = 0 init { println("Towers of Hanoi with$disks disks:\n")        move(disks, 'L', 'C', 'R')        println("\nCompleted in $moves moves\n") } private fun move(n: Int, from: Char, to: Char, via: Char) { if (n > 0) { move(n - 1, from, via, to) moves++ println("Move disk$n from $from to$to")            move(n - 1, via, to, from)        }    }} fun main(args: Array<String>) {    Hanoi(3)    Hanoi(4)}
Output:
Towers of Hanoi with 3 disks:

Move disk 1 from L to C
Move disk 2 from L to R
Move disk 1 from C to R
Move disk 3 from L to C
Move disk 1 from R to L
Move disk 2 from R to C
Move disk 1 from L to C

Completed in 7 moves

Towers of Hanoi with 4 disks:

Move disk 1 from L to R
Move disk 2 from L to C
Move disk 1 from R to C
Move disk 3 from L to R
Move disk 1 from C to L
Move disk 2 from C to R
Move disk 1 from L to R
Move disk 4 from L to C
Move disk 1 from R to C
Move disk 2 from R to L
Move disk 1 from C to L
Move disk 3 from R to C
Move disk 1 from L to R
Move disk 2 from L to C
Move disk 1 from R to C

Completed in 15 moves


## lambdatalk

(Following NewLisp, PicoLisp, Racket, Scheme)

 {def move {lambda {:n :from :to :via}  {if {<= :n 0}   then >   else {move {- :n 1} :from :via :to}         move disk :n from :from to :to {br}        {move {- :n 1} :via :to :from} }}}-> move{move 4 A B C}> move disk 1 from A to C> move disk 2 from A to B> move disk 1 from C to B> move disk 3 from A to C> move disk 1 from B to A> move disk 2 from B to C> move disk 1 from A to C> move disk 4 from A to B> move disk 1 from C to B> move disk 2 from C to A> move disk 1 from B to A> move disk 3 from C to B> move disk 1 from A to C> move disk 2 from A to B> move disk 1 from C to B  

## Lingo

on hanoi (n, a, b, c)  if n > 0 then    hanoi(n-1, a, c, b)    put "Move disk from" && a && "to" && c    hanoi(n-1, b, a, c)  end ifend
hanoi(3, "A", "B", "C")-- "Move disk from A to C"-- "Move disk from A to B"-- "Move disk from C to B"-- "Move disk from A to C"-- "Move disk from B to A"-- "Move disk from B to C"-- "Move disk from A to C"

## Logo

to move :n :from :to :via  if :n = 0 [stop]  move :n-1 :from :via :to  (print [Move disk from] :from [to] :to)  move :n-1 :via :to :fromendmove 4 "left "middle "right

## Logtalk

:- object(hanoi).     :- public(run/1).    :- mode(run(+integer), one).    :- info(run/1, [        comment is 'Solves the towers of Hanoi problem for the specified number of disks.',        argnames is ['Disks']]).     run(Disks) :-        move(Disks, left, middle, right).     move(1, Left, _, Right):-        !,        report(Left, Right).    move(Disks, Left, Aux, Right):-        Disks2 is Disks - 1,        move(Disks2, Left, Right, Aux),        report(Left, Right),        move(Disks2, Aux, Left, Right).     report(Pole1, Pole2):-        write('Move a disk from '),        writeq(Pole1),        write(' to '),        writeq(Pole2),        write('.'),        nl. :- end_object.

## LOLCODE

 HAI HOW DUZ I HANOI YR N AN YR SRC AN YR DST AN YR VIA    BTW VISIBLE SMOOSH "HANOI N=" N " SRC=" SRC " DST=" DST " VIA=" VIA MKAY    BOTH SAEM N AN 0, O RLY?        YA RLY            BTW VISIBLE "Done."            GTFO        NO WAI            I HAS A LOWER ITZ DIFF OF N AN 1            HANOI DST VIA SRC LOWER            VISIBLE SMOOSH "Move disc " N " from " SRC ...             " to " DST MKAY            HANOI SRC DST VIA LOWER    OICIF U SAY SO HANOI 2 3 1 4 BTW requires reversed arguments? KTHXBYE 

## Lua

function move(n, src, dst, via)    if n > 0 then        move(n - 1, src, via, dst)        print(src, 'to', dst)        move(n - 1, via, dst, src)    endend move(4, 1, 2, 3)

### Hanoi Iterative

 #!/usr/bin/env luajitlocal function printf(fmt, ...) io.write(string.format(fmt, ...)) endlocal runs=0local function move(tower, from, to)	if #tower[from]==0 		or (#tower[to]>0 		and tower[from][#tower[from]]>tower[to][#tower[to]]) then			to,from=from,to	end	if #tower[from]>0 then		tower[to][#tower[to]+1]=tower[from][#tower[from]]		tower[from][#tower[from]]=nil 		io.write(tower[to][#tower[to]],":",from, "→", to, " ")	endend local function hanoi(n)	local src,dst,via={},{},{}	local tower={src,dst,via}	for i=1,n do src[i]=n-i+1 end	local one,nxt,lst	if n%2==1 then -- odd		one,nxt,lst=1,2,3	else		one,nxt,lst=1,3,2	end	--repeat	::loop::		move(tower, one, nxt)		if #dst==n then return end		move(tower, one, lst)		one,nxt,lst=nxt,lst,one	goto loop	--until falseend local num=arg and tonumber(arg) or 4 hanoi(num) 
Output:
> ./hanoi_iter.lua 5
1:1→2 2:1→3 1:2→3 3:1→2 1:3→1 2:3→2 1:1→2 4:1→3 1:2→3 2:2→1 1:3→1 3:2→3 1:1→2 2:1→3 1:2→3 5:1→2 1:3→1 2:3→2 1:1→2 3:3→1 1:2→3 2:2→1 1:3→1 4:3→2 1:1→2 2:1→3 1:2→3 3:1→2 1:3→1 2:3→2 1:1→2


### Hanoi Bitwise Fast

 #!/usr/bin/env luajit-- binary solutionlocal bit=require"bit"local band,bor=bit.band,bit.borlocal function hanoi(n)	local even=(n-1)%2	for m=1,2^n-1 do		io.write(m,":",band(m,m-1)%3+1, "→", (bor(m,m-1)+1)%3+1, " ")	endend local num=arg and tonumber(arg) or 4 hanoi(num) 
Output:
> ./hanoi_bit.lua 4
1:1→3 2:1→2 3:3→2 4:1→3 5:2→1 6:2→3 7:1→3 8:1→2 9:3→2 10:3→1 11:2→1 12:3→2 13:1→3 14:1→2 15:3→2
> time ./hanoi_bit.lua 30 >/dev/null  ; on AMD FX-8350 @ 4 GHz
./hanoi_bit.lua 30 > /dev/null  297,40s user 1,39s system 99% cpu 4:59,01 total


## M2000 Interpreter

Translation of: FreeBasic
 Module Hanoi {      Rem HANOI TOWERS      Print "Three disks" : Print      move(3, 1, 2, 3)      Print       Print "Four disks" : Print      move(4, 1, 2, 3)        Sub move(n, from, to, via)            If n <=0 Then Exit Sub            move(n - 1, from, via, to)            Print "Move disk"; n; " from pole"; from; " to pole"; to            move(n - 1, via, to, from)      End Sub}Hanoi 
Output:

same as in FreeBasic

## Maple

 Hanoi := proc(n::posint,a,b,c)   if n = 1 then       printf("Move disk from tower %a to tower %a.\n",a,c);   else       Hanoi(n-1,a,c,b);       Hanoi(1,a,b,c);       Hanoi(n-1,b,a,c);    fi;end: printf("Moving 2 disks from tower A to tower C using tower B.\n");Hanoi(2,A,B,C); 
Output:

Moving 2 disks from tower A to tower C using tower B.

Move disk from tower A to tower B.

Move disk from tower A to tower C.

Move disk from tower B to tower C.

## Mathematica

Hanoi[0, from_, to_, via_] := Null  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])

## MATLAB

This is a direct translation from the Python example given in the Wikipedia entry for the Tower of Hanoi puzzle.

function towerOfHanoi(n,A,C,B)    if (n~=0)        towerOfHanoi(n-1,A,B,C);        disp(sprintf('Move plate %d from tower %d to tower %d',[n A C]));        towerOfHanoi(n-1,B,C,A);    endend
Sample output:
towerOfHanoi(3,1,3,2)
Move plate 1 from tower 1 to tower 3
Move plate 2 from tower 1 to tower 2
Move plate 1 from tower 3 to tower 2
Move plate 3 from tower 1 to tower 3
Move plate 1 from tower 2 to tower 1
Move plate 2 from tower 2 to tower 3
Move plate 1 from tower 1 to tower 3

## MiniScript

moveDisc = function(n, A, C, B)    if n == 0 then return    moveDisc n-1, A, B, C    print "Move disc " + n + " from pole " + A + " to pole " + C    moveDisc n-1, B, C, Aend function // Move disc 3 from pole 1 to pole 3, with pole 2 as sparemoveDisc 3, 1, 3, 2
Output:
Move disc 1 from pole 1 to pole 3
Move disc 2 from pole 1 to pole 2
Move disc 1 from pole 3 to pole 2
Move disc 3 from pole 1 to pole 3
Move disc 1 from pole 2 to pole 1
Move disc 2 from pole 2 to pole 3
Move disc 1 from pole 1 to pole 3

## MIPS Assembly

 # Towers of Hanoi# MIPS assembly implementation (tested with MARS)# Source: https://stackoverflow.com/questions/50382420/hanoi-towers-recursive-solution-using-mips/50383530#50383530 .dataprompt: .asciiz "Enter a number: "part1: .asciiz "\nMove disk "part2: .asciiz " from rod "part3: .asciiz " to rod " .text.globl mainmain:    li $v0, 4 # print string la$a0,  prompt    syscall    li $v0, 5 # read integer syscall # parameters for the routine add$a0, $v0,$zero # move to $a0 li$a1, 'A'    li $a2, 'B' li$a3, 'C'     jal hanoi           # call hanoi routine     li $v0, 10 # exit syscall hanoi: #save in stack addi$sp, $sp, -20 sw$ra, 0($sp) sw$s0, 4($sp) sw$s1, 8($sp) sw$s2, 12($sp) sw$s3, 16($sp) add$s0, $a0,$zero    add $s1,$a1, $zero add$s2, $a2,$zero    add $s3,$a3, $zero addi$t1, $zero, 1 beq$s0, $t1, output recur1: addi$a0, $s0, -1 add$a1, $s1,$zero        add $a2,$s3, $zero add$a3, $s2,$zero        jal hanoi         j output     recur2:         addi $a0,$s0, -1        add $a1,$s3, $zero add$a2, $s2,$zero        add $a3,$s1, $zero jal hanoi exithanoi: lw$ra, 0($sp) # restore registers from stack lw$s0, 4($sp) lw$s1, 8($sp) lw$s2, 12($sp) lw$s3, 16($sp) addi$sp, $sp, 20 # restore stack pointer jr$ra     output:         li $v0, 4 # print string la$a0,  part1        syscall        li $v0, 1 # print integer add$a0, $s0,$zero        syscall        li $v0, 4 # print string la$a0,  part2        syscall        li $v0, 11 # print character add$a0, $s1,$zero        syscall        li $v0, 4 # print string la$a0,  part3        syscall        li $v0, 11 # print character add$a0, $s2,$zero        syscall         beq $s0,$t1, exithanoi        j recur2 

## МК-61/52

^	2	x^y	П0	<->	2	/	{x}	x#0	163	П3	2	П2	БП	20	3	П2	2	П31	П1	ПП	25	КППB	ПП	28	КППA	ПП	31КППB	ПП	34	КППA	ИП1	ИП3	КППC	ИП1	ИП2	КППCИП3	ИП2	КППC	ИП1	ИП3	КППC	ИП2	ИП1	КППC	ИП2ИП3	КППC	ИП1	ИП3	КППC	В/О	ИП1	ИП2	БП	62ИП2	ИП1	КППC	ИП1	ИП2	ИП3	П1	->	П3	->П2	В/О	1	0	/	+	С/П	КИП0	ИП0	x=089	3	3	1	ИНВ	^	ВП	2	С/П	В/О

Instruction: РA = 56; РB = 60; РC = 72; N В/О С/П, where 2 <= N <= 7.

## Modula-2

MODULE Towers;FROM FormatString IMPORT FormatString;FROM Terminal IMPORT WriteString,ReadChar; PROCEDURE Move(n,from,to,via : INTEGER);VAR buf : ARRAY[0..63] OF CHAR;BEGIN    IF n>0 THEN        Move(n-1, from, via, to);        FormatString("Move disk %i from pole %i to pole %i\n", buf, n, from, to);        WriteString(buf);        Move(n-1, via, to, from)    ENDEND Move; BEGIN    Move(3, 1, 3, 2);     ReadCharEND Towers.

## Modula-3

MODULE Hanoi EXPORTS Main; FROM IO IMPORT Put;FROM Fmt IMPORT Int; PROCEDURE doHanoi(n, from, to, using: INTEGER) =  BEGIN    IF n > 0 THEN      doHanoi(n - 1, from, using, to);      Put("move " & Int(from) & " --> " & Int(to) & "\n");      doHanoi(n - 1, using, to, from);    END;  END doHanoi; BEGIN  doHanoi(4, 1, 2, 3);END Hanoi.

## Oz

declare  proc {TowersOfHanoi N From To Via}     if N > 0 then        {TowersOfHanoi N-1 From Via To}        {System.showInfo "Move from "#From#" to "#To}        {TowersOfHanoi N-1 Via To From}     end  endin  {TowersOfHanoi 4 left middle right}

## PARI/GP

Translation of: Python
\\ Towers of Hanoi\\ 8/19/2016 aev\\ Where: n - number of disks, sp - start pole, ep - end pole.HanoiTowers(n,sp,ep)={  if(n!=0,     HanoiTowers(n-1,sp,6-sp-ep);    print("Move disk ", n, " from pole ", sp," to pole ", ep);    HanoiTowers(n-1,6-sp-ep,ep);     );}\\ Testing n=3:HanoiTowers(3,1,3);
Output:
> HanoiTower(3,1,3);
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


## Pascal

Works with: Free Pascal version 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.

program Hanoi;type  TPole = (tpLeft, tpCenter, tpRight);const  strPole:array[TPole] of string=('left','center','right');  procedure MoveStack (const Ndisks : integer; const Origin,Destination,Auxiliary:TPole); begin  if Ndisks >0 then begin     MoveStack(Ndisks - 1, Origin,Auxiliary, Destination );     Writeln('Move disk ',Ndisks ,' from ',strPole[Origin],' to ',strPole[Destination]);     MoveStack(Ndisks - 1, Auxiliary, Destination, origin);  end; end; begin MoveStack(4,tpLeft,tpCenter,tpRight);end.

A little longer, but clearer for my taste

program Hanoi;type  TPole = (tpLeft, tpCenter, tpRight);const  strPole:array[TPole] of string=('left','center','right');  procedure MoveOneDisk(const DiskNum:integer; const Origin,Destination:TPole); begin  Writeln('Move disk ',DiskNum,' from ',strPole[Origin],' to ',strPole[Destination]); end;  procedure MoveStack (const Ndisks : integer; const Origin,Destination,Auxiliary:TPole); begin  if Ndisks =1 then       MoveOneDisk(1,origin,Destination)  else begin       MoveStack(Ndisks - 1, Origin,Auxiliary, Destination );       MoveOneDisk(Ndisks,origin,Destination);       MoveStack(Ndisks - 1, Auxiliary, Destination, origin);  end; end; begin MoveStack(4,tpLeft,tpCenter,tpRight);end.

## Perl

sub hanoi {    my ($n,$from, $to,$via) = (@_, 1, 2, 3);     if ($n == 1) { print "Move disk from pole$from to pole $to.\n"; } else { hanoi($n - 1, $from,$via, $to); hanoi(1,$from, $to,$via);        hanoi($n - 1,$via, $to,$from);    };};

## Phix

constant poles = {"left","middle","right"}enum               left,  middle,  right sequence disksinteger movesprocedure showpegs(integer src, integer dest)string desc = sprintf("%s to %s:",{poles[src],poles[dest]})    disks[dest] &= disks[src][$] disks[src] = disks[src][1..$-1]    for i=1 to length(disks) do        printf(1,"%-16s | %s\n",{desc,join(sq_add(disks[i],'0'),' ')})        desc = ""    end for    printf(1,"\n")    moves += 1end procedure procedure hanoir(integer n, src=left, dest=right, via=middle)    if n>0 then        hanoir(n-1, src, via, dest)        showpegs(src,dest)        hanoir(n-1, via, dest, src)    end ifend procedure procedure hanoi(integer n)    disks = {reverse(tagset(n)),{},{}}    moves = 0    hanoir(n)    printf(1,"completed in %d moves\n",{moves})end procedure hanoi(3)
Output:
left to right:   | 3 2
|
| 1

left to middle:  | 3
| 2
| 1

right to middle: | 3
| 2 1
|

left to right:   |
| 2 1
| 3

middle to left:  | 1
| 2
| 3

middle to right: | 1
|
| 3 2

left to right:   |
|
| 3 2 1

completed in 7 moves

left to middle:  | 4 3 2
| 1
|

left to right:   | 4 3
| 1
| 2

middle to right: | 4 3
|
| 2 1

...

left to middle:  | 2
| 1
| 4 3

left to right:   |
| 1
| 4 3 2

middle to right: |
|
| 4 3 2 1

completed in 15 moves

left to right:   | 5 4 3 2
|
| 1

left to middle:  | 5 4 3
| 2
| 1

right to middle: | 5 4 3
| 2 1
|

...

middle to left:  | 1
| 2
| 5 4 3

middle to right: | 1
|
| 5 4 3 2

left to right:   |
|
| 5 4 3 2 1

completed in 31 moves

left to middle:  | 6 5 4 3 2
| 1
|

left to right:   | 6 5 4 3
| 1
| 2

middle to right: | 6 5 4 3
|
| 2 1

...

left to middle:  | 2
| 1
| 6 5 4 3

left to right:   |
| 1
| 6 5 4 3 2

middle to right: |
|
| 6 5 4 3 2 1

completed in 63 moves


## PHL

Translation of: C
module hanoi; extern printf; @Void move(@Integer n, @Integer from, @Integer to, @Integer via) [	if (n > 0) {		move(n - 1, from, via, to);		printf("Move disk from pole %d to pole %d\n", from, to);		move(n - 1, via, to, from);	}] @Integer main [	move(4, 1,2,3);	return 0;]

## PHP

Translation of: Java
function move($n,$from,$to,$via) {    if ($n === 1) { print("Move disk from pole$from to pole $to"); } else { move($n-1,$from,$via,$to); move(1,$from,$to,$via);        move($n-1,$via,$to,$from);    }}

## PicoLisp

(de move (N A B C)  # Use: (move 3 'left 'center 'right)   (unless (=0 N)      (move (dec N) A C B)      (println 'Move 'disk 'from A 'to B)      (move (dec N) C B A) ) )

## PL/I

Translation of: Fortran
tower: proc options (main);    call Move (4,1,2,3); Move: procedure (ndiscs, from, to, via) recursive;   declare (ndiscs, from, to, via) fixed binary;    if ndiscs = 1 then      put skip edit ('Move disc from pole ', trim(from), ' to pole ',         trim(to) ) (a);   else      do;         call Move (ndiscs-1, from, via, to);         call Move (1, from, to, via);         call Move (ndiscs-1, via, to, from);      end;end Move; end tower;

## Plain TeX

\newcount\hanoidepth\def\hanoi#1{%  \hanoidepth = #1  \move abc}%\def\move#1#2#3{%  \advance \hanoidepth by -1  \ifnum \hanoidepth > 0    \move #1#3#2  \fi  Move the upper disk from pole #1 to pole #3.\par  \ifnum \hanoidepth > 0    \move#2#1#3  \fi  \advance \hanoidepth by 1} \hanoi{5}\end

## Pop11

define hanoi(n, src, dst, via);if n > 0 then    hanoi(n - 1, src, via, dst);    'Move disk ' >< n >< ' from ' >< src >< ' to ' >< dst >< '.' =>    hanoi(n - 1, via, dst, src);endif;enddefine; hanoi(4, "left", "middle", "right");

## PostScript

A million-page document, each page showing one move.

%!PS-Adobe-3.0%%BoundingBox: 0 0 300 300 /plate {        exch 100 mul 50 add exch th mul 10 add moveto        dup s mul neg 2 div 0 rmoveto        dup s mul 0 rlineto        0 th rlineto        s neg mul 0 rlineto        closepath gsave .5 setgray fill grestore 0 setgray stroke} def /drawtower {        0 1 2 { /x exch def /y 0 def                tower x get {                        dup 0 gt { x y plate /y y 1 add def } {pop} ifelse                } forall        } for showpage} def /apop { [ exch aload pop /last exch def ] last } def/apush{ [ 3 1 roll aload pop counttomark -1 roll ] } def /hanoi {        0 dict begin /from /mid /to /h 5 -1 2 { -1 roll def } for        h 1 eq {                        tower from get apop tower to get apush                tower to 3 -1 roll put                tower from 3 -1 roll put                drawtower        } {                     /h h 1 sub def                from to mid h hanoi                from mid to 1 hanoi                mid from to h hanoi        } ifelse        end} def  /n 12 def/s 90 n div def/th 180 n div def/tower [ [n 1 add -1 2 { } for ] [] [] ] def drawtower 0 1 2 n hanoi %%EOF

## PowerShell

Works with: PowerShell version 4.0
 function hanoi($n,$a,  $b,$c) {    if($n -eq 1) { "$a -> $c" } else{ hanoi ($n - 1) $a$c $b hanoi 1$a $b$c         hanoi ($n - 1)$b $a$c    }}hanoi 3 "A" "B" "C" 

Output:

A -> C
A -> B
C -> B
A -> C
B -> A
B -> C
A -> C


## Prolog

From Programming in Prolog by W.F. Clocksin & C.S. Mellish

hanoi(N) :- move(N,left,center,right). move(0,_,_,_) :- !.move(N,A,B,C) :-    M is N-1,    move(M,A,C,B),    inform(A,B),    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,  length(Moves, NMoves),  phrase(move(N, Src, Aux, Dest), Moves).  move(1, Src, _, Dest) --> !,  [Src->Dest]. move(2, Src, Aux, Dest) --> !,  [Src->Aux,Src->Dest,Aux->Dest]. move(N, Src, Aux, Dest) -->  { succ(N0, N) },  move(N0, Src, Dest, Aux),  move(1, Src, Aux, Dest),  move(N0, Aux, Src, Dest). 

## PureBasic

Algorithm according to http://en.wikipedia.org/wiki/Towers_of_Hanoi

Procedure Hanoi(n, A.s, C.s, B.s)  If n    Hanoi(n-1, A, B, C)    PrintN("Move the plate from "+A+" to "+C)    Hanoi(n-1, B, C, A)  EndIfEndProcedure

Full program

Procedure Hanoi(n, A.s, C.s, B.s)  If n    Hanoi(n-1, A, B, C)    PrintN("Move the plate from "+A+" to "+C)    Hanoi(n-1, B, C, A)  EndIfEndProcedure If OpenConsole()  Define n=3  PrintN("Moving "+Str(n)+" pegs."+#CRLF$) Hanoi(n,"Left Peg","Middle Peg","Right Peg") PrintN(#CRLF$+"Press ENTER to exit."): Input()EndIf
Output:
Moving 3 pegs.

Move the plate from Left Peg to Middle Peg
Move the plate from Left Peg to Right Peg
Move the plate from Middle Peg to Right Peg
Move the plate from Left Peg to Middle Peg
Move the plate from Right Peg to Left Peg
Move the plate from Right Peg to Middle Peg
Move the plate from Left Peg to Middle Peg

Press ENTER to exit.


## Python

### Recursive

def hanoi(ndisks, startPeg=1, endPeg=3):    if ndisks:        hanoi(ndisks-1, startPeg, 6-startPeg-endPeg)        print "Move disk %d from peg %d to peg %d" % (ndisks, startPeg, endPeg)        hanoi(ndisks-1, 6-startPeg-endPeg, endPeg) hanoi(ndisks=4)
Output:
for ndisks=2
Move disk 1 from peg 1 to peg 2
Move disk 2 from peg 1 to peg 3
Move disk 1 from peg 2 to peg 3


Or, separating the definition of the data from its display:

Works with: Python version 3.7
'''Towers of Hanoi'''  # hanoi :: Int -> String -> String -> String -> [(String, String)]def hanoi(n):    '''A list of (from, to) label pairs,       where a, b and c are labels for each of the       three Hanoi tower positions.'''    def go(n, a, b, c):        p = n - 1        return (            go(p, a, c, b) + [(a, b)] + go(p, c, b, a)        ) if 0 < n else []    return lambda a: lambda b: lambda c: go(n, a, b, c)  # TEST ----------------------------------------------------if __name__ == '__main__':     # fromTo :: (String, String) -> String    def fromTo(xy):        '''x -> y'''        x, y = xy        return x.rjust(5, ' ') + ' -> ' + y     print(__doc__ + ':\n\n' + '\n'.join(        map(fromTo, hanoi(4)('left')('right')('mid'))    ))
Output:
Towers of Hanoi:

left -> mid
left -> right
mid -> right
left -> mid
right -> left
right -> mid
left -> mid
left -> right
mid -> right
mid -> left
right -> left
mid -> right
left -> mid
left -> right
mid -> right

### Graphic

Refactoring the version above to recursively generate a simple visualisation:

Works with: Python version 3.7
'''Towers of Hanoi''' from itertools import accumulate, chain, repeatfrom inspect import signatureimport operator  # hanoi :: Int -> [(Int, Int)]def hanoi(n):    '''A list of index pairs, representing disk moves       between indexed Hanoi positions.    '''    def go(n, a, b, c):        p = n - 1        return (            go(p, a, c, b) + [(a, b)] + go(p, c, b, a)        ) if 0 < n else []    return go(n, 0, 2, 1)  # hanoiState :: ([Int],[Int],[Int], String) -> (Int, Int) ->#               ([Int],[Int],[Int], String)def hanoiState(tpl, ab):    '''A new Hanoi tower state'''    a, b = ab    xs, ys = tpl[a], tpl[b]     w = 3 * (2 + (2 * max(map(max, filter(len, tpl[:-1])))))     def delta(i):        return tpl[i] if i not in ab else xs[1:] if (            i == a        ) else [xs] + ys     tkns = moveName(('left', 'mid', 'right'))(ab)    caption = ' '.join(tkns)    return tuple(map(delta, [0, 1, 2])) + (        (caption if tkns != 'mid' else caption.rjust(w, ' ')),    )  # showHanoi :: ([Int],[Int],[Int], String) -> Stringdef showHanoi(tpl):    '''Captioned string representation of an updated Hanoi tower state.'''     def fullHeight(n):        return lambda xs: list(repeat('', n - len(xs))) + xs     mul = curry(operator.mul)    lt = curry(operator.lt)    rods = fmap(fmap(mul('__')))(        list(tpl[0:3])    )    h = max(map(len, rods))    w = 2 + max(        map(            compose(max)(fmap(len)),            filter(compose(lt(0))(len), rods)        )    )    xs = fmap(concat)(        transpose(fmap(            compose(fmap(center(w)(' ')))(                fullHeight(h)            )        )(rods))    )    return tpl + '\n\n' + unlines(xs) + '\n' + ('___' * w)  # moveName :: (String, String, String) -> (Int, Int) -> [String]def moveName(labels):    '''(from, to) index pair represented as an a -> b string.'''    def go(ab):        a, b = ab        return [labels[a], ' to ', labels[b]] if a < b else [            labels[b], ' from ', labels[a]        ]    return lambda ab: go(ab)  # TEST ----------------------------------------------------def main():    '''Visualisation of a Hanoi tower sequence for N discs.    '''    n = 3    print('Hanoi sequence for ' + str(n) + ' disks:\n')    print(unlines(        fmap(showHanoi)(            scanl(hanoiState)(                (enumFromTo(1)(n), [], [], '')            )(hanoi(n))        )    ))  # GENERIC ------------------------------------------------- # center :: Int -> Char -> String -> Stringdef center(n):    '''String s padded with c to approximate centre,       fitting in but not truncated to width n.'''    return lambda c: lambda s: s.center(n, c)  # compose (<<<) :: (b -> c) -> (a -> b) -> a -> cdef compose(g):    '''Right to left function composition.'''    return lambda f: lambda x: g(f(x))  # concat :: [[a]] -> [a]# concat :: [String] -> Stringdef concat(xs):    '''The concatenation of all the elements       in a list or iterable.'''     def f(ys):        zs = list(chain(*ys))        return ''.join(zs) if isinstance(ys, str) else zs     return (        f(xs) if isinstance(xs, list) else (            chain.from_iterable(xs)        )    ) if xs else []  # curry :: ((a, b) -> c) -> a -> b -> cdef curry(f):    '''A curried function derived       from an uncurried function.'''    if 1 < len(signature(f).parameters):        return lambda x: lambda y: f(x, y)    else:        return f  # enumFromTo :: (Int, Int) -> [Int]def enumFromTo(m):    '''Integer enumeration from m to n.'''    return lambda n: list(range(m, 1 + n))  # fmap :: (a -> b) -> [a] -> [b]def fmap(f):    '''fmap over a list.       f lifted to a function over a list.    '''    return lambda xs: list(map(f, xs))  # scanl :: (b -> a -> b) -> b -> [a] -> [b]def scanl(f):    '''scanl is like reduce, but returns a succession of       intermediate values, building from the left.    '''    return lambda a: lambda xs: (        accumulate(chain([a], xs), f)    )  # showLog :: a -> IO Stringdef showLog(*s):    '''Arguments printed with       intercalated arrows.'''    print(        ' -> '.join(map(str, s))    )  # transpose :: Matrix a -> Matrix adef transpose(m):    '''The rows and columns of the argument transposed.       (The matrix containers and rows can be lists or tuples).    '''    if m:        inner = type(m)        z = zip(*m)        return (type(m))(            map(inner, z) if tuple != inner else z        )    else:        return m  # unlines :: [String] -> Stringdef unlines(xs):    '''A single string derived by the intercalation       of a list of strings with the newline character.    '''    return '\n'.join(xs)  # TEST ----------------------------------------------------if __name__ == '__main__':    main()
Hanoi sequence for 3 disks:

__
____
______
________________________
left  to  right

____
______            __
________________________
left  to  mid

______   ____     __
________________________
mid  from  right

__
______   ____
________________________
left  to  right

__
____   ______
________________________
left  from  mid

__     ____   ______
________________________
mid  to  right

____
__            ______
________________________
left  to  right

__
____
______
________________________

### Library: VPython

There is a 3D hanoi-game in the examples that come with VPython, and at github.

## Quite BASIC

'This is implemented on the Quite BASIC website
'http://www.quitebasic.com/prj/puzzle/towers-of-hanoi/

1000 REM Towers of Hanoi1010 REM Quite BASIC Puzzle Project1020 CLS1030 PRINT "Towers of Hanoi"1040 PRINT1050 PRINT "This is a recursive solution for seven discs."1060 PRINT1070 PRINT "See the REM statements in the program if you didn't think that recursion was possible in classic BASIC!"1080 REM Yep, recursive GOSUB calls works in Quite BASIC!  1090 REM However, to actually write useful recursive algorithms, it helps to have variable scoping and parameters to subroutines -- something classic BASIC is lacking.  In this case we have only one "parameter" -- the variable N.  And subroutines are always called with N-1.  This is lucky for us because we can keep track of the value by decrementing it when we enter subroutines and incrementing it back when we exit.1100 REM If we had subroutine parameters we could have written a single subroutine for moving discs from peg P to peg Q where P and Q were subroutine parameters, but no such luck.  Instead we have to write six different subroutines for moving from peg to peg.  See Subroutines 4000, 5000, 6000, 7000, 8000, and 9000.1110 REM ===============================2000 REM A, B, and C are arrays holding the discs2010 REM We refer to the corresponding pegs as peg A, B, and C2020 ARRAY A2030 ARRAY B2040 ARRAY C2050 REM Fill peg A with seven discs2060 FOR I = 0 TO 62070 LET A[I] = 7 - I2080 NEXT I2090 REM X, Y, Z hold the number of discs on pegs A, B, and C2100 LET X = 72110 LET Y = 02120 LET Z = 02130 REM Disc colors2140 ARRAY P2150 LET P = "cyan"2160 LET P = "blue"2170 LET P = "green"2180 LET P = "yellow"2190 LET P = "magenta"2200 LET P = "orange"2210 LET P = "red"2220 REM Draw initial position -- all discs on the A peg2230 FOR I = 0 TO 62240 FOR J = 8 - A[I] TO 8 + A[I]2250 PLOT J, I, P[A[I]]2260 NEXT J2270 NEXT I 2280 REM N is the number of discs to move2290 LET N = 72320 REM Move all discs from peg A to peg B2310 GOSUB 60002320 END3000 REM The subroutines 3400, 3500, 3600, 3700, 3800, 3900 3010 REM handle the drawing of the discs on the canvas as we3020 REM move discs from one peg to another.3030 REM These subroutines also update the variables X, Y, and Z3040 REM which hold the number of discs on each peg.3050 REM ============================== 3400 REM Subroutine -- Remove disc from peg A3410 LET X = X - 13420 FOR I = 8 - A[X] TO 8 + A[X]3430 PLOT I, X, "gray"3440 NEXT I3450 RETURN3500 REM Subroutine -- Add disc to peg A3510 FOR I = 8 - A[X] TO 8 + A[X]3520 PLOT I, X, P[A[X]]3530 NEXT I3540 LET X = X + 13550 PAUSE 400 * (5 - LEVEL) + 10 3560 RETURN3600 REM Subroutine -- Remove disc from peg B3610 LET Y = Y - 13620 FOR I = 24 - B[Y] TO 24 + B[Y]3630 PLOT I, Y, "gray"3640 NEXT I3650 RETURN3700 REM Subroutine -- Add disc to peg B3710 FOR I = 24 - B[Y] TO 24 + B[Y]3720 PLOT I, Y, P[B[Y]]3730 NEXT I3740 LET Y = Y + 13750 PAUSE 400 * (5 - LEVEL) + 10 3760 RETURN3800 REM Subroutine -- Remove disc from peg C3810 LET Z = Z - 13820 FOR I = 40 - C[Z] TO 40 + C[Z]3830 PLOT I, Z, "gray"3840 NEXT I3850 RETURN3900 REM Subroutine -- Add disc to peg C3910 FOR I = 40 - C[Z] TO 40 + C[Z]3920 PLOT I, Z, P[C[Z]]3930 NEXT I3940 LET Z = Z + 13950 PAUSE 400 * (5 - LEVEL) + 10 3960 RETURN4000 REM ======================================4010 REM Recursive Subroutine -- move N discs from peg B to peg A4020 REM First move N-1 discs from peg B to peg C4030 LET N = N - 14040 IF N <> 0 THEN GOSUB 90004050 REM Then move one disc from peg B to peg A 4060 GOSUB 36004070 LET A[X] = B[Y]4080 GOSUB 35004090 REM And finally move N-1 discs from peg C to peg A4100 IF N <> 0 THEN GOSUB 50004110 REM Restore N before returning4120 LET N = N + 14130 RETURN5000 REM ======================================5010 REM Recursive Subroutine -- Move N discs from peg C to peg A5020 REM First move N-1 discs from peg C to peg B5030 LET N = N - 15040 IF N <> 0 THEN GOSUB 80005050 REM Then move one disc from peg C to peg A5060 GOSUB 38005070 LET A[X] = C[Z]5080 GOSUB 35005090 REM And finally move N-1 discs from peg B to peg A5100 IF N <> 0 THEN GOSUB 40005120 REM Restore N before returning5130 LET N = N + 15140 RETURN6000 REM ======================================6000 REM Recursive Subroutine -- Move N discs from peg A to peg B6010 REM First move N-1 discs from peg A to peg C6020 LET N = N - 16030 IF N <> 0 THEN GOSUB 70006040 REM Then move one disc from peg A to peg B6050 GOSUB 34006060 LET B[Y] = A[X]6070 GOSUB 37006090 REM And finally move N-1 discs from peg C to peg B6100 IF N <> 0 THEN GOSUB 80006110 REM Restore N before returning6120 LET N = N + 16130 RETURN7000 REM ======================================7010 REM Recursive Subroutine -- Move N discs from peg A to peg C7020 REM First move N-1 discs from peg A to peg B7030 LET N = N - 17040 IF N <> 0 THEN GOSUB 60007050 REM Then move one disc from peg A to peg C7060 GOSUB 34007070 LET C[Z] = A[X]7080 GOSUB 39007090 REM And finally move N-1 discs from peg B to peg C7100 IF N <> 0 THEN GOSUB 90007110 REM Restore N before returning7120 LET N = N + 17130 RETURN8000 REM ======================================8010 REM Recursive Subroutine -- Move N discs from peg C to peg B8020 REM First move N-1 discs from peg C to peg A8030 LET N = N - 18040 IF N <> 0 THEN GOSUB 50008050 REM Then move one disc from peg C to peg B8060 GOSUB 38008070 LET B[Y] = C[Z]8080 GOSUB 37008090 REM And finally move N-1 discs from peg A to peg B8100 IF N <> 0 THEN GOSUB 60008110 REM Restore N before returning8120 LET N = N + 18130 RETURN9000 REM ======================================9010 REM Recursive Subroutine -- Move N discs from peg B to peg C9020 REM First move N-1 discs from peg B to peg A9030 LET N = N - 19040 IF N <> 0 THEN GOSUB 40009050 REM Then move one disc from peg B to peg C9060 GOSUB 36009070 LET C[Z] = B[Y]9080 GOSUB 39009090 REM And finally move N-1 discs from peg A to peg C9100 IF N <> 0 THEN GOSUB 70009110 REM Restore N before returning9120 LET N = N + 19130 RETURN

## R

Translation of: Octave
hanoimove <- function(ndisks, from, to, via) {  if (ndisks == 1) {    cat("move disk from", from, "to", to, "\n")  } else {    hanoimove(ndisks - 1, from, via, to)    hanoimove(1, from, to, via)    hanoimove(ndisks - 1, via, to, from)  }} hanoimove(4, 1, 2, 3)

## Racket

 #lang racket(define (hanoi n a b c)  (when (> n 0)    (hanoi (- n 1) a c b)    (printf "Move ~a to ~a\n" a b)    (hanoi (- n 1) c b a)))(hanoi 4 'left 'middle 'right) 

## Raku

(formerly Perl 6)

subset Peg of Int where 1|2|3; multi hanoi (0,      Peg $a, Peg$b,     Peg $c) { }multi hanoi (Int$n, Peg $a = 1, Peg$b = 2, Peg $c = 3) { hanoi$n - 1, $a,$c, $b; say "Move$a to $b."; hanoi$n - 1, $c,$b, $a;} ## Rascal Translation of: Python public void hanoi(ndisks, startPeg, endPeg){ if(ndisks>0){ hanoi(ndisks-1, startPeg, 6 - startPeg - endPeg); println("Move disk <ndisks> from peg <startPeg> to peg <endPeg>"); hanoi(ndisks-1, 6 - startPeg - endPeg, endPeg); }} Output: rascal>hanoi(4,1,3)Move disk 1 from peg 1 to peg 2Move disk 2 from peg 1 to peg 3Move disk 1 from peg 2 to peg 3Move disk 3 from peg 1 to peg 2Move disk 1 from peg 3 to peg 1Move disk 2 from peg 3 to peg 2Move disk 1 from peg 1 to peg 2Move disk 4 from peg 1 to peg 3Move disk 1 from peg 2 to peg 3Move disk 2 from peg 2 to peg 1Move disk 1 from peg 3 to peg 1Move disk 3 from peg 2 to peg 3Move disk 1 from peg 1 to peg 2Move disk 2 from peg 1 to peg 3Move disk 1 from peg 2 to peg 3ok ## Raven Translation of: Python define hanoi use ndisks, startpeg, endpeg ndisks 0 > if 6 startpeg - endpeg - startpeg ndisks 1 - hanoi endpeg startpeg ndisks "Move disk %d from peg %d to peg %d\n" print endpeg 6 startpeg - endpeg - ndisks 1 - hanoi define dohanoi use ndisks # startpeg=1, endpeg=3 3 1 ndisks hanoi # 4 disks4 dohanoi  Output: raven hanoi.rv Move disk 1 from peg 1 to peg 2 Move disk 2 from peg 1 to peg 3 Move disk 1 from peg 2 to peg 3 Move disk 3 from peg 1 to peg 2 Move disk 1 from peg 3 to peg 1 Move disk 2 from peg 3 to peg 2 Move disk 1 from peg 1 to peg 2 Move disk 4 from peg 1 to peg 3 Move disk 1 from peg 2 to peg 3 Move disk 2 from peg 2 to peg 1 Move disk 1 from peg 3 to peg 1 Move disk 3 from peg 2 to peg 3 Move disk 1 from peg 1 to peg 2 Move disk 2 from peg 1 to peg 3 Move disk 1 from peg 2 to peg 3  ## REBOL rebol [ Title: "Towers of Hanoi" URL: http://rosettacode.org/wiki/Towers_of_Hanoi] hanoi: func [ {Begin moving the golden disks from one pole to the next. Note: when last disk moved, the world will end.} disks [integer!] "Number of discs on starting pole." /poles "Name poles." from to via][ if disks = 0 [return] if not poles [from: 'left to: 'middle via: 'right] hanoi/poles disks - 1 from via to print [from "->" to] hanoi/poles disks - 1 via to from] hanoi 4 Output: left -> right left -> middle right -> middle left -> right middle -> left middle -> right left -> right left -> middle right -> middle right -> left middle -> left right -> middle left -> right left -> middle right -> middle ## Retro ~~~{ 'Num 'From 'To 'Via } [ var ] a:for-each :set !Via !To !From !Num ; :display @To @From 'Move_a_ring_from_%n_to_%n\n s:format s:put ; :hanoi (num,from,to,via-) set @Num n:-zero? [ @Num @From @To @Via @Num n:dec @From @Via @To hanoi set display @Num n:dec @Via @To @From hanoi ] if ; #3 #1 #3 #2 hanoi nl ~~~ ## REXX ### simple text moves /*REXX program displays the moves to solve the Tower of Hanoi (with N disks). */parse arg N . /*get optional number of disks from CL.*/if N=='' | N=="," then N=3 /*Not specified? Then use the default.*/#= 0 /*#: the number of disk moves (so far)*/z= 2**N - 1 /*Z: " " " minimum # of moves.*/call mov 1, 3, N /*move the top disk, then recurse ··· */say /* [↓] Display the minimum # of moves.*/say 'The minimum number of moves to solve a ' N"─disk Tower of Hanoi is " zexit /*stick a fork in it, we're all done. *//*──────────────────────────────────────────────────────────────────────────────────────*/mov: procedure expose # z; parse arg @1,@2,@3; L= length(z) if @3==1 then do; #= # + 1 /*bump the (disk) move counter by one. */ say 'step' right(#, L)": move disk on tower" @1 '───►' @2 end else do; call mov @1, 6 [email protected] [email protected], @3 -1 call mov @1, @2, 1 call mov 6 - @1 - @2, @2, @3 -1 end return /* [↑] this subroutine uses recursion.*/ output when using the default input: step 1: move disk on tower 1 ───► 3 step 2: move disk on tower 1 ───► 2 step 3: move disk on tower 3 ───► 2 step 4: move disk on tower 1 ───► 3 step 5: move disk on tower 2 ───► 1 step 6: move disk on tower 2 ───► 3 step 7: move disk on tower 1 ───► 3 The minimum number of moves to solve a 3-disk Tower of Hanoi is 7  output when the following was entered (to solve with four disks): 4 step 1: move disk on tower 1 ───► 2 step 2: move disk on tower 1 ───► 3 step 3: move disk on tower 2 ───► 3 step 4: move disk on tower 1 ───► 2 step 5: move disk on tower 3 ───► 1 step 6: move disk on tower 3 ───► 2 step 7: move disk on tower 1 ───► 2 step 8: move disk on tower 1 ───► 3 step 9: move disk on tower 2 ───► 3 step 10: move disk on tower 2 ───► 1 step 11: move disk on tower 3 ───► 1 step 12: move disk on tower 2 ───► 3 step 13: move disk on tower 1 ───► 2 step 14: move disk on tower 1 ───► 3 step 15: move disk on tower 2 ───► 3 The minimum number of moves to solve a 4-disk Tower of Hanoi is 15  ### pictorial moves This REXX version pictorially shows (via ASCII art) the moves for solving the Town of Hanoi. Quite a bit of code has been dedicated to showing a "picture" of the towers with the disks, and the movement of the disk (for each move). "Coloring" of the disks is attempted with dithering. In addition, it shows each move in a countdown manner (the last move is marked as #1). It may not be obvious from the pictorial display of the moves, but whenever a disk is moved from one tower to another, it is always the top disk that is moved (to the target tower). 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. /*REXX program displays the moves to solve the Tower of Hanoi (with N disks). */parse arg N . /*get optional number of disks from CL.*/if N=='' | N=="," then N=3 /*Not specified? Then use the default.*/sw= 80; wp= sw%3 - 1; blanks= left('', wp) /*define some default REXX variables. */c.1= sw % 3 % 2 /* [↑] SW: assume default Screen Width*/c.2= sw % 2 - 1 /* ◄─── C.1 C.2 C.2 are the positions*/c.3= sw - 2 - c.1 /* of the 3 columns.*/#= 0; z= 2**N - 1; moveK= z /*#moves; min# of moves; where to move.*/@abc= 'abcdefghijklmnopqrstuvwxyN' /*dithering chars when many disks used.*/ebcdic= ('f2'x==2) /*determine if EBCDIC or ASCII machine.*/ if ebcdic then do; bar= 'bf'x; ar= "df"x; dither= 'db9f9caf'x; down= "9a"x tr= 'bc'x; bl= "ab"x; br= 'bb'x; vert= "fa"x; tl= 'ac'x end else do; bar= 'c4'x; ar= "10"x; dither= 'b0b1b2db'x; down= "19"x tr= 'bf'x; bl= "c0"x; br= 'd9'x; vert= "b3"x; tl= 'da'x end verts= vert || vert; Tcorners= tl || tr; box = left(dither, 1)downs= down || down; Bcorners= bl || br; boxChars= dither || @abc$.= 0;         $.1= N; k= N; kk= k + k do j=1 for N; @.3.j= blanks; @.2.j= blanks; @.1.j= center( copies(box, kk), wp) if N<=length(boxChars) then @.1.j= translate( @.1.j, , substr( boxChars, kk%2, 1), box) kk= kk - 2 end /*j*/ /*populate the tower of Hanoi spindles.*/ call showTowers; call mov 1,3,N; saysay 'The minimum number of moves to solve a ' N"-disk Tower of Hanoi is " zexit /*stick a fork in it, we're all done. *//*──────────────────────────────────────────────────────────────────────────────────────*/dsk: parse arg from dest; #= # + 1; pp= if from==1 then do; pp= overlay(bl, pp, c.1) pp= overlay(bar, pp, c.1+1, c.dest-c.1-1, bar) || tr end if from==2 then do if dest==1 then do; pp= overlay(tl, pp, c.1) pp= overlay(bar, pp, c.1+1, c.2-c.1-1,bar)||br end if dest==3 then do; pp= overlay(bl, pp, c.2) pp= overlay(bar, pp, c.2+1, c.3-c.2-1,bar)||tr end end if from==3 then do; pp= overlay(br, pp, c.3) pp= overlay(bar, pp, c.dest+1, c.3-c.dest-1, bar) pp= overlay(tl, pp, c.dest) end say translate(pp, downs, Bcorners || Tcorners || bar); say overlay(moveK, pp, 1) say translate(pp, verts, Tcorners || Bcorners || bar) say translate(pp, downs, Tcorners || Bcorners || bar); moveK= moveK - 1$.from= $.from - 1;$.dest= $.dest + 1; _f=$.from + 1;           _t= $.dest @.dest._t= @.from._f; @.from._f= blanks; call showTowers return/*──────────────────────────────────────────────────────────────────────────────────────*/mov: if arg(3)==1 then call dsk arg(1) arg(2) else do; call mov arg(1), 6 -arg(1) -arg(2), arg(3) -1 call mov arg(1), arg(2), 1 call mov 6 -arg(1) -arg(2), arg(2), arg(3) -1 end /* [↑] The MOV subroutine is recursive, */ return /*it uses no variables, is uses BIFs instead*//*──────────────────────────────────────────────────────────────────────────────────────*/showTowers: do j=N by -1 for N; [email protected].1.j @.2.j @.3.j; if _\='' then say _; end; return output when using the default input:  ░░ ▒▒▒▒ ▓▓▓▓▓▓ ↓ 7 └───────────────────────────────────────────────────┐ │ ↓ ▒▒▒▒ ▓▓▓▓▓▓ ░░ ↓ 6 └─────────────────────────┐ │ ↓ ▓▓▓▓▓▓ ▒▒▒▒ ░░ ↓ 5 ┌─────────────────────────┘ │ ↓ ░░ ▓▓▓▓▓▓ ▒▒▒▒ ↓ 4 └───────────────────────────────────────────────────┐ │ ↓ ░░ ▒▒▒▒ ▓▓▓▓▓▓ ↓ 3 ┌─────────────────────────┘ │ ↓ ░░ ▒▒▒▒ ▓▓▓▓▓▓ ↓ 2 └─────────────────────────┐ │ ↓ ▒▒▒▒ ░░ ▓▓▓▓▓▓ ↓ 1 └───────────────────────────────────────────────────┐ │ ↓ ░░ ▒▒▒▒ ▓▓▓▓▓▓ The minimum number of moves to solve a 3-disk Tower of Hanoi is 7  ## Ring  move(4, 1, 2, 3) func move n, src, dst, via if n > 0 move(n - 1, src, via, dst) see "" + src + " to " + dst + nl move(n - 1, via, dst, src) ok  ## Ruby ### version 1 def move(num_disks, start=0, target=1, using=2) if num_disks == 1 @towers[target] << @towers[start].pop puts "Move disk from #{start} to #{target} : #{@towers}" else move(num_disks-1, start, using, target) move(1, start, target, using) move(num_disks-1, using, target, start) end end n = 5@towers = [[*1..n].reverse, [], []]move(n) Output: Move disk from 0 to 1 : [[5, 4, 3, 2], , []] Move disk from 0 to 2 : [[5, 4, 3], , ] Move disk from 1 to 2 : [[5, 4, 3], [], [2, 1]] Move disk from 0 to 1 : [[5, 4], , [2, 1]] Move disk from 2 to 0 : [[5, 4, 1], , ] Move disk from 2 to 1 : [[5, 4, 1], [3, 2], []] Move disk from 0 to 1 : [[5, 4], [3, 2, 1], []] Move disk from 0 to 2 : [, [3, 2, 1], ] Move disk from 1 to 2 : [, [3, 2], [4, 1]] Move disk from 1 to 0 : [[5, 2], , [4, 1]] Move disk from 2 to 0 : [[5, 2, 1], , ] Move disk from 1 to 2 : [[5, 2, 1], [], [4, 3]] Move disk from 0 to 1 : [[5, 2], , [4, 3]] Move disk from 0 to 2 : [, , [4, 3, 2]] Move disk from 1 to 2 : [, [], [4, 3, 2, 1]] Move disk from 0 to 1 : [[], , [4, 3, 2, 1]] Move disk from 2 to 0 : [, , [4, 3, 2]] Move disk from 2 to 1 : [, [5, 2], [4, 3]] Move disk from 0 to 1 : [[], [5, 2, 1], [4, 3]] Move disk from 2 to 0 : [, [5, 2, 1], ] Move disk from 1 to 2 : [, [5, 2], [4, 1]] Move disk from 1 to 0 : [[3, 2], , [4, 1]] Move disk from 2 to 0 : [[3, 2, 1], , ] Move disk from 2 to 1 : [[3, 2, 1], [5, 4], []] Move disk from 0 to 1 : [[3, 2], [5, 4, 1], []] Move disk from 0 to 2 : [, [5, 4, 1], ] Move disk from 1 to 2 : [, [5, 4], [2, 1]] Move disk from 0 to 1 : [[], [5, 4, 3], [2, 1]] Move disk from 2 to 0 : [, [5, 4, 3], ] Move disk from 2 to 1 : [, [5, 4, 3, 2], []] Move disk from 0 to 1 : [[], [5, 4, 3, 2, 1], []]  ### version 2 # solve(source, via, target)# Example:# solve([5, 4, 3, 2, 1], [], [])# Note this will also solve randomly placed disks,# "place all disk in target with legal moves only".def solve(*towers) # total number of disks disks = towers.inject(0){|sum, tower| sum+tower.length} x=0 # sequence number p towers # initial trace # have we solved the puzzle yet? while towers.last.length < disks do x+=1 # assume the next step from = (x&x-1)%3 to = ((x|(x-1))+1)%3 # can we actually take from tower? if top = towers[from].last bottom = towers[to].last # is the move legal? if !bottom || bottom > top # ok, do it! towers[to].push(towers[from].pop) p towers # trace end end endend solve([5, 4, 3, 2, 1], [], []) Output: [[5, 4, 3, 2, 1], [], []] [[5, 4, 3, 2], [], ] [[5, 4, 3], , ] [[5, 4, 3], [2, 1], []] [[5, 4], [2, 1], ] [[5, 4, 1], , ] [[5, 4, 1], [], [3, 2]] [[5, 4], [], [3, 2, 1]] [, , [3, 2, 1]] [, [4, 1], [3, 2]] [[5, 2], [4, 1], ] [[5, 2, 1], , ] [[5, 2, 1], [4, 3], []] [[5, 2], [4, 3], ] [, [4, 3, 2], ] [, [4, 3, 2, 1], []] [[], [4, 3, 2, 1], ] [, [4, 3, 2], ] [, [4, 3], [5, 2]] [[], [4, 3], [5, 2, 1]] [, , [5, 2, 1]] [, [4, 1], [5, 2]] [[3, 2], [4, 1], ] [[3, 2, 1], , ] [[3, 2, 1], [], [5, 4]] [[3, 2], [], [5, 4, 1]] [, , [5, 4, 1]] [, [2, 1], [5, 4]] [[], [2, 1], [5, 4, 3]] [, , [5, 4, 3]] [, [], [5, 4, 3, 2]] [[], [], [5, 4, 3, 2, 1]]  ## Run BASIC a = move(4, "1", "2", "3")function move(n, a$, b$, c$) if n > 0 then	a = move(n-1, a$, c$, b$) print "Move disk from " ; a$ ; " to " ; c$a = move(n-1, b$, a$, c$)end ifend function
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

## Rust

Translation of: C
fn move_(n: i32, from: i32, to: i32, via: i32) {    if n > 0 {        move_(n - 1, from, via, to);        println!("Move disk from pole {} to pole {}", from, to);        move_(n - 1, via, to, from);    }} fn main() {    move_(4, 1,2,3);}

## SASL

Copied from SAL manual, Appendix II, answer (3)

hanoi 8 ‘abc"WHEREhanoi 0 (a,b,c,) = ()hanoi n ( a,b,c) = hanoi (n-1) (a,c,b) ,                   ‘move a disc from " , a , ‘ to " , b , NL ,                   hanoi (n-1) (c,b,a)?

## Sather

Translation of: Fortran
class MAIN is   move(ndisks, from, to, via:INT) is    if ndisks = 1 then      #OUT + "Move disk from pole " + from + " to pole " + to + "\n";    else      move(ndisks-1, from, via, to);      move(1, from, to, via);      move(ndisks-1, via, to, from);    end;  end;   main is    move(4, 1, 2, 3);  end;end;

## Scala

def move(n: Int, from: Int, to: Int, via: Int) : Unit = {    if (n == 1) {      Console.println("Move disk from pole " + from + " to pole " + to)    } else {      move(n - 1, from, via, to)      move(1, from, to, via)      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

object TowersOfHanoi {  import scala.reflect.Manifest   def simpleName(m:Manifest[_]):String = {    val name = m.toString    name.substring(name.lastIndexOf('$')+1) } trait Nat final class _0 extends Nat final class Succ[Pre<:Nat] extends Nat type _1 = Succ[_0] type _2 = Succ[_1] type _3 = Succ[_2] type _4 = Succ[_3] case class Move[N<:Nat,A,B,C]() implicit def move0[A,B,C](implicit a:Manifest[A],b:Manifest[B]):Move[_0,A,B,C] = { System.out.println("Move from "+simpleName(a)+" to "+simpleName(b));null } implicit def moveN[P<:Nat,A,B,C](implicit m1:Move[P,A,C,B],m2:Move[_0,A,B,C],m3:Move[P,C,B,A]) :Move[Succ[P],A,B,C] = null def run[N<:Nat,A,B,C](implicit m:Move[N,A,B,C]) = null case class Left() case class Center() case class Right() def main(args:Array[String]){ run[_2,Left,Right,Center] }} ## Scheme Recursive Process (define (towers-of-hanoi n from to spare) (define (print-move from to) (display "Move[") (display from) (display ", ") (display to) (display "]") (newline)) (cond ((= n 0) "done") (else (towers-of-hanoi (- n 1) from spare to) (print-move from to) (towers-of-hanoi (- n 1) spare to from)))) (towers-of-hanoi 3 "A" "B" "C") Output: Move[A, B] Move[A, C] Move[B, C] Move[A, B] Move[C, A] Move[C, B] Move[A, B] "done" ## Seed7 const proc: hanoi (in integer: disk, in string: source, in string: dest, in string: via) is func begin if disk > 0 then hanoi(pred(disk), source, via, dest); writeln("Move disk " <& disk <& " from " <& source <& " to " <& dest); hanoi(pred(disk), via, dest, source); end if; end func; ## Sidef Translation of: Perl func hanoi(n, from=1, to=2, via=3) { if (n == 1) { say "Move disk from pole #{from} to pole #{to}."; } else { hanoi(n-1, from, via, to); hanoi( 1, from, to, via); hanoi(n-1, via, to, from); }} hanoi(4); ## SNOBOL4 * # Note: count is global define('hanoi(n,src,trg,tmp)') :(hanoi_end)hanoi hanoi = eq(n,0) 1 :s(return) hanoi(n - 1, src, tmp, trg) count = count + 1 output = count ': Move disc from ' src ' to ' trg hanoi(n - 1, tmp, trg, src) :(return)hanoi_end * # Test with 4 discs hanoi(4,'A','C','B')end Output: 1: Move disc from A to B 2: Move disc from A to C 3: Move disc from B to C 4: Move disc from A to B 5: Move disc from C to A 6: Move disc from C to B 7: Move disc from A to B 8: Move disc from A to C 9: Move disc from B to C 10: Move disc from B to A 11: Move disc from C to A 12: Move disc from B to C 13: Move disc from A to B 14: Move disc from A to C 15: Move disc from B to C ## Standard ML  fun hanoi(0, a, b, c) = [] | hanoi(n, a, b, c) = hanoi(n-1, a, c, b) @ [(a,b)] @ hanoi(n-1, c, b, a);  ## Stata function hanoi(n, a, b, c) { if (n>0) { hanoi(n-1, a, c, b) printf("Move from %f to %f\n", a, b) hanoi(n-1, c, b, a) }} hanoi(3, 1, 2, 3) Move from 1 to 2Move from 1 to 3Move from 2 to 3Move from 1 to 2Move from 3 to 1Move from 3 to 2Move from 1 to 2 ## Swift Translation of: JavaScript func hanoi(n:Int, 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) }} hanoi(4, "A", "B", "C") Swift 2.1 func hanoi(n:Int, a:String, b:String, c:String) { if (n > 0) { hanoi(n - 1, a: a, b: c, c: b) print("Move disk from \(a) to \(c)") hanoi(n - 1, a: b, b: a, c: c) }} hanoi(4, a:"A", b:"B", c:"C") ## Tcl The use of interp alias shown is a sort of closure: keep track of the number of moves required interp alias {} hanoi {} do_hanoi 0 proc do_hanoi {count n {from A} {to C} {via B}} { if {$n == 1} {        interp alias {} hanoi {} do_hanoi [incr count]        puts "$count: move from$from to $to" } else { incr n -1 hanoi$n $from$via $to hanoi 1$from $to$via        hanoi $n$via $to$from    }} hanoi 4
Output:
1: move from A to B
2: move from A to C
3: move from B to C
4: move from A to B
5: move from C to A
6: move from C to B
7: move from A to B
8: move from A to C
9: move from B to C
10: move from B to A
11: move from C to A
12: move from B to C
13: move from A to B
14: move from A to C
15: move from B to C

## TI-83 BASIC

TI-83 BASIC lacks recursion, so technically this task is impossible, however here is a version that uses an iterative method.

PROGRAM:TOHSOLVE0→A1→B0→C0→D0→M1→RWhile A<1 or A>7Input "No. of rings=?",AEndrandM(A+1,3)→[C][[1,2][1,3][2,3]]→[E] Fill(0,[C])For(I,1,A,1)I?[C](I,1)EndClrHomeWhile [C](1,3)≠1 and [C](1,2)≠1 For(J,1,3)For(I,1,A)If [C](I,J)≠0:ThenOutput(I+1,3J,[C](I,J))EndEndEndWhile C=0Output(1,3B," ")1→I[E](R,2)→JWhile [C](I,J)=0 and I≤AI+1→IEnd[C](I,J)→D1→I[E](R,1)→JWhile [C](I,J)=0 and I≤AI+1→IEndIf (D<[C](I,J) and D≠0) or [C](I,J)=0:Then[E](R,2)→BElse[E](R,1)→BEnd 1→IWhile [C](I,B)=0 and I≤AI+1→IEndIf I≤A:Then[C](I,B)→C0→[C](I,B)Output(I+1,3B," ")EndOutput(1,3B,"V")End While C≠0Output(1,3B," ")If B=[E](R,2):Then[E](R,1)→BElse[E](R,2)→BEnd 1→IWhile [C](I,B)=0 and I≤AI+1→IEndIf [C](I,B)=0 or [C](I,B)>C:ThenC→[C](I-1,B)0→CM+1→MEndEndOutput(1,3B,"V")R+1→RIf R=4:Then:1→R:End End 

## Toka

value| sa sb sc n |[ to sc to sb to sa to n ] is vars![ ( num from to via -- )  vars!  n 0 <>  [    n sa sb sc     n 1- sa sc sb recurse    vars!    ." Move a ring from " sa . ." to " sb . cr    n 1- sc sb sa recurse  ] ifTrue] is hanoi

## 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 )  RETURN() ENDIF PROCProgramRunTowersofhanoiRecursiveSub( totalDiskI - 1, fromS, viaS, toS, bufferI ) AddLine( Format( "Move disk", " ", totalDiskI, " ", "from peg", " ", "'", fromS, "'", " ", "to peg", " ", "'", toS, "'" ), bufferI ) PROCProgramRunTowersofhanoiRecursiveSub( totalDiskI - 1, viaS, toS, fromS, bufferI )END // library: program: run: towersofhanoi: recursive <description></description> <version>1.0.0.0.6</version> <version control></version control> (filenamemacro=runprtre.s) [kn, ri, tu, 07-02-2012 19:40:45]PROC PROCProgramRunTowersofhanoiRecursive( INTEGER totalDiskI, STRING fromS, STRING toS, STRING viaS ) INTEGER bufferI = 0 PushPosition() bufferI = CreateTempBuffer() PopPosition() PROCProgramRunTowersofhanoiRecursiveSub( totalDiskI, fromS, toS, viaS, bufferI ) GotoBufferId( bufferI )END PROC Main()STRING s1 = "4"IF ( NOT ( Ask( "program: run: towersofhanoi: recursive: totalDiskI = ", s1, _EDIT_HISTORY_ ) ) AND ( Length( s1 ) > 0 ) ) RETURN() ENDIF PROCProgramRunTowersofhanoiRecursive( Val( s1 ), "source", "target", "via" )END

## uBasic/4tH

Translation of: C
Proc  _Move(4, 1,2,3)                  ' 4 disks, 3 polesEnd _Move Param(4)  If ([email protected] > 0) Then    Proc _Move ([email protected] - 1, [email protected], [email protected], [email protected])    Print "Move disk from pole ";[email protected];" to pole ";[email protected]    Proc _Move ([email protected] - 1, [email protected], [email protected], [email protected])  EndIfReturn

## UNIX Shell

Works with: bash
#!/bin/bash move(){  local n="$1" local from="$2"  local to="$3" local via="$4"   if [[ "$n" == "1" ]] then echo "Move disk from pole$from to pole $to" else move$(($n - 1))$from $via$to    move 1 $from$to $via move$(($n - 1))$via $to$from  fi} move $1$2 $3$4

## Ursala

#import nat move = ~&al^& ^rlPlrrPCT/~&arhthPX ^|W/~& ^|G/predecessor ^/~&htxPC ~&zyxPC #show+ main = ^|T(~&,' -> '--)* move/4 <'start','end','middle'>
Output:
start -> middle
start -> end
middle -> end
start -> middle
end -> start
end -> middle
start -> middle
start -> end
middle -> end
middle -> start
end -> start
middle -> end
start -> middle
start -> end
middle -> end

## VBScript

Derived from the BASIC256 version.

Sub Move(n,fromPeg,toPeg,viaPeg)	If n > 0 Then		Move n-1, fromPeg, viaPeg, toPeg		WScript.StdOut.Write "Move disk from " & fromPeg & " to " & toPeg		WScript.StdOut.WriteBlankLines(1)		Move n-1, viaPeg, toPeg, fromPeg	End IfEnd Sub Move 4,1,2,3WScript.StdOut.Write("Towers of Hanoi puzzle completed!")
Output:
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!

## Vedit macro language

This implementation outputs the results in current edit buffer.

#1=1; #2=2; #3=3; #4=4          // move 4 disks from 1 to 2Call("MOVE_DISKS")Return // Move disks// #1 = from, #2 = to, #3 = via, #4 = number of disks//:MOVE_DISKS:if (#4 > 0) {    Num_Push(1,4)        #9=#2; #2=#3; #3=#9; #4--       // #1 to #3 via #2        Call("MOVE_DISKS")    Num_Pop(1,4)     Ins_Text("Move a disk from ")       // move one disk    Num_Ins(#1, LEFT+NOCR)    Ins_Text(" to ")    Num_Ins(#2, LEFT)     Num_Push(1,4)        #9=#1; #1=#3; #3 = #9; #4--     // #3 to #2 via #1        Call("MOVE_DISKS")    Num_Pop(1,4)}Return

## Visual Basic .NET

Module TowersOfHanoi    Sub MoveTowerDisks(ByVal disks As Integer, ByVal fromTower As Integer, ByVal toTower As Integer, ByVal viaTower As Integer)        If disks > 0 Then            MoveTowerDisks(disks - 1, fromTower, viaTower, toTower)            System.Console.WriteLine("Move disk {0} from {1} to {2}", disks, fromTower, toTower)            MoveTowerDisks(disks - 1, viaTower, toTower, fromTower)        End If    End Sub     Sub Main()        MoveTowerDisks(4, 1, 2, 3)    End SubEnd Module

## XPL0

code Text=12; proc MoveTower(Discs, From, To, Using);int  Discs, From, To, Using;[if Discs > 0 then    [MoveTower(Discs-1, From, Using, To);    Text(0, "Move from ");  Text(0, From);    Text(0, " peg to ");  Text(0, To);  Text(0, " peg.^M^J");    MoveTower(Discs-1, Using, To, From);    ];]; MoveTower(3, "left", "right", "center")
Output:
Move from left peg to right peg.
Move from left peg to center peg.
Move from right peg to center peg.
Move from left peg to right peg.
Move from center peg to left peg.
Move from center peg to right peg.
Move from left peg to right peg.


## XQuery

declare function local:hanoi($disk as xs:integer,$from as xs:integer,    $to as xs:integer,$via as xs:integer) as element()* {  if($disk > 0) then ( local:hanoi($disk - 1, $from,$via, $to), <move disk='{$disk}'><from>{$from}</from><to>{$to}</to></move>,    local:hanoi($disk - 1,$via, $to,$from)  )   else ()}; <hanoi>{  local:hanoi(4, 1, 2, 3)}</hanoi>
Output:
<?xml version="1.0" encoding="UTF-8"?><hanoi>   <move disk="1">      <from>1</from>      <to>3</to>   </move>   <move disk="2">      <from>1</from>      <to>2</to>   </move>   <move disk="1">      <from>3</from>      <to>2</to>   </move>   <move disk="3">      <from>1</from>      <to>3</to>   </move>   <move disk="1">      <from>2</from>      <to>1</to>   </move>   <move disk="2">      <from>2</from>      <to>3</to>   </move>   <move disk="1">      <from>1</from>      <to>3</to>   </move>   <move disk="4">      <from>1</from>      <to>2</to>   </move>   <move disk="1">      <from>3</from>      <to>2</to>   </move>   <move disk="2">      <from>3</from>      <to>1</to>   </move>   <move disk="1">      <from>2</from>      <to>1</to>   </move>   <move disk="3">      <from>3</from>      <to>2</to>   </move>   <move disk="1">      <from>1</from>      <to>3</to>   </move>   <move disk="2">      <from>1</from>      <to>2</to>   </move>   <move disk="1">      <from>3</from>      <to>2</to>   </move></hanoi>

## XSLT

<xsl:template name="hanoi"><xsl:param name="n"/><xsl:param name="from">left</xsl:param><xsl:param name="to">middle</xsl:param><xsl:param name="via">right</xsl:param>  <xsl:if test="$n &gt; 0"> <xsl:call-template name="hanoi"> <xsl:with-param name="n" select="$n - 1"/>      <xsl:with-param name="from" select="$from"/> <xsl:with-param name="to" select="$via"/>      <xsl:with-param name="via"  select="$to"/> </xsl:call-template> <fo:block> <xsl:text>Move disk from </xsl:text> <xsl:value-of select="$from"/>      <xsl:text> to </xsl:text>      <xsl:value-of select="$to"/> </fo:block> <xsl:call-template name="hanoi"> <xsl:with-param name="n" select="$n - 1"/>      <xsl:with-param name="from" select="$via"/> <xsl:with-param name="to" select="$to"/>      <xsl:with-param name="via"  select="\$from"/>    </xsl:call-template>  </xsl:if></xsl:template>
<xsl:call-template name="hanoi"><xsl:with-param name="n" select="4"/></xsl:call-template>


## Yabasic

sub hanoi(ndisks, startPeg, endPeg)    if ndisks then        hanoi(ndisks-1, startPeg, 6-startPeg-endPeg)        //print "Move disk ", ndisks, " from ", startPeg, " to ", endPeg        hanoi(ndisks-1, 6-startPeg-endPeg, endPeg)    end ifend sub print "Be patient, please.\n\n"print "Hanoi 1 ellapsed ... "; t1 = peek("millisrunning")hanoi(22, 1, 3)t2 = peek("millisrunning")print t2-t1, " ms"  sub hanoi2(n, from, to_, via)    if n = 1 then	//print "Move from ", from, " to ", to_    else	hanoi2(n - 1, from, via , to_ )    	hanoi2(1    , from, to_ , via )    	hanoi2(n - 1, via , to_ , from)    end ifend sub print "Hanoi 2 ellapsed ... ";hanoi2(22, 1, 3, 2)print peek("millisrunning") - t2, " ms"

## zkl

Translation of: C
fcn move(n, from,to,via){   if (n>0){      move(n-1, from,via,to);      println("Move disk from pole %d to pole %d".fmt(from, to));      move(n-1, via,to,from);   }}move(3, 1,2,3);
Output:
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
`