Post Reply 
Tower of Hanoi (Tour de Hanoi)
04-21-2016, 08:04 AM (This post was last modified: 04-21-2016 08:05 AM by StephenG1CMZ.)
Post: #1
Tower of Hanoi (Tour de Hanoi)
Prompted by my recent involvement with a team activity to solve the Tower of Hanoi, I produced this little program..

Unlike all the existing versions I have seen, this one allows you to enter a challenge time, and calculates the average time per move - or enter an average move time and calculate how long a practical activity with real objects will need.

Stephen Lewkowicz (G1CMZ)
Visit this user's website Find all posts by this user
Quote this message in a reply
04-21-2016, 08:15 AM
Post: #2
RE: Tower of Hanoi (Tour de Hanoi)
Version 1 is available in English Francais and Polskie (with help from Google Translate).

It implements the minimum 3-towers solution to the problem.
It lists the required moves in lists L1 (from) and L2 (to).
There is no animation of the contents of each tower.
Code:

 LOCAL STHANOI:={"Tower of Hanoi","Wieża Hanoi","Tour de Hanoi"};
 LOCAL STG:=" StephenG1CMZ ";
 LOCAL CRID:=" ©2016"+STG; 

 LOCAL VERNUM:="1.0";

 LOCAL SL;
 LOCAL II;
 LOCAL NOTEsc;

 LOCAL EN:=1;
 LOCAL PL:=2;
 LOCAL FR:=3;
 LOCAL LANGS:={"English","Polskie","Français"};

 //CUSTOMISE
 LOCAL LANG_ASK:=1;   //1=ASK 0=USE SYSTEM
 LOCAL DEFLT_LANG:={EN,PL,FR,EN}; // 1 2 3 REST
 LOCAL INTRO_CONFIRM:=1; //1 0
 LOCAL INPROGRESS:=0; //1=SHOW 0=NO
 LOCAL SHOW_MOVE_LIST:=1;
 //

 LOCAL TFROM,TTO,TVIA;
 LOCAL STVER:={"Version ","Wersja ","Version "}+ VERNUM;
 
 LOCAL THREET:={": 3 Towers",": 3 Wieże",": 3 Tours"};
 LOCAL NITEMS:=5; //0..13;
 LOCAL STFIRST:={"1st","1-ty","1er"};
 LOCAL STDEST:={"DEST","CEL","DEST"};
 LOCAL STVIA:={"VIA","PRZEZ","VIA"};
 LOCAL NL:=CHAR(10);
 LOCAL Z_ESC:=4;
 LOCAL IMP_LIMITS_CHOOSE:={1,2047};// 11 ITEMS
 LOCAL IMP_LIMIT_LISTS:=10000;// 13 ITEMS

 LOCAL MOVES;//REQUIRED
 LOCAL NMOVE;

 // ENTER TIMEGIVEN TO ESTIMATE MOVETIME
 // ENTER MOVETIME TO ESTIMATE REQUIRED TIME
 // (ANY UNITS UNSPECIFIED)

 LOCAL TIMEGIVEN := 10*60;//FOR CHALLENGE
 LOCAL EST_MOVETIME:=1;
 
 LOCAL TTL;

 LOCAL STOBJ:={" Objects",""," Objets"};
 LOCAL LBL:={
  {"# objects","From","To","Via",
  "TOTAL TIME","MOVE TIME"},
  {"# obiekty","Od","Do","Przez","Czas Caŀkowity","Przesunąć czas"},
  {"# objets","De","À","Via","Temps Totale","DéplacerTemps"}};
 
 LOCAL HLP:={
  {"Number of objects to move [0..13]",
  "Name of From/1st Tower",
  "Name of To/Destination Tower",
  "Name of Via/Temporary Tower",
  "TIME ALLOWED -> EST TIME PER MOVE",
  "EST MOVE TIME -> TIME NEEDED"},
  {"Liczbe obkiektõw, aby przenieść [0..13]",
   "Nazwa Z/1-ty wieży",
   "Nazwa Do/Preznacenia wieży",
   "Nazwa Poprzez/Tymczasowej wieży",
   "Dopuszczalny czas -> przewidywany czas na ruch",
   "Szacowany czas ruch -> czas potrzebny"},
  {"Nombre d'objets à déplacer [0..13]",
   "Nom de De/1er Tour","Nom de À/Tour de destination","Nom de Via/Tour Temporaire",
   "Temps imparti -> heure par coup","déplacer le temps -> temps nécessaire estimée"}};

 LOCAL STIMPLIMIT:={"IMPLEMENTATION LIMIT:"+NL,"REALIZACJA LIMIT:"+NL,"LIMITE DE MISE EN OEUVRE"+NL};
 LOCAL STTOOMANY:={"too many moves to list","zbyt wiele ruchów do listy","trop de coups à la liste"};
 LOCAL STNOCHOOSE:={"CHOOSE","CHOOSE","CHOOSE"};
 LOCAL STOBJNEEDS:={" objects need "," przedmioty potrzebne "," objets ont besoin de "};
 LOCAL STMOVES:={" moves"," porusza"," mouvements"};
 LOCAL STPERMOVE:={" per move"," za ruch"," par coup"};
 LOCAL STESTDUN:={"Estimated completion in ","Szacuje się zakończenie ","L'estimation d'achèvement "};
 LOCAL STANYKEY:={"PRESS ANY KEY","NACIŚNIJ DOWOLNY KLAWISZ","APPUYEZ SUR UNE TOUCHE"}+" !{Esc}";
 LOCAL STLIST:={"Listing ","Wymienianie kolejno ","Liste des "};
 LOCAL STSEELISTS:={
  "{Esc Shift List Edit} to see lists ",
  "{Esc Shift List Edit} aby zobaczyć list ",
  "{Esc Shift List Editer}pour voir les listes"};
 LOCAL INSTR:="";
 LOCAL INSTRS:={};
 LOCAL CHS,OKC;
 LOCAL TM;

 OOPS()
 BEGIN
  LOCAL ST:="*** Esc ***";
  MSGBOX(ST);
  PRINT(ST);
 END;

 GOON()
 BEGIN
  IF NOTEsc THEN
   IF GETKEY==Z_ESC THEN
    OOPS();
    NOTEsc:=0;
    //RETURN 0;
   END;
   RETURN 1;
  ELSE
   RETURN 0;
  END;  
 END;

 LOCAL TOOBIG(MSG)
 BEGIN
     MSGBOX(STHANOI(SL)+NL+STIMPLIMIT(SL)+MSG);
 END;

 LOCAL MOVECOUNT(NITEMS)
 BEGIN
  RETURN 2^(ABS(NITEMS))-1;
 END;

 LOCAL AMOVE(NITEMS,TFROM,TTO,TVIA)
 BEGIN
  IF GOON()==1 THEN
   IF (NITEMS>0) THEN
     IF INPROGRESS THEN
      DRAWMENU(MOVES-NMOVE);
     END; 
    //PRINT("GOAL:GET "+NITEMS+" ITEMS FROM "+TFROM+" TO "+TTO);
 
    AMOVE(NITEMS-1,TFROM,TVIA,TTO);//SOLVING
 
    L1(NMOVE):=TFROM;
    L2(NMOVE):=TTO;
    INSTR:=(MOVES-NMOVE+1)+"↔"+NMOVE+": "+TFROM+" -> "+TTO;
    INSTRS(NMOVE):=INSTR;
    NMOVE:=NMOVE+1;
   
    AMOVE(NITEMS-1,TVIA,TTO,TFROM);//COMPLETED
   END;
  
  END;
 END;

 LOCAL GET_INPUTS()
 BEGIN
   OKC:=INPUT({NITEMS,TFROM,TTO,TVIA,TIMEGIVEN,EST_MOVETIME},TTL,LBL(SL),HLP(S​L));
 END;

 INTRO_REPORT()
 BEGIN
   MOVES:=MOVECOUNT(NITEMS);
   PRINT(NITEMS+STOBJNEEDS(SL)+MOVES+STMOVES(SL));
   IF TIMEGIVEN AND MOVES THEN
    PRINT(TIMEGIVEN+"/"+MOVES+"="+(TIMEGIVEN/MOVES) + STPERMOVE(SL));
   END;
   IF EST_MOVETIME THEN 
    PRINT(STESTDUN(SL)+MOVES+"*"+EST_MOVETIME+"="+(MOVES*EST_MOVETIME));  
   END;
   //THOSE ESTIMATES ARE CALCULATED INDEPENDENTLY AND MUTUALLY INCONSISTENT
   
 END;

 LOCAL RESULT_REPORT()
 BEGIN
  IF SHOW_MOVE_LIST  AND MOVES≥IMP_LIMITS_CHOOSE(1) THEN //WA.CHOOSE
    IF MOVES>IMP_LIMITS_CHOOSE(2) THEN
      //TOOBIG(STNOCHOOSE(SL)+NL+MOVES+">"+IMP_LIMITS_CHOOSE(2));
    ELSE  
     TTL:=STHANOI(SL)+STG;
     OKC:=CHOOSE(CHS,TTL+NITEMS+STOBJ(SL),INSTRS);
    END; 
  END;
 END;

 LOCAL PROGRAM_REPORT()
 BEGIN
    PRINT(IFTE(TM<1000,TM+" ms",ROUND(TM/1000,0)+" s"));
    PRINT(STSEELISTS(SL)+"L1&L2");
 END;

 LOCAL DO_TOWER3(NITEMS)
 BEGIN
   //MOVING A NEG NUM OF DISKS TO DEST
   //PERHAPS EQUATES TO MOVING THE DISKS FROM DEST
   IF NITEMS<0 THEN
    NITEMS:=ABS(NITEMS);//INGUARD
    //SWAP FROM AND TO TOWERS() RETURN TBD
   END;
 
   MOVES:=MOVECOUNT(NITEMS);
   NMOVE:=1;//MOVES
   L1:={}; L2:={}; //LIST L1 FROM L2 TO
   INSTRS:={};     //READABLE INSTRUCION
   AMOVE(NITEMS,TFROM,TTO,TVIA);//COMPLETED
 END;

 

 LOCAL STARTING ()
 BEGIN
  SL:=DEFLT_LANG(MIN(Language,SIZE(DEFLT_LANG)));
  TTL:=STHANOI(SL)+CRID; 
  PRINT();
  PRINT(TTL);

  IF LANG_ASK THEN
   OKC:=CHOOSE(SL,TTL,LANGS);
   SL:=DEFLT_LANG(SL);
  END;
  TTL:=STHANOI(SL)+CRID;
  PRINT();
  PRINT(TTL);
  PRINT(STVER(SL)+THREET(SL));
  TFROM:=STFIRST(SL);
  TTO:=STDEST(SL);
  TVIA:=STVIA(SL);
  NOTEsc:=1;//GOON INIT
  TM:=0;
 END;

 EXPORT TOWER1()
 BEGIN
  STARTING();
  GET_INPUTS();
  IF OKC THEN //INPUT READY
   //OKC:=1;//MUST NOT =Z_ESC
   MOVES:=MOVECOUNT(NITEMS);
   IF INTRO_CONFIRM THEN //OPTIONAL INFO
    INTRO_REPORT();
    PRINT(STANYKEY(SL));
    OKC:=WAIT;
   END; 

   IF OKC==Z_ESC THEN
    OOPS();
   ELSE //REQUEST CONFIRMED
    PRINT(STLIST(SL)+MOVES+STMOVES(SL)+"...");
 
    IF MOVES>IMP_LIMIT_LISTS THEN
     TOOBIG(STTOOMANY(SL)+NL+MOVES+">"+IMP_LIMIT_LISTS);
    ELSE
     //DO ACTION
     TM:=TICKS;  
     DO_TOWER3(NITEMS);
     TM:=TICKS-TM;

     RESULT_REPORT();//SHOWS MOVES
    END;
   END; 
   PROGRAM_REPORT();
  ELSE
   OOPS();//INPUT CANCEL
  END;
 END;

Stephen Lewkowicz (G1CMZ)
Visit this user's website Find all posts by this user
Quote this message in a reply
04-21-2016, 08:32 AM
Post: #3
RE: Tower of Hanoi (Tour de Hanoi)
Dzien dobry

FAJNIE !

Gérard.
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)