| 
 
      
        
            | Main Menu |  
            |  |  
          |  |  
           
            | Forums |   
            |  |   
            |  |  
           
            | Programming 
                Contest |   
            |  |   
            |  |  
           
            | Documentation 
               |   
            |  |   
            |  |  
           
            | Partner 
                Sites  |   
            | 
 |   
            |  |  
           
            | Sponsors |   
            |  |   
            |  |  
 | 
        
          | 
| Code of cagret 
<?php
Back to results/*
 * cards.php
 * php-editors.com contest - 7th April 2003
 * +-----------------------------------+
 * | Author:   cagrET (Cezary Tomczak) |
 * | Email:    cagret@yahoo.com        |
 * | Homepage: http://cagret.prv.pl    |
 * | Country:  Poland                  |
 * +-----------------------------------+
 */
 
 error_reporting(E_ALL);
 //set_time_limit(60);
 //set_error_handler('my_error_handler');
 
 new Cards;
 
 class Cards
 {
 var $filename      = 'deck.txt';
 
 var $cards;   // min: 2 , max: 52 , even number: 2,4,6 ... 50,52
 var $perfect; // cards in perfect position
 
 var $cards_op     = array(); //operations (CSF)
 var $cards_op_id;            //current id
 var $cards_op_tmp = array(); //temporary
 var $cards_tmp;              //last shuffle done
 
 var $decks    = array(); //combinations of decks
 
 var $len;  // length
 var $half; // 1/2 length
 
 var $maxshuffle;
 
 var $CutFlip; //cut flip combinations
 var $Shuffle; //shuffle combinations
 
 var $time;
 
 
 function Cards()
 {
 //init
 $this->cards   = $this->read($this->filename);
 $this->len     = strlen($this->cards);
 $this->half    = $this->len / 2;
 $this->perfect = $this->getPerfect($this->half);
 $this->maxshuffle = $this->getMaxShuffle($this->half);
 
 //starting
 //$this->time_start();
 $this->init();
 }
 
 function __construct()
 {
 this->Cards();
 }
 function init()
 {
 //print $this->operate_undo('12C23FC1C', 1);
 //return;
 
 //print $this->operate('F1C1C1C1C1C', 1);
 //return;
 
 //cutflip and shuffle arrays
 $this->CutFlip = $this->getCutFlip();
 $this->Shuffle = $this->getShuffle();
 
 $this->decks = $this->CutFlip; //creating deck of combinations
 $this->try1st();               //try 1st combinations of C , F , CF
 $this->CutFlip = $this->getCutFlip2();
 
 $even = false;
 
 while (true) {
 if ($even) {
 $this->tryCutFlip();
 $even = false;
 } else {
 $this->tryShuffle();
 $even = true;
 }
 }
 }
 
 //1st operate
 function try1st()
 {
 foreach($this->decks as $val) {
 $this->operate($val);
 }
 }
 
 //joins deck with parts of CutFlip array
 function tryCutFlip()
 {
 $tmp_decks = $this->decks;
 $this->decks = array();
 
 $this->cards_op_tmp = $this->cards_op;
 $this->cards_op     = array();
 
 foreach($tmp_decks as $key => $val) {
 foreach ($this->CutFlip as $val2) {
 $this->cards_op_id = $key;
 $this->operate_fast($val2, $val);
 $this->decks[] = $val . $val2;
 }
 }
 }
 
 //joins deck with parts of Shuffle array
 function tryShuffle()
 {
 $tmp_decks   = $this->decks;
 $this->decks = array();
 
 $this->cards_op_tmp = $this->cards_op;
 $this->cards_op     = array();
 
 foreach($tmp_decks as $key => $val) {
 foreach($this->Shuffle as $val2) {
 $this->cards_op_id = $key;
 $this->operate_fast($val2, $val);
 $this->decks[] = $val . $val2;
 }
 }
 }
 
 function getCutFlip()
 {
 return array('', 'F', 'C', 'CF');
 }
 
 //there is no sense in repeating 'F' or 'CF'
 function getCutFlip2()
 {
 return array('C');
 }
 
 function getShuffle()
 {
 $len = $this->maxshuffle;
 $Shuffle = array();
 for($i = 1; $i <= $len; ++$i) {
 $Shuffle[] = $i;
 }
 return $Shuffle;
 }
 
 //this is faster cause it adds 1 operation instead of doing all ... (in table is string from similar operation)
 //$s - last operation, $s_start - all prevoious ; F1C3C4 ($s_start) 3($s)
 function operate_fast($s, $s_start)
 {
 $tmp = $this->cards_op_tmp[$this->cards_op_id];
 
 switch ($s) {
 case 'C':
 //CUT
 $tmp = substr($tmp, -$this->half) . substr($tmp, 0, $this->half);
 break;
 case 'F':
 //FLIP
 $tmp = strrev($tmp);
 break;
 default:
 //SHUFFLE
 if ($s == 1) {
 $tmp = $this->shuffle($tmp);
 $this->cards_tmp = $tmp;
 } else {
 $tmp = $this->cards_tmp = $this->shuffle($this->cards_tmp);
 }
 break;
 }
 
 //caching results - average 12x times faster with caching
 $this->cards_op[] = $tmp;
 
 if ($tmp == $this->perfect) {
 $this->finish($s_start . $s);
 }
 }
 
 //operates on $s = FSS etc.
 function operate($s, $return = false)
 {
 $tmp = $this->cards;
 $len = strlen($s);
 
 for($i = 0; $i < $len; ++$i) {
 $index = $s{$i};
 if (is_numeric($index) && $i < $len-1 && is_numeric($s{$i + 1})) {
 $index .= $s{++$i};
 }
 
 switch ($index) {
 case 'C':
 //CUT
 $tmp = substr($tmp, -$this->half) . substr($tmp, 0, $this->half);
 break;
 case 'F':
 //FLIP
 $tmp = strrev($tmp);
 break;
 default:
 //SHUFFLE x times
 //if ($this->count == 12) trigger_error('', E_USER_ERROR);
 $tmp = $this->shuffle_x($tmp, $index);
 break;
 }
 }
 
 if ($return) {
 return $tmp;
 } else {
 //operate_fast compatible
 $this->cards_op[] = $tmp;
 
 if ($tmp == $this->perfect) {
 $this->finish($s);
 }
 }
 }
 
 //FOUND
 function finish($s)
 {
 $s = $this->undo_deck($s);
 print $s . strlen($s);
 //print '<br /><br />' . $this->time_end();
 exit;
 }
 
 //translate from our system - change F4C3 to FSSSSCSSS etc.
 function undo_deck($s)
 {
 $len = strlen($s);
 $tmp = '';
 for ($i = 0; $i < $len; ++$i) {
 if (is_numeric($index = $s{$i})) {
 if ($i < $len-1 && is_numeric($s{$i + 1})) {
 $index .= $s{++$i};
 }
 $tmp .= str_repeat('S', $index);
 } else {
 $tmp .= $s{$i};
 }
 }
 return $tmp;
 }
 
 // CUT == undo cut x1
 function cut($s)
 {
 return substr($s, -$this->half) . substr($s, 0, $this->half);
 }
 
 // SHUFFLE single string (SLOW)
 function shuffle($s)
 {
 $tmp  = '';
 $b    = $this->half;
 for ($i = 0; $i < $this->half; ++$i) {
 $tmp .= $s{$b++} . $s{$i};
 }
 return $tmp;
 }
 
 // SHUFFLE x times (SLOW)
 function shuffle_x($s, $x)
 {
 $tmp2 = $s;
 for ($i = 1; $i <= $x; ++$i) {
 $tmp = '';
 $a   = 0;
 $b   = $this->half;
 for ($ii = 0; $ii < $this->half; ++$ii) {
 $tmp .= $tmp2{$b++} . $tmp2{$a++};
 }
 $tmp2 = $tmp;
 }
 return $tmp2;
 }
 
 // SHUFFLE UNDO (SLOW)
 function shuffle_undo($s)
 {
 $a = '';
 $b = '';
 for ($x = 0; $x < $this->len; $x += 2) {
 $b .= $s{$x};
 $a .= $s{$x + 1};
 }
 return $a . $b;
 }
 
 // FLIP == undo flip x1
 function flip($s)
 {
 return strrev($s);
 }
 
 // GET PERFECT string ; $deck = $this->half
 function getPerfect($deck)
 {
 $upper = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
 $lower = 'abcdefghijklmnopqrstuvwxyz';
 return substr($upper, 0, $deck) . substr($lower, 0, $deck);
 }
 
 // number of shuffles after which string repeats OR is reversed (flip)
 function getMaxShuffle($deck)
 {
 switch ($deck) {
 case 1:  return 1;//should 0 but must 1 :-)
 case 2:  return 1;//3
 case 3:  return 2;
 case 4:  return 2;//5
 case 5:  return 4;//9
 case 6:  return 5;//11
 case 7:  return 3;
 case 8:  return 3;//7
 case 9:  return 8;//17
 case 10: return 5;
 case 11: return 10;
 case 12: return 9;//19
 case 13: return 8;//17
 case 14: return 13;//27
 case 15: return 4;
 case 16: return 4;//9
 case 17: return 11;
 case 18: return 17;//35
 case 19: return 11;
 case 20: return 9;//19
 case 21: return 6;//13
 case 22: return 11;
 case 23: return 22;
 case 24: return 20;
 case 25: return 7;
 case 26: return 25;//51
 }
 }
 
 // READ string from file (and trim)
 function read($filename)
 {
 $fp = fopen($filename, 'r', 0) or exit('couldnt open file');
 $data = trim(fread($fp, filesize($filename)));
 fclose($fp);
 return $data;
 }
 
 //FOR TESTING - undo operations
 //this is used to create decks that have a solution 100%
 function operate_undo($s)
 {
 $tmp = $this->cards;
 //reverse cause undo
 $s   = strrev($s);
 $len = strlen($s);
 
 for ($i = 0; $i < $len; $i++) {
 $index = $s{$i};
 if (is_numeric($index) && $i < $len-1 && is_numeric($s{$i + 1})) {
 $index .= $s{++$i};
 }
 switch ($s{$i}) {
 case 'C':
 //CUT (cut = undo cut)
 $tmp = $this->cut($tmp);
 break;
 case 'F':
 //FLIP (flip = undo flip)
 $tmp = $this->flip($tmp);
 break;
 default:
 //UNDO SHUFFLE x times
 for($ii = 1; $ii <= $index; ++$ii) {
 $tmp = $this->shuffle_undo($tmp);
 }
 break;
 }
 }
 return $tmp;
 }
 
 // initializing TIME
 function time_start()
 {
 $this->time = $this->get_microtime();
 }
 
 // return elapsed TIME - must call time_start() before
 function time_end()
 {
 return ($this->get_microtime() - $this->time);
 }
 
 // get microtime
 function get_microtime()
 {
 $mtime = explode(" ", microtime());
 return (double)($mtime[1]) + (double)($mtime[0]);
 }
 
 // human readable variable
 function print_r($var)
 {
 echo '<pre>';
 print_r($var);
 echo '</pre>';
 exit();
 }
 }
 
 // ERROR HANDLER - give additional informations about variables
 // in actual SCOPE
 function my_error_handler($errno, $errmsg, $file, $line, $vars)
 {
 //limit of 5 errors
 static $count;
 if (!isset($count)) {
 $count = 0;
 }
 $count++;
 if ($count > 5) {
 exit;
 }
 
 echo '<pre>';
 echo "<b>Error:</b> $errmsg \n";
 echo "<b>Line:</b> $line\n\n";
 print_r($vars);
 echo '</pre>';
 
 //when called like this => trigger_error('my error', E_USER_ERROR);
 if ($errno == E_USER_ERROR) {
 exit();
 }
 }
 ?>
 
 |  |  |