Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

2 Stron V   1 2 >  
Reply to this topicStart new topic
> Wieże Hanoi, Klasa, PHP 5
dr_bonzo
post 22.05.2005, 22:50:17
Post #1





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


Co to robi? Rozwiazuje "Wieze Hanoi", uzywa minimalnej liczby ruchow i pokazuje je kolejno.

PHP5 REQUIRED

  1. <pre><?php
  2. class HanoiStack
  3. {
  4.     private $arrStack = array();
  5.     
  6.     public function HanoiStack()
  7.     {
  8.     }
  9.     
  10.     public function pushItem( $intItem )
  11.     {
  12.         $intItem = intval( $intItem );
  13.         
  14.         if ( count( $this->arrStack ) === 0 )
  15.         {
  16.             array_push( $this->arrStack, $intItem );
  17.         }
  18.         else
  19.         {
  20.             if ( $intItem > $this->getLastItem() )
  21.             {
  22.                 throw new Exception( 'Cannot put bigger brick on smaller (' . $intItem . ' on ' . $this->getLastItem() . ')' );
  23.             }
  24.             
  25.             array_push( $this->arrStack, $intItem );
  26.         }
  27.     }
  28.     
  29.     public function popItem()
  30.     {
  31.         if ( count( $this->arrStack ) === 0 )
  32.         {
  33.             print_r( $this->arrStack );
  34.             throw new Exception( 'Cannot pop intem from empty stack' );
  35.         }
  36.         
  37.         return array_pop( $this->arrStack );
  38.     }
  39.     
  40.     public function getLastItem()
  41.     {
  42.         if ( count( $this->arrStack ) === 0 )
  43.         {
  44.             return -1;
  45.         }
  46.         
  47.         return $this->arrStack[ count( $this->arrStack ) - 1 ];
  48.     }
  49.     
  50.     public function __toString()
  51.     {
  52.         $s = '[ ';
  53.         
  54.         foreach ( $this->arrStack as $v )
  55.         {
  56.             $s .= $v . ' ';
  57.         }
  58.         
  59.         $s .= &#092;"]n\";
  60.         return $s;
  61.     }
  62. }
  63.  
  64. class Hanoi
  65. {
  66.     private $arrStacks = array();
  67.     
  68.     private $intN;
  69.     
  70.     private $intMoves;
  71.     
  72.     public function Hanoi( $intN )
  73.     {
  74.         $this->intN = intval( $intN );
  75.         
  76.         for ( $i = 0; $i < 3; $i++ )
  77.         {
  78.             $this->arrStacks[ $i ] = new HanoiStack();
  79.         }
  80.         
  81.         for ( $i = $this->intN - 1; $i >= 0; $i-- )
  82.         {
  83.             $this->arrStacks[ 0 ]->pushItem( $i ); 
  84.         }
  85.     }
  86.     
  87.     public function solve()
  88.     {
  89.         $this->printTowers();
  90.         
  91.         // z wiezy 0 na wieze 2
  92.         if ( $this->intN <= 0 )
  93.         {
  94.             throw new Exception( 'Wrong intN' );
  95.         }
  96.         
  97.         $i_max = intval( pow( 2, $this->intN ) - 1 );
  98.         
  99.         $intBrickOnePosition = 0;
  100.         $intMoveDirection = ( $this->intN % 2 === 1 ) ? -: 1;
  101.         
  102.         for ( $i = 0; $i < $i_max; $i++ )
  103.         {
  104.             if ( $i % 2 === 0 )
  105.             {
  106.                 // zdejmij jedynke (tu zero: indeksujemy klocki od zera)
  107.                 $intItem = $this->arrStacks[ $intBrickOnePosition ]->popItem();
  108.                 print( '(' . $intBrickOnePosition . ')--[ ' . $intItem . ' ]-->(' . ( $intBrickOnePosition + $intMoveDirection + 3 ) % 3 . ')' . &#092;"n\" );
  109.                 $intBrickOnePosition = ( $intBrickOnePosition + $intMoveDirection + 3 ) % 3;
  110.                 // i przenies ja w keirunku $intMoveDirection
  111.                 $this->arrStacks[ $intBrickOnePosition ]->pushItem( $intItem );
  112.             }
  113.             else
  114.             {
  115.                 $arrTowerIndices = array();
  116.                 $arrTopItems = array();
  117.                 $x = 0;
  118.                 
  119.                 
  120.                 // znajdz wieze z min i max brickiem !== 1
  121.                 for ( $j = 0; $j < 3; $j++ )
  122.                 {
  123.                     if ( $j !== $intBrickOnePosition )
  124.                     {
  125.                         $arrTowerIndices[ $x ] = $j;
  126.                         $arrTopItems[ $x ] = $this->arrStacks[ $j ]->getLastItem();
  127.                         $x++;
  128.                     }
  129.                 }
  130.                 
  131.                 $intTowerWithSmallerTopItem = ( $arrTopItems[ 0 ] < $arrTopItems[ 1 ] ) ? $arrTowerIndices[ 0 ] : $arrTowerIndices[ 1 ];
  132.                 $intTowerWithBiggerTopItem = ( $arrTopItems[ 0 ] > $arrTopItems[ 1 ] ) ? $arrTowerIndices[ 0 ] : $arrTowerIndices[ 1 ];
  133.                 
  134.                 if ( $this->arrStacks[ $intTowerWithSmallerTopItem ]->getLastItem() === -1 )
  135.                 {
  136.                     // zamien je to ta pierwsza jest pusta
  137.                     $temp = $intTowerWithSmallerTopItem;
  138.                     $intTowerWithSmallerTopItem = $intTowerWithBiggerTopItem;
  139.                     $intTowerWithBiggerTopItem = $temp;
  140.                 }
  141.                 
  142.                 // przenies klocek
  143.                 $intItem = $this->arrStacks[ $intTowerWithSmallerTopItem ]->popItem();
  144.                 print( '(' . $intTowerWithSmallerTopItem . ')--[ ' . $intItem . ' ]-->(' . $intTowerWithBiggerTopItem . ')' . &#092;"n\" );
  145.                 $this->arrStacks[ $intTowerWithBiggerTopItem ]->pushItem( $intItem );
  146.                 
  147.                 
  148.             }
  149.             
  150.             $this->printTowers();
  151.         }
  152.     }
  153.     
  154.     private function printTowers()
  155.     {
  156.         print( '0: ' );
  157.         print( $this->arrStacks[ 0 ] );
  158.         print( '1: ' );
  159.         print( $this->arrStacks[ 1 ] );
  160.         print( '2: ' );
  161.         print( $this->arrStacks[ 2 ] );
  162.         print( &#092;"n\" );
  163.     }
  164. }
  165.  
  166.  
  167. class HanoiTowers
  168. {
  169.     public static function main()
  170.     {
  171.         try
  172.         {
  173.             $objHanoiTower = new Hanoi( 3 );
  174.             $objHanoiTower->solve();
  175.         }
  176.         catch ( Exception $e )
  177.         {
  178.             print( $e );
  179.         }
  180.     }
  181. }
  182.  
  183. HanoiTowers::main();
  184. ?></pre>


Ten post edytował dr_bonzo 2.06.2005, 17:47:06


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
GrayHat
post 25.05.2005, 22:06:35
Post #2





Grupa: Zarejestrowani
Postów: 566
Pomógł: 18
Dołączył: 23.08.2003
Skąd: Łomża

Ostrzeżenie: (0%)
-----


mozna jakis exampel?


--------------------
*Note: No animals were killed durning the construction of this post.
Go to the top of the page
+Quote Post
dr_bonzo
post 25.05.2005, 22:56:07
Post #3





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


Ehhh... a chociarz uruchomiles ten skrypt?
Wystarczy go skopiowac i uruchomic -- wyswietli ci kolejne ruchy i kolejne stany wiez.


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
GrayHat
post 25.05.2005, 23:41:07
Post #4





Grupa: Zarejestrowani
Postów: 566
Pomógł: 18
Dołączył: 23.08.2003
Skąd: Łomża

Ostrzeżenie: (0%)
-----


a wogole co to wierze hanoi??


--------------------
*Note: No animals were killed durning the construction of this post.
Go to the top of the page
+Quote Post
dr_bonzo
post 25.05.2005, 23:53:17
Post #5





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


WieZe -- google wiedzialo ale nie powiedzialo?
http://en.wikipedia.org/wiki/Tower_of_Hanoi


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
Bielo
post 29.05.2005, 09:22:10
Post #6





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 21.09.2003
Skąd: Truskaw

Ostrzeżenie: (0%)
-----


Sam algorytm rozwiązywania Hanoi wygląda tak:
  1. <?php
  2.  
  3. function hanoi($dyskow, $z, $na)//hanoi(ilosc dyskow do przelozenia, slupek na ktorym zaczynamy, slupek na ktory pr
    z
  4. nosimy)
  5. {
  6. if($dyskow==1)
  7. {
  8. print(&#092;"Przesun dysk nr \".$dyskow.\" z \".$z.\" na \".$na.\"<br />\");
  9. }
  10. else
  11. {
  12. hanoi($dyskow-1, $z, 3-$z-$na);
  13. print(&#092;"Przesun dysk nr \".$dyskow.\" z \".$z.\" na \".$na.\"<br />\");
  14. hanoi($dyskow-1, 3-$z-$na, $na);
  15. }
  16. }
  17.  
  18. ?>

Przyklad pzepisany z ksiazki Helionu "Algorytmy, struktury danych i techniki programowania", sprawdzalem pieknie dziala.

Nie przygladalem sie za bardzo Twojemu skryptowi, ale mysle ze mozna bylo zrobic to krocej


--------------------
Go to the top of the page
+Quote Post
dr_bonzo
post 29.05.2005, 10:12:15
Post #7





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


Twoj algorytm jest rekurencyjny, a moj nie. Oba opisane sa w wikipedii:

Cytat
Alternately move disc 1 and one of the larger discs. If two of the larger discs are available, always move the smaller one onto the larger. When you move an odd-numbered disc, always move it one peg clockwise; when you move an even-numbered disc, always move it one peg counterclockwise.

An even easier way to remember this solution is to notice that the smallest disk gets every second move, and always moves in the same direction. In between smallest disk moves, there is only one legal move that does does not involve moving the smallest disk again.

----

Cytat
Nie przygladalem sie za bardzo Twojemu skryptowi, ale mysle ze mozna bylo zrobic to krocej

No pewnie, w ogole porzucic klasy, obsluge bledow, skrocic printTowers(), itd.


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
Bielo
post 29.05.2005, 10:20:44
Post #8





Grupa: Zarejestrowani
Postów: 127
Pomógł: 0
Dołączył: 21.09.2003
Skąd: Truskaw

Ostrzeżenie: (0%)
-----


to co ja napisalem to jest tylko algorytm, a nie caly skrypt. Po dodaniu do niego obslugi bledow i przerobieniu na wersje obiektowa, bylby chyba krotszy od Twojego, ale rozumiem tez uzycie wersji nerekurencyjnej


--------------------
Go to the top of the page
+Quote Post
Radarek
post 29.05.2005, 11:45:05
Post #9





Grupa: Zarejestrowani
Postów: 188
Pomógł: 0
Dołączył: 23.05.2005

Ostrzeżenie: (0%)
-----


A mi nawet nie chce sie czytac i probowac zrozumiec wersje iteracyjna, bo po co? Wersja rekurencyjna jest tak intuicyjna i zrozumiala, ze nie trzeba nic wiecej. To niesamowite, ze te kilka linijek jest poprawnym rozwiazaniem [i najoptymalniejszym] podanego problemu. Ale braw nie bije bo znalem juz wczesniej to rozwiazanie winksmiley.jpg
Go to the top of the page
+Quote Post
M4chu
post 29.05.2005, 11:52:49
Post #10





Grupa: Zarejestrowani
Postów: 135
Pomógł: 0
Dołączył: 28.09.2003
Skąd: Rzeszów

Ostrzeżenie: (0%)
-----


Najoptymalniejszym? Dla mnie najoptymalniejsze to najszybsze, a rekurencyjne takie napewno nie jest.
Go to the top of the page
+Quote Post
dr_bonzo
post 29.05.2005, 12:15:32
Post #11





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


Cytat
Ale braw nie bije bo znalem juz wczesniej to rozwiazanie

Prawda jest taka ze nudzilo mi sie tamtej nocy i napisalem ten algorytm.
A wpadlem na niego (rozwiazujac na papierze dziesiatki razy WH) dawno temu.

Cytat
Wersja rekurencyjna jest tak intuicyjna i zrozumiala

A sprobuj go zastosowac w praktyce w realu...


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
Bakus
post 29.05.2005, 14:36:03
Post #12


Administrator serwera


Grupa: Przyjaciele php.pl
Postów: 909
Pomógł: 0
Dołączył: 12.08.2003
Skąd: /var/www/wroclaw.php

Ostrzeżenie: (0%)
-----


@Bielo: Jeżeli masz pomysł, to go rozwiń, napisz skrypt i umieść w osobnym temacie.


--------------------
Powrót do przeszłości :)
Go to the top of the page
+Quote Post
Radarek
post 29.05.2005, 14:38:41
Post #13





Grupa: Zarejestrowani
Postów: 188
Pomógł: 0
Dołączył: 23.05.2005

Ostrzeżenie: (0%)
-----


Cytat
Najoptymalniejszym? Dla mnie najoptymalniejsze to najszybsze, a rekurencyjne takie napewno nie jest.


Dlaczego nie?smile.gif Zapewniam cie ze jest. Powiedz jaki jest powod dla ktorego mialo byc nie byc?

Cytat
Prawda jest taka ze nudzilo mi sie tamtej nocy i napisalem ten algorytm.
A wpadlem na niego (rozwiazujac na papierze dziesiatki razy WH) dawno temu.


Przyznam ci sie, ze ja tez kiedys wpadlem na to rozwiazanie, ale mniejsza z tym.

Cytat
A sprobuj go zastosowac w praktyce w realu...


Hm.. jesli pisze program to po to zeby robil cos za mnie. Np. program sortujacy za pomoca quicksorta lub heapsorta. Sprobuj zrobic to w praktyce. Bez sensu gadanie... smile.gif
Go to the top of the page
+Quote Post
bela
post 29.05.2005, 16:12:29
Post #14


Administrator PHPedia.pl


Grupa: Developerzy
Postów: 1 102
Pomógł: 2
Dołączył: 14.09.2003

Ostrzeżenie: (0%)
-----


Cytat(Radarek @ 2005-05-29 15:38:41)
Cytat

Najoptymalniejszym? Dla mnie najoptymalniejsze to najszybsze, a rekurencyjne takie napewno nie jest.


Dlaczego nie?smile.gif Zapewniam cie ze jest. Powiedz jaki jest powod dla ktorego mialo byc nie byc?

Udowodnij, że jest najoptymalniejsze winksmiley.jpg


--------------------
Go to the top of the page
+Quote Post
Radarek
post 29.05.2005, 16:46:24
Post #15





Grupa: Zarejestrowani
Postów: 188
Pomógł: 0
Dołączył: 23.05.2005

Ostrzeżenie: (0%)
-----


Cytat(bela_666 @ 2005-05-29 15:12:29)
Cytat(Radarek @ 2005-05-29 15:38:41)
Cytat

Najoptymalniejszym? Dla mnie najoptymalniejsze to najszybsze, a rekurencyjne takie napewno nie jest.


Dlaczego nie?smile.gif Zapewniam cie ze jest. Powiedz jaki jest powod dla ktorego mialo byc nie byc?

Udowodnij, że jest najoptymalniejsze winksmiley.jpg

Hm.. ilosc ruchow potrzebnych do przeniesienia N krazkow wynosci 2^(n-1) i taka jest zlozonosc programu. Szybciej sie nie da. Zakladajac, ze wersja iteracyjna wykonuje taka sama ilosc ruchow to i tak jest mniej optymalna. Czemu? Bo zawiera wiecej instrukcji smile.gif. Przepiszcie obra programy na C/C++, skompilujcie do kodu assemblerowego i porownajcie rozmiary kodu. Stawiam, ze mniejszy bedzie rekurencyjny.
Go to the top of the page
+Quote Post
dr_bonzo
post 29.05.2005, 17:50:27
Post #16





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


Ale wez tez pod uwage wielokrotne wywolywanie funkcji, co takze zajmuje zasoby i cpu (trzeba utworzyc zmienne lokalne, odlozyc je na stos, wywolac funkcje, zdjac zmienne z powrotem, itd). Ale nie wiem, ktora z metod bedzie szybsza.


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
Radarek
post 29.05.2005, 18:33:38
Post #17





Grupa: Zarejestrowani
Postów: 188
Pomógł: 0
Dołączył: 23.05.2005

Ostrzeżenie: (0%)
-----


Cytat(dr_bonzo @ 2005-05-29 16:50:27)
Ale wez tez pod uwage wielokrotne wywolywanie funkcji, co takze zajmuje zasoby i cpu (trzeba utworzyc zmienne lokalne, odlozyc je na stos, wywolac funkcje, zdjac zmienne z powrotem, itd). Ale nie wiem, ktora z metod bedzie szybsza.

Tak wzialem to pod uwage. Rekurencyjne wywolanie funkcji to odlozenie na stos zmiennych lokalnych funkcji oraz adresu powrotu. Nie wierzysz chyba zeby wersja rekurencyjna bedzie dluzsza? smile.gif
Go to the top of the page
+Quote Post
onlyX
post 2.06.2005, 17:28:09
Post #18





Grupa: Zarejestrowani
Postów: 119
Pomógł: 0
Dołączył: 15.07.2003
Skąd: Grajewo

Ostrzeżenie: (0%)
-----


A mi wyrzuciło taki błąd w tym pierszym skrypcie:
Kod
Parse error: parse error, expecting `T_OLD_FUNCTION' or `T_FUNCTION' or `T_VAR' or `'}'' in D:\usr\test\hanoi.php on line 4
Go to the top of the page
+Quote Post
dr_bonzo
post 2.06.2005, 17:46:52
Post #19





Grupa: Przyjaciele php.pl
Postów: 5 724
Pomógł: 259
Dołączył: 13.04.2004
Skąd: N/A

Ostrzeżenie: (0%)
-----


Bo musisz miec PHP5.

PS. Uzupelniony 1szy post o to info


--------------------
Nie lubię jednorożców.
Go to the top of the page
+Quote Post
piratt
post 29.09.2005, 10:34:07
Post #20





Grupa: Zarejestrowani
Postów: 20
Pomógł: 0
Dołączył: 28.09.2005

Ostrzeżenie: (0%)
-----


A wzial ktos pod uwage fakt ze w wersji rekurencyjnej skonczy sie baaardzo szybko pamiec? winksmiley.jpg Rekurencja nie jest zalecana przy duzej liczbie wywolan.
Go to the top of the page
+Quote Post

2 Stron V   1 2 >
Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 25.07.2025 - 10:15