File indexing completed on 2024-06-16 03:38:29

0001 <?php
0002 // Convert Guess24-difficulty.csv and Guess24-solutions.csv into a json file with required informations
0003 // Usage from guess24 directory: $ php build-datas.php
0004 // Output a report on stdout and a json file for the activity.
0005 
0006 $outputFile = "../resource/guess24.json";
0007 $difficultyFile = "Guess24-difficulty.csv";
0008 $solutionFile = "Guess24-solutions.csv";
0009 $limitRate = 80.0;
0010 $verbose = false;
0011 $noSolutions = false;
0012 
0013 $short_options = "vschr:";
0014 $long_options = ["verbose", "solutions", "help", "rate:"];
0015 $options = getopt($short_options, $long_options);
0016 
0017 if(isset($options["v"]) || isset($options["verbose"])) {
0018     $verbose = true;
0019 }
0020 if(isset($options["s"]) || isset($options["solutions"])) {
0021     $noSolutions = true;
0022 }
0023 if(isset($options["r"]) || isset($options["rate"])) {
0024     $limitRate = isset($options["r"]) ? $options["r"] : $options["rate"];
0025     if (is_numeric($limitRate))
0026         $limitRate = (float) $limitRate;
0027     else {
0028         print("Rate parameter should be numeric.\n");
0029         exit(1);
0030     }
0031 }
0032 
0033 if(isset($options["h"]) || isset($options["help"])) {
0034     print("Usage: php build-datas.php [OPTIONS]\n");
0035     print("Create file `$outputFile` from `$difficultyFile` and `$solutionFile`.\nPrint a report on stdout.\n\n");
0036     print("Options\n");
0037     print("  -v, --verbose              print informations on rejected formulas.\n");
0038     print("  -s, --solutions            no solutions in output file.\n");
0039     print("  -r, --rate [LIMITRATE]     set minimum solved rate required (default 80).\n");
0040     print("  -h, --help                 display this help and exit.\n");
0041     exit(0);
0042 }
0043 
0044 // First line contains csv headers
0045 function stripFirstLine($text) {
0046     return substr($text, strpos($text, "\n") + 1);
0047 }
0048 
0049 $solutions = array();
0050 $problems = array();
0051 $rejected = 0;
0052 // Load files, remove non-breaking spaces and split into an array
0053 $ranked   = preg_split("/\n/", stripFirstLine(trim(preg_replace("/\xc2\xa0/", '', file_get_contents($difficultyFile)))));
0054 $solutext = preg_split("/\n/", stripFirstLine(trim(preg_replace("/\xc2\xa0/", '', file_get_contents($solutionFile)))));
0055 
0056 foreach($solutext as $sol) {
0057     $sols = preg_split("/,/", $sol);
0058     array_shift($sols);
0059     $puz = trim(array_shift($sols));
0060     while (trim($sols[array_key_last($sols)]) === "") {   // Remove empty solutions
0061         array_pop($sols);
0062     }
0063     $translatedSols = Array();
0064     foreach($sols as $idx => $val) {
0065         $val = preg_replace(array("/×/", "/÷/"), array("*", "/"), trim($val));
0066         $val = trim($val);
0067         $result = 0;
0068         $sols[$idx] = $val;
0069         if (preg_match_all("/\([^\)]+\)/", $val, $matches)) {    // Check for rational intermediate result
0070             foreach($matches[0] as $formula) {
0071                 $formula = substr($formula, 1, strlen($formula) - 2);
0072                 eval("\$result = $formula;");
0073                 if ($result != floor($result)) {
0074                     if ($verbose)
0075                         print("$puz solution $val rejected: ($formula) = $result\n");
0076                     array_splice($sols, $idx, 1);
0077                     $rejected++;
0078                     continue 2;
0079                 }
0080             }
0081         }
0082         $translatedSols[] = $val;
0083     }
0084     $solutions[$puz] = $translatedSols;
0085 }
0086 foreach($ranked as $line) {
0087     list($rank, $puzzle, $amt, $solvedRate, $sigmaMean, $sigmaSTD) = preg_split("/,/", $line);
0088     $puzzle = trim($puzzle);
0089     $solvedRate = (double) substr($solvedRate, 0, strlen($solvedRate) - 1);
0090     if (($solvedRate > $limitRate) && count($solutions[$puzzle])) {
0091         $problems[] = array(
0092             'puzzle' => $puzzle,
0093             'solutions' => $solutions[$puzzle]
0094         );
0095     }
0096 }
0097 
0098 $difficount = array(0, 0, 0);
0099 foreach($problems as $num => $problem) {
0100     $complexity = 3;
0101     foreach($problem['solutions'] as $solution) {
0102         if (preg_match("/\//", $solution)) {    // if one solution has divide
0103             $complexity = min($complexity, 3);
0104             continue;
0105         }
0106         if (preg_match("/\*/", $solution)) {    // if one solution has multiply
0107             $complexity = min($complexity, 2);
0108             continue;
0109         }
0110         $complexity = min($complexity, 1);      // if one solution has no multiply nor divide
0111     }
0112     $problems[$num]['complexity'] = $complexity;
0113     if ($noSolutions)
0114         unset($problems[$num]['solutions']);
0115     $difficount[$complexity - 1]++;
0116 }
0117 
0118 file_put_contents($outputFile, json_encode($problems, JSON_PRETTY_PRINT));
0119 
0120 // Statistics on stdout
0121 $total = $difficount[0] + $difficount[1] + $difficount[2];
0122 print("Problems with a solved rate greater than $limitRate%\n");
0123 print(str_repeat("-", 20)."\n");
0124 print("Complexity 1: {$difficount[0]} problems\n");
0125 print("Complexity 2: {$difficount[1]} problems\n");
0126 print("Complexity 3: {$difficount[2]} problems\n");
0127 print("Total: $total problems\n");
0128 print(str_repeat("-", 20)."\n");
0129 print("Output file: $outputFile\n");
0130 print("Output file size: ".filesize($outputFile)." bytes\n");
0131 print("$rejected solutions rejected for a rational intermediate result\n");
0132 
0133 ?>