HBH PHP Competition RESULTS
The winners have been chosen and we had some stiff competition to be honest.
The winners are:
1st place: system_meltdown (Score: 69.813)
2nd place: ynori7 (Score: 77.147)
3rd place: define (Score: 89.835)
Congratulations!
The winners are decided and if you got a higher score on your own computer, that doesn't matter really. The scores change from computer to computer and fortunally / unfortunally, my computer was the judge.
And thanks to everyone that participated this contest! I've at least learned that the next competition I am going to hold is going to be alot more detailed.
And again, thanks to jjbutler88 that made the original script in his very bad php (haha). If it weren't for his skills to code bad php (and good php if he wants) this wouldn't have been possible!
//
// script written by jjbutler88 for the HBH PHP optimization competition, organised by -cL
// Probably the worst script I have written in my entire life. Coding angst supressed by listening to 'Clair de Lune' on repeat :)
//
echo "The following script is to be optimised to run the fastest by running the code inbetween the comments.<br/>";
echo "The file 'words.txt' must be opened and read. Then the words contained in the file must be seperated into the following catagories (words can fall into more than 1 category):<br/><br/>";
echo "+ Letters only<br/>";
echo "+ Contains letters and numbers<br/>";
echo "+ Contains punctuation<br/>";
echo "<br/>The arrays must contain no duplicates, and must be sorted alphanumerically where possible.";
echo "<br/>Output begins below:<br/>";
echo "<br/>-----------------------------------------------------------------------------------------<br/>";
$startTime = explode(" ", microtime());
///////////////////////////////////
// DO NOT EDIT ABOVE THIS LINE! //
//////////////////////////////////
/*
Relative path so PHP doesn't have to guess
Get rid of any \r\n lines or empty ones
*/
$words = file( "./words.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES );
$words = array_unique( $words ); // Remove any dupes early, save sorting them and then removing
natsort( $words ); // Natural sort, so it will go 1, 2, 3, 10, rather than 1, 10, 2, 3
$types = array(); // Initialise an array which will become mutidimensional to hold the different types
foreach( $words as $word ) // Loop through each word
{
$word = trim( $word ); // Trim \r\n characters from the word
switch( $word ) // Switch rather than an if-else block to save resources
{
case ctype_alpha( $word ): // No need to use regex as ctype works fine
$types[0][] = $word; // $array[] = "value" rather than array_push( $array, "value" ), no need for function overhead
break;
case ctype_alnum( $word ): // Same as above ^_^
$types[1][] = $word;
break;
default: // If they're not a-zA-Z0-9 then they obvs. have punctuation
$types[2][] = $word;
break;
}
}
$letters = implode( ", ", $types[0] ); // Implode the a-zA-Z array into a comma separated string
$alnum = implode( ", ", $types[1] ); // Implode the a-zA-Z0-9 array into a comma separated string
$punc = implode( ", ", $types[2] ); // Implode the punctuation array into a comma separated string
echo '+ Letters only: ', $letters, '<br/><br/>+ Contains letters and numbers: ', $alnum, '<br/><br/>+ Contains punctuation: ', $punc;
/* ^^ Rather than using .'s to concatenate the string, it's quicker to use commas to split them into separate arguments ^^ */
///////////////////////////////////
// DO NOT EDIT BELOW THIS LINE! //
//////////////////////////////////
$mem = memory_get_peak_usage();
$endTime = explode(" ", microtime());
echo "<br/>-----------------------------------------------------------------------------------------<br/>";
$executionTime = floatval($endTime[0] - $startTime[0]);
echo "Execution time: $executionTime ms<br/>";
echo "Peak memory allocation: ".$mem."<br/>";
$score = round($mem * $executionTime, 3);
echo "Score: $score - Lower is better!";
?>```
face palm Why didn't I think of ctype >.<! Oh well, I'm happy with what I did. We need more competitions like this :). Maybe a optimization test where we are not given the source at all and are just told what our script must output. Would make it a little harder and much more interesting I think.
Anyways, congratulations to all that won!
edit: retarded typo, said one instead of won :P
edit 2:
Tweaking systems code this came out .5 points better(after like 20 tests on each):
switch( $word ) // Switch rather than an if-else block to save resources
{
case ctype_alpha( $word ): // No need to use regex as ctype works fine
$letters .= ' '.$word; // $array[] = "value" rather than array_push( $array, "value" ), no need for function overhead
break;
case ctype_alnum( $word ): // Same as above ^_^
$alnum .= ' '.$word;
break;
default: // If they're not a-zA-Z0-9 then they obvs. have punctuation
$punc .= ' '.$word;
break;
}
Its not that big of a difference but, its worth mentioning for the future I suppose.
p4plus2 wrote: face palm Why didn't I think of ctype >.<! Oh well, I'm happy with what I did. We need more competitions like this :). Maybe a optimization test where we are not given the source at all and are just told what our script must output. Would make it a little harder and much more interesting I think.
Anyways, congratulations to all that won!
edit: retarded typo, said one instead of won :P
edit 2:
Tweaking systems code this came out .5 points better(after like 20 tests on each):
switch( $word ) // Switch rather than an if-else block to save resources
{
case ctype_alpha( $word ): // No need to use regex as ctype works fine
$letters .= ' '.$word; // $array[] = "value" rather than array_push( $array, "value" ), no need for function overhead
break;
case ctype_alnum( $word ): // Same as above ^_^
$alnum .= ' '.$word;
break;
default: // If they're not a-zA-Z0-9 then they obvs. have punctuation
$punc .= ' '.$word;
break;
}
Its not that big of a difference but, its worth mentioning for the future I suppose.
Yeah I knew this was possible, but I wanted them comma separated, not by a space, plus I prefer arrays :p
system_meltdown wrote:
Yeah I knew this was possible, but I wanted them comma separated, not by a space, plus I prefer arrays :p
Thats true, I suppose yours would be a much better method for a comma separated value. I guess its more a matter of preference.
edit: typo, I'm not typing so great today >.<
$words = explode( "\n", file_get_contents('words.txt') );
$alpha = array();
$alphaNum = array();
$punct = array();
foreach ( $words as $line ) {
if ( preg_match("/^[A-Za-z]+$/",$line) ) {
$alpha[] = $line;
}
if ( preg_match("/[a-zA-Z]+/",$line) && preg_match("/[0-9]+/",$line) ) {
$alphaNum[] = $line;
}
if ( preg_match("/[\W|_]+/",$line) ) {
$punct[] = $line;
}
}
$alpha = array_unique( $alpha );
$alphaNum = array_unique( $alphaNum );
$punct = array_unique( $punct );
sort( $alpha );
sort( $alphaNum );
sort( $punct );
echo '<p>+ Letters only: <br />';
print_r($alpha);
echo '</p><p>+ Contains letters and numbers: <br />';
print_r($alphaNum);
echo '</p><p>+ Contains punctuation: <br />';
print_r($punct);
Looks like we all had a fairly similar approach. Here's my code for those interested:
$lettersOnly = array();
$lettersAndNumbers = array();
$punctuation = array();
$words = array_unique(explode(' ', $file));
sort($words);
foreach($words as $word)
{
$word=trim($word);
if(ctype_alpha($word))
{
$lettersOnly[] = $word;
}
elseif(ctype_alnum($word))
{
$lettersAndNumbers[] = $word;
}
else
{
$punctuation[] = $word;
}
}
echo "+ Letters only: ";
print_r($lettersOnly);
echo "<br/><br/>+ Contains letters and numbers: ";
print_r($lettersAndNumbers);
echo "<br/><br/>+ Contains punctuation: ";
print_r($punctuation);```