<?php

////
//// RULES
////

// secret function generates data points
$hidden_code = "n*(n+1)/2+pow(n,3)/10";

// number of additional data points to be given past where hypothesis fails
$num_hints = 3;

// max number of terms user can match
$max_terms = 20;

////
//// GAME LOGIC
////

// collect users form post
$hypothesis = trim($_REQUEST['hypothesis']);

if(!strlen($hypothesis)) {
    $hypothesis = "1";
}   

// fix some common syntax errors
$hypothesis = preg_replace("/(\b\w)(\()/", "$1*$2", $hypothesis);
$hypothesis = preg_replace("/(\))(\w)/", "$1*$2", $hypothesis);

// beautify a version for printing
$pretty_hypothesis = $hypothesis;
$pretty_hypothesis = preg_replace("/\b(\w+)\b/", "<span class=\"func\">$1</span>", $pretty_hypothesis);
$pretty_hypothesis = preg_replace("/\b([nN])\b/", "<span class=\"parm\">n</span>", $pretty_hypothesis);

// save this code
$user_code = preg_replace("/\b([nN])\b/", "n", $hypothesis);

// define functions from code strings

function f_hidden($n) {
    global $hidden_code;
    $code = preg_replace("/n/", $n, $hidden_code);
    eval("\$res = intval($code);");
    return $res;
}

function f_user($n) {
    global $user_code;
    $code = preg_replace("/n/", $n, $user_code);
    eval("\$res = intval($code);");
    return $res;
}


// fill up data points while hypothesis fits
$sequence = Array();
$hints_remaining = $num_hints;
for($n = 1; $n < $max_terms; $n++) { // may terminate early!

    $hidden = f_hidden($n);
    $user = f_user($n);
        
    if($hidden != $user) {
        $hints_remaining--;
        $user = "<span class=\"wrong\">$user</span>";
    }
    
    if(0 == $hints_remaining) {
        break;
    }
    
    $sequence[] = Array($n,$hidden,$user);    

} // for n

// check victory
if($n == $max_terms) {
    $victory = true;
}


////
//// RENDERING
////

?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"><html>
<head> <title>Sequence Sleuth</title> <style>    math { font-size: large; }
    parm { font-weight: bolder; }
    wrong { color: red; }
    func { font-style: italic; } </style></head>
<body>

<h1>Sequence Sleuth</h1>

<p>Discover a formula that fits the provided data points.  As your model improves, more data points will be revealed.</p>


<h3>Experiment</h3>
<table>
<tr><td>Hypothesis:</td><td class="math">f(<span class="parm">n</span>) = <?=$pretty_hypothesis?></td></tr>
<?php if($victory) { ?>
<tr><td><b>Victory!</b></td><td>Your hypothesis fits the data beyond the threshold for a layman to actually care. </td></tr>
<?php } ?>
</table>

<form action="<?=$_SERVER['PHP_SELF']?>" method="POST">
f(<span class="parm">n</span>) = <input type="text" name="hypothesis" value="<?=$hypothesis?>" /><br>
<input type="submit" value="Verify" /> <a href="http://us2.php.net/manual/en/ref.math.php">language reference</a>
</form>

<h3>Results</h3>
<table>
<thead>
<tr><td>&nbsp;</td><td>Data</td><td>Guess</td></tr>
</thead>
<tbody>
<tbody>
<?php
    foreach($sequence as $term) {
        $index= $term[0];
        $data = $term[1];
        $hypo = $term[2];
        print("<tr><td>f(<span class=\"parm\">$index</span>) = <td>$data</td><td>$hypo</td></tr>\n");
    }
?>
</tbody>
</tbody>
</table>

</body>
</html>