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)
ANDROID HP Prime App broken offline on some mobiles
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)
ANDROID HP Prime App broken offline on some mobiles
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)