Zend - The PHP Company




Algorithms

Add Code


Numbers Game Solver  

Type: application
Added by: codewalkers
Entered: 13/12/2003
Last modified: 02/11/2002
Rating: - (fewer than 3 votes)
Views: 6360
This code solves the "numbers game", a popular UK television show. It is a winner of the Codewalkers PHP Coding Contest. See example URL for more info.


<?php
/*
Zack Coburn
zack@zackcoburn.com
http://www.zackcoburn.com
*/
list($usec$sec) = explode(" ",microtime()); 
$start=((float)$usec + (float)$sec); 

$ops=array("+","-","*");
$vars=array("a","b","c","d","e","f");
$random=array(round(mt_rand(2,100)),round(mt_rand(2,100)),round(mt_rand(2,100)),round(mt_rand(2,100)),round(mt_rand(2,100)),round(mt_rand(2,100)));
$count=0;

class 
numbersgame {

    function 
getmicrotime(){ 
        list(
$usec$sec) = explode(" ",microtime()); 
        return ((float)
$usec + (float)$sec); 
    } 

    function 
timelimit($grandtotal){
        global 
$log;
        global 
$start;
        global 
$input;
        if (
$_GET["checkme"]==1){
            
$end $this->getmicrotime();
            
$time sprintf('%.16f'$end $start);
            if (
$time>=29.8){
                exit;
            }            
        }elseif(
$_GET["checkme"]!=1){
            
$end $this->getmicrotime();
            
$time sprintf('%.16f'$end $start);
            if (
$time>=29.8){
                
$input=basename($input);
                
$writefile=fopen($input.".out","w");
                
fwrite($writefile,$log);
                echo 
$grandtotal;
                exit;
            }
        }
    }

    function 
parse_input($inputfile){
        
$handle fopen ($inputfile"r");
        
$input fread ($handlefilesize ($inputfile));
        
fclose ($handle);
        
$input=explode("n",$input);
        foreach(
$input as $key=>$value){
            
$problems[$key]=explode(",",$input[$key]);
        }
        return 
$problems;
    }
    
    function 
sets($numbers){
        
$set[0]=array($numbers[0],$numbers[1],$numbers[2],$numbers[3],$numbers[4],$numbers[5]);
        global 
$setsorted;
        
$setsorted=$set[0];
        
arsort($setsorted);
        
$set[2]=array();
        
$set[3]=array();
        
$set[4]=array();
        
$set[5]=array();
        
$set[6]=array();
        foreach(
$set[0] as $value1){
            foreach(
$set[0] as $value2){
                if (
$value2<>$value1){
                    
array_push($set[2],array($value1,$value2));
                    foreach(
$set[0] as $value3){
                        if (
$value3<>$value1 and $value3<>$value2){
                            
array_push($set[3],array($value1,$value2,$value3));
                            foreach(
$set[0] as $value4){
                                    if (
$value4<>$value1 and $value4<>$value2 and $value4<>$value3){
                                        
array_push($set[4],array($value1,$value2,$value3,$value4));
                                        foreach(
$set[0] as $value5){
                                            if (
$value5<>$value1 and $value5<>$value2 and $value5<>$value3 and $value5<>$value4){
                                                
array_push($set[5],array($value1,$value2,$value3,$value4,$value5));
                                                foreach(
$set[0] as $value6){
                                                    if (
$value6<>$value1 and $value6<>$value2 and $value6<>$value3 and $value6<>$value4 and $value6<>$value5){
                                                    
array_push($set[6],array($value1,$value2,$value3,$value4,$value5,$value6));
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return 
$set;
    }

    function 
expressions(){
        global 
$ops;
        global 
$vars;
        
//generate all expression permutations
        
$i=0;
        
$expressions[2]=array();
        
$expressions[3]=array();
        
$expressions[4]=array();
        
$expressions[5]=array();
        
$expressions[6]=array();
        foreach(
$ops as $op){
            
array_push($expressions[2],$vars[0].$op.$vars[1]);
        }
        foreach(
$ops as $op){
            foreach(
$expressions[2] as $expr){
                
array_push($expressions[3],$expr.$op.$vars[2]);
                
array_push($expressions[3],"(".$expr.")".$op.$vars[2]);
            }
        }
        foreach(
$ops as $op){
            foreach(
$expressions[3] as $expr){
                
array_push($expressions[4],$expr.$op.$vars[3]);
                
array_push($expressions[4],"(".$expr.")".$op.$vars[3]);
            }
        }
        foreach(
$ops as $op){
            foreach(
$expressions[4] as $expr){
                
array_push($expressions[5],$expr.$op.$vars[4]);
                
array_push($expressions[5],"(".$expr.")".$op.$vars[4]);
            }
        }
        foreach(
$ops as $op){
            foreach(
$expressions[5] as $expr){
                
array_push($expressions[6],$expr.$op.$vars[5]);
                
array_push($expressions[6],"(".$expr.")".$op.$vars[5]);
            }
        }
        return 
$expressions;
    }
    
    function 
duplicate($eq,$set=""){
        global 
$random;
        global 
$equations;
        global 
$used;
        global 
$vars;
        foreach(
$equations as $key=>$value){
            if (
$used[$key]==$set or $set==""){
                if (eval(
"return @(".str_replace($vars,$random,$equations[$key]).");")==eval("return @(".str_replace($vars,$random,$eq).");")){
                    return 
TRUE;
                }
            }
        }
        return 
FALSE;
    }

}

if (
$_GET["checkme"]==1){
?>
<!DOCTYPE html 
     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Codewalkers PHP Coding Contest - The Numbers Game - Zack Coburn</title>
</head>
<body>
<form name="form1" method="post" action="<?php echo $_SERVER["PHP_SELF"];?>?checkme=1">
  <strong>Numbers</strong>: 
  <input type="text" name="n1" size="2">
  <input type="text" name="n2" size="2">
  <input type="text" name="n3" size="2">
  <input type="text" name="n4" size="2">
  <input type="text" name="n5" size="2">
  <input type="text" name="n6" size="2">
  <br />
  <strong>Target Number</strong>: 
  <input type="text" name="n7" size="3">
  <br />
  <input type="submit" name="Submit" value="Find Solutions">
</form>
<?php 
if ($_POST["n1"]>and $_POST["n2"]>and $_POST["n3"]>and $_POST["n4"]>and $_POST["n5"]>and $_POST["n6"]>and $_POST["n7"]>0){
    
$numbersgame=new numbersgame;
    
$problem[0]=$_POST["n1"];
    
$problem[1]=$_POST["n2"];
    
$problem[2]=$_POST["n3"];
    
$problem[3]=$_POST["n4"];
    
$problem[4]=$_POST["n5"];
    
$problem[5]=$_POST["n6"];
    
$problem[6]=$_POST["n7"];

    
$expressions=$numbersgame->expressions();
    
$sets=$numbersgame->sets($problem);
    
$used=array(); //sets used
    
$solutions=array(); //solutions f=equation using a-f, corresponding with set used
    
$equations=array(); //equations with numbers, for display
    
for ($n=2;$n<=6;$n++){
        foreach(
$expressions[$n] as $key=>$expr){
            
$num=substr_count(strtr($expr,"abcdefg","aaaaaa"),"a");
            for (
$i=0;$i<count($sets[$num]);$i+=floor(count($sets[$num])/round(mt_rand(15,40),0))){
                
$set=$sets[$num][$i];
                
$replace=str_replace($vars,$set,$expr);
                
$test=eval("return @(".$replace.");");
                
$numbersgame->timelimit($grandtotal);
                if (
$test==$problem[6]){
                    
$eq=$replace;
                    foreach(
$setsorted as $key1=>$value1){
                        
$eq=str_replace($value1,$vars[$key1],$eq);
                    }
                    
$theset=sort($set);
                    if (
$numbersgame->duplicate($eq,$theset)==FALSE){
                        
$solutions[$count++]=$replace;
                        
$equations[$count]=$eq;
                        
$used[$count]=$theset;
                        echo 
$replace."<br />n";
                        
$grandtotal++;
                        break;
                    }
                    break;
                }
            }
        }
    }
}
?>
</body>
</html>
<?php
}elseif($_GET["checkme"]!=and $_GET["input"]<>""){
    
$input=$_GET["input"];
    
$numbersgame=new numbersgame;
    
$numbers=$numbersgame->parse_input($input);
    
$expressions=$numbersgame->expressions();
    
    
$grandtotal=0;
    foreach (
$numbers as $problem){
        
$log.=$problem[0].",".$problem[1].",".$problem[2].",".$problem[3].",".$problem[4].",".$problem[5].",".$problem[6]."n";
        
$sets=$numbersgame->sets($problem);
        
$used=array(); //sets used
        
$solutions=array(); //solutions f=equation using a-f, corresponding with set used
        
$equations=array(); //equations with numbers, for display
        
for ($n=2;$n<=6;$n++){
            foreach(
$expressions[$n] as $key=>$expr){
                
$num=substr_count(strtr($expr,"abcdefg","aaaaaa"),"a");
                for (
$i=0;$i<count($sets[$num]);$i+=floor(count($sets[$num])/round(mt_rand(15,40),0))){
                    
$set=$sets[$num][$i];
                    
$replace=str_replace($vars,$set,$expr);
                    
$test=eval("return @(".$replace.");");
                    
$numbersgame->timelimit($grandtotal);
                    if (
$test==$problem[6]){
                        
$eq=$replace;
                        foreach(
$setsorted as $key1=>$value1){
                            
$eq=str_replace($value1,$vars[$key1],$eq);
                        }
                        
$theset=sort($set);
                        if (
$numbersgame->duplicate($eq,$theset)==FALSE){
                            
$solutions[$count++]=$replace;
                            
$equations[$count]=$eq;
                            
$used[$count]=$theset;
                            
$log.=$replace."n";
                            
$grandtotal++;
                            break;
                        }
                        break;
                    }
                }
            }
        }
    }
}
?>


Usage Example


See the example


Rate This Script





Search



This Category All Categories