Code of matteo
<?php

/*********************************************************/
/* Jumbled Words for PHP-Editors.com Coding Contest      */
/* (C) 2003 Matteo Beccati <matteo@beccati.com>          */
/*********************************************************/



$solveTimeLimit ini_get('max_execution_time');
if (!
$solveTimeLimit$solveTimeLimit 10000;
$solveMaxTime time() - 3;

echo 
"<pre>\n";
parseFile();

$result 0;
while (list(
$x, ) = each($entries))
{
    
$sol[$x] = array();
    
$result += solveEntry($entries[$x], $sol[$x]);
}

for (
$x=0; isset($sol[$x]); $x++)
    echo 
join(' '$sol[$x])."\n";

echo 
$result."\n";
echo 
"</pre>";



/***************************************************/
/* Parse input file                                */
/***************************************************/

function parseFile()
{
    global 
$entries$solveTimeLimit$solveMaxTime$solveMd5;
    
    
$buf file('lists.txt');
    
    
$e 0;
    
$c count($buf);
    
    
// Read words
    
for ($x 0$x $c$x++)
    {
        
$s trim($buf[$x]);
        
$last substr($s, -1);

        if (
$last == ',')
        {
            
// List found
            
$entries[$e][0] = explode(' 'substr($s0strlen($s)-1));
            
$entries[$e][1] = '';
            
            
// Set entry max score as the length of all the words
            
$entries[$e]['maxscore'] = strlen(join($entries[$e][0]));
        }
        else
        {
            
// (Part of) Sentence found
            
if (!isset($entries[$e][1])) $entries[$e][1] = '';
            
$entries[$e][1] .= str_replace(' '''$last == '.' substr($s0strlen($s)-1) : $s);

            if (
$last == '.')
                
// Last sentence line
                
$e++;
        }
    }
    
    
$total_score 0;
    for (
$x 0; isset($entries[$x][0]); $x++)
    {
        
$tmp join(''$entries[$x][0]);
        
        
// Calculate md5 of list and sentence to find duplicates (who knows? :)
        
$entries[$x]['md5'] = md5($tmp.$entries[$x][1]);
        
        
// Calculate max theoric score for the pair        
        
if (isset($solveMd5[$entries[$x]['md5']]))
            
// Pair already present, fake a null max score because only one would be evaluated
            
$entries[$x]['maxscore'] = 0;
        else
        {
            
$solveMd5[$entries[$x]['md5']] = true;
            
            
$jlen strlen($entries[$x][1])+2;
            
$lasting strlen(removeLetters(wordSort($entries[$x][1]), wordSort($tmp))); 
            
$lasting $lasting <= $lasting 2;
            
$e2 $entries[$x]['maxscore'] - $lasting;

            
$entries[$x]['maxscore'] = min($jlen$e2);
            
$total_score += $entries[$x]['maxscore'];
        }
    }
    
    
// Calculate available time for each entry
    
for ($x 0; isset($entries[$x][0]); $x++)
    {
        
$entries[$x]['timespan'] = floor($solveTimeLimit $entries[$x]['maxscore'] / $total_score);
        
        if (!
$entries[$x]['timespan'] && $entries[$x]['maxscore'])
        {
            
$entries[$x]['timespan'] = 1;
            
$solveMaxTime--;
        }
    }
    
    if (isset(
$entries[$x])) unset($entries[$x]);

    
// Sort entries by score, highest first    
    
uasort($entries"entries_sort_callback");
}

/***************************************************/
/* Sort letters in a word                          */
/***************************************************/

function wordSort($w)
{
    
$a = array();
    
$len strlen($w);
    
    for (
$x=0$x<$len$x++)
        
$a[] = $w{$x};
    
    
sort($a);
    
    return 
join(''$a);
}

/***************************************************/
/* Highlight bonus letters                         */
/***************************************************/

function highLight($w)
{
    for (
$i 0$i strlen($w[1]);$i++)
    {
        
$c $w[1]{$i};
        
$x strrpos($w[0], $c);
        
        
$w[0] = substr($w[0], 0$x).'{'.$c.'}'.substr($w[0], $x+1);
    }
    
    
$w[0] = str_replace('}{'''$w[0]);
    
$w[0] = str_replace('{''<span style="color: red">'$w[0]);
    
$w[0] = str_replace('}''</span>'$w[0]);
    
    return 
$w[0];
}

/***************************************************/
/* Removes needle letters from haystack            */
/***************************************************/

function removeLetters($needle$haystack)
{
    while (
$haystack !== '' && $needle !== '')
    {
        if ((
$x strpos($haystack$needle{0})) !== false)
        {
            
$haystack substr($haystack0$x).substr($haystack$x+1);
            
$needle substr($needle1);
        }
        else
            
$needle str_replace($needle{0}, ''$needle);
    }
    
    return 
$haystack;
}



/***************************************************/
/* Solve one entry                                 */
/***************************************************/

function solveEntry($e, &$sol)
{
    global 
$solveEntryBuffer$solveMaxScore$solveStop$solveMaxTime$solveMd5;
    
    if (
is_array($solveMd5[$e['md5']]))
    {
        
$sol $solveMd5[$e['md5']][0];
        return 
$solveMd5[$e['md5']][1];
    }
    
    
$solveMaxScore $e['maxscore'];
    
    foreach (
$e[0] as $k => $v)
    {
        
$solveMaxScore += strlen($v);
        
$e2[0][$k] = wordSort($v);
    }

    
uasort($e2[0], 'strlen_callback');
    
$e2[1] = wordSort($e[1]);
    
$solveMaxScore $e['maxscore'];

    
$solveStop false;
    
$solveMaxTime += $e['timespan'];
    
$solveEntryBuffer $e2[0];
    
$solve = new solver($e2[1]);
    
$score $solve->score;
    
    
$words = array();
    
    while (isset(
$solve->best) && isset($solve->children[$solve->best]))
    {
        
$words[] = array($e[0][$solve->best], $solve->children[$solve->best]->blank);
        
$solve $solve->children[$solve->best];
    }
    
    
$blanks '';
    foreach (
$words as $k => $v)
    {
        if (
strlen($blanks))
        {
            
$tmp $blanks;
            
$blanks $v[1];
            
$words[$k][1] = str_replace($tmp''$v[1]);
        }
        elseif (
strlen($v[1]))
            
$blanks $v[1];
    }
    
    
usort($words'sol_compare_callback');

    foreach (
$words as $v)
        
$sol[] = highLight($v);
    
    
$solveMd5[$e['md5']] = array($sol$score);
    
    return 
$score;
}

/***************************************************/
/* Sort callback functions                         */
/***************************************************/

function sol_compare_callback(&$a, &$b)
{
    
$r strlen($b[0]) - strlen($a[0]);
    
    return 
$r $r strcmp($a[0], $b[0]);
}

function 
entries_sort_callback($a$b)
{
    if (!
$a['maxscore'])
        return 
1;
    
    return 
$a['maxscore'] < $b['maxscore'] ? -1;
}



/***************************************************/
/* Solver class                                    */
/***************************************************/

class solver
{
    var 
$jumbled;
    var 
$history;
    var 
$score;
    var 
$blank;
    var 
$children;
    var 
$best;
    
    function 
solver($j$skip false)
    {
        global 
$solveEntryBuffer$solveEntryLen;
        
        
$this->jumbled $j;
        
$this->score 0;
        
$this->blank '';
        
$this->history = array();
        
        if (!
$skip)
        {
            
reset($solveEntryBuffer);
            while (list(
$k, ) = each($solveEntryBuffer))
            {
                
$solveEntryLen[$k] = strlen($solveEntryBuffer[$k]);
                
$this->unexplored[$k] = $k;
            }
            
            
$this->start(false);
        }
    }
    
    function 
__construct($j$skip false)
    {
        
$this->solver($j$skip);
    }

    function 
start($current false$blank '')
    {        
        global 
$solveEntryBuffer$solveEntryLen$solveMaxScore$solveStop$solveMaxTime;
        
        
$this->children = array();

        if (
$current !== false)
        {
            
$this->score += strlen($solveEntryBuffer[$current]);
            unset (
$this->unexplored[$current]);
            
$this->jumbled removeLetters($solveEntryBuffer[$current], $this->jumbled);
            
            if (
$blank != '')
            {
                
$this->blank .= $blank;
                
$this->history[] = $current.'-'.$blank;
            }
            else
                
$this->history[] = $current;
            
            if (!
$solveStop && $this->score >= $solveMaxScore || time() > $solveMaxTime)
                
$solveStop true;
        }
        
        
$jblen strlen($this->jumbled) + strlen($this->blank);
        
        for (;!
is_null($k key($this->unexplored));next($this->unexplored))
        {
            if (
$solveStop)
                break;

            if (
$solveEntryLen[$k] > $jblen)
                continue;
            
            
$s $solveEntryBuffer[$k];
            
            
$st removeLetters($this->jumbled$s);
            
            if (!
strlen($st))
                
$this->children[$k] = $this->clone($k);
            elseif (
strlen($st) == && strlen($this->blank) < && (!strlen($this->blank) || $this->blank{0} != $st))
                    
$this->children[$k] = $this->clone($k$st);
            elseif (
strlen($st) == && !strlen($this->blank) && $st{0} != $st{1})
                
$this->children[$k] = $this->clone($k$st);
        }
        
        
$max 0;
        for (
reset($this->children);!is_null($c key($this->children));next($this->children))
        {
            if (
$this->children[$c]->score $max)
            {

                
$max $this->children[$c]->score;
                
$this->best $c;
            }
        }
        
        if (
$max)
            
$this->score $max;
    }

    function clone(
$current$blank '')
    {
        
$new = new solver($this->jumbledtrue);
        
$new->history $this->history;
        
$new->score $this->score;
        
$new->blank $this->blank;
        
$new->unexplored $this->unexplored;
        
        
$new->start($current$blank);
        
        return 
$new;
    }
}

?>


Back to results


© Copyright 2003-2023 www.php-editors.com. The ultimate PHP Editor and PHP IDE site.