=begin conf PGAS = http://perlgolf.sourceforge.net/cgi-bin/PGAS/ version = 1.04 =end conf =begin tiebreaker alt-substr my $entry = shift; my $code = $entry->code; $code =~ s/\r\n|\n\r/\n/g; # Handle newlines the smart way. $code =~ s/\n+$//; # Free last newlines. $code =~ s{^#![-\w/.]+?perl}{}; # Shebang. my $vowels = $code =~ y/aeiouyAEIOUY//; my $alphan = $code =~ y/a-zA-Z0-9//; my $tie; if ( $alphan != 0 ) { $tie = $vowels / $alphan; $tie = .99 if $tie == 1; } else { $tie = .99; } return sprintf "%.2f", $tie; =end tiebreaker =head1 The Monthly Course: Interlinear Counts =begin hole interlin id = 5 type = script tiebreaker = alt-substr =end hole =head1 Goal For each sentence in an input stream, display the count of words, of vowels, and of alphanumeric character. Also display the count of vowels and of alphanumerics for each of as many words as will fit on a line. =head1 Specification =over 4 The program is a filter: it must read from STDIN, and send output to STDOUT. =item * The input will consist of zero or more paragraphs, possibly interspersed with blank lines. =item * A paragraph consists of one or more sentences, separated by sequences of whitespace characters (spaces or newlines). =item * A sentence consists of one or more words, separated by sequences of whitespace characters, and ending in a period. =item * A word contains at least one alphanumeric character (letter or digit), and optionally some punctuation (C<. , ; : ' " ( ) & />). Note: This means that punctuation characters can never occur alone. But except for the period, which must end a sentence, punctuation can occur anywhere in a word. =item * An underscore is not a letter. =item * All input lines are properly newline terminated, and do not contain binary 0. =item * All input files have a total size so that they will fit comfortably in memory and still allow you ample memory to play with. Please note that the input file can be empty. =item * You may assume ASCII as the character set but you may not use Unicode-specific semantics. =item * All sentences will be less than 200 characters long and contain less than 100 vowels. =item * For each sentence in the input, you are to print two lines. =over 4 =item 1 A line containing the number of words in the sentence, a colon, a horizontal tab, and up to 60 characters of text from the sentence, including the final period. Case must be preserved, and the words of the text must be separated by spaces to conform to the alignment described below. If the whole sentence, thus aligned, cannot be printed in the given width, the last three characters of that width must be replaced by periods. =item 2 A line containing the total number of vowels (aeiouy, regardless of case) in the sentence, a slash, the total number of alphanumeric characters in the sentence, a colon, and a horizontal tab, and similar counts for the words in the preceding line. That is, for each word that is visible, fully or in part, on the previous line, you must print the the number of vowels and alphanumerics in the whole word, again separated by a slash. These pairs of counts must be aligned with spaces to begin in the same columns as the corresponding words, and must be separated by at least one space; if that is not possible (because they would touch or overlap), extra spaces must be inserted in the text line instead. =back =back =head1 Tiebreaker The tiebreaker is calculated as the number of vowels in the script divided by the total number of letters and digits. =head1 General rules =over 4 =item * All output lines must be properly newline terminated. =item * You must not write to STDERR. =item * The program return code does not matter. =item * The average runtime of the program must be finite, but may be arbitrarily long. =item * The programs can be written as one or more lines. The score is the total number of characters you need (smaller is better). If your program is more than one line, you must count the newlines in between as one character each. The #! line is not counted. If you use options on the #! line, the options themselves are counted, including the leading space and ``-''. =item * If two (or more) golfers have the same score for the hole, the golfer with the lowest tie break score wins. =item * All programs must work on perl 5.6.1. =item * Assume total memory is < 2**32 bytes. The runtime of your programs should be finite. If your program takes more than a reasonable time to run, the validation of your solution by the referees can of course take more time than usual. =item * The programs may only use the perl executable, no other executables on the system are allowed (the program may use itself though). You may use any of the perl 5.6.1 standard core modules (perldoc perlmodlib for a list of those core modules). Your solutions must be portable in the sense that it should work on all versions of 5.6.1 everywhere (however, it's perfectly fine to abuse perl 5.6.1 bugs). =item * When tested, your script will be named interlin.pl, and you must assume your script to have file permissions of 0444 (that is read-only and non-executable for windows folks). =back =head1 Example Given the input: I am just a poor sample paragraph. Please don't treat me too hard as you split and separate me into vowels and stuff. You are to output the following: 7: I am just a poor sample paragraph. 11/27: 1/1 1/2 1/4 1/1 2/4 2/6 3/9 16: Please don't treat me too hard as you split and separat... 27/65: 3/6 1/4 2/5 1/2 2/3 1/4 1/2 3/3 1/5 1/3 4/8 =head1 Deadline The game starts June 1st (00:00 UTC) and ends June 8th (00:00 UTC). =head1 Test program A test program is provided to help screen entries. Any program that passes the test program should be submitted. If you are surprised that your solution passed the test program, please submit it anyway! That will help us identify bugs in the test program. For the test program to work correctly, you will have to name your script interlin.pl and place it in the same directory as your test program. Run the test program: $ perl tpr04.pl to verify that your entries are valid. Passing the test program does not assure your solution is valid. The referees have the final say. =head1 Submitting You can submit your solutions here (you'll notice it's the same page as the Leaderboard). Do not publish your solutions anywhere. That will spoil the game, as your solutions are meant to be secret. All solutions will be published at the end of the game. Prizes (provided by O'Reilly and ActiveState) will be awarded to veteran and beginner winners. A prize may also be awarded to any especially interesting artistic and/or unorthodox solutions. =head1 Leaderboard You can track your ranking through the leaderboard here. Beginners are encouraged to enter and there is a separate leaderboard for them. There is also a special leaderboard for teams. There will be no prizes awarded to the best team, other than the admiration of your fellow golfers. If you are in a team, you can't also play individually. =head1 Feedback We encourage you to send feedback as well as your ideas for future holes and tiebreakers to golf@theperlreview.com. =head1 Referees =over 4 =item * Samy Kankar =item * Ala Qumsieh =item * Lars Mathiesen =item * Dave Hoover =item * Jerome Quelin =back If you want to be a referee next month, drop us a note: golf@theperlreview.com =cut # # Here is the Games::Golf interface compatible code to test the entries # my @tests = ( # void input. [ "", "" ], # Lone letter in sentence. [ "a. f. This is a long long long long long long long very very very very very very very long sentence. f. Another long long long sentence, really long, I mean longer than the previous. a. And finally a sentence. a long word sdlfkjsdklfjsldfkjsldfkjsdlfkjsdlfkjsdlfkjsdflksdjflsdkjflsdkjfsldkfjslkfjslkdfjsldkfjsdlkfjsldkfjsldfkjsldkfjsdlfkj. A. ", "1:\ta. 1/1:\t1/1 1:\tf. 0/1:\t0/1 19:\tThis is a long long long long long long long very very... 28/75:\t1/4 1/2 1/1 1/4 1/4 1/4 1/4 1/4 1/4 1/4 2/4 2/4 1:\tf. 0/1:\t0/1 13:\tAnother long long long sentence, really long, I mean lo... 24/63:\t3/7 1/4 1/4 1/4 3/8 3/6 1/4 1/1 2/4 2/6 1:\ta. 1/1:\t1/1 4:\tAnd finally a sentence. 8/19:\t1/3 3/7 1/1 3/8 4:\ta long word sdlfkjsdklfjsldfkjsldfkjsdlfkjsdlfkjsdlfkjs... 3/125:\t1/1 1/4 1/4 0/116 1:\tA. 1/1:\t1/1 " ], # Empty line [ " ", "" ], # Empty line before paragraph. [ " Empty line before paragraph. ", "4:\tEmpty line before paragraph. 10/24:\t2/5 2/4 3/6 3/9 " ], # Empty line after paragraph. [ "Empty line after paragraph. ", "4:\tEmpty line after paragraph. 9/23:\t2/5 2/4 2/5 3/9 " ], # There must not be extra space after the dot printed. [ "Does your output have an extra space after the dot b. ", "11:\tDoes your output have an extra space after the dot b. 19/42:\t2/4 3/4 3/6 2/4 1/2 2/5 2/5 2/5 1/3 1/3 0/1 " ], # More than one space between words [ "There can be more than one space between words. And more than one line between paragraphs. ", "9:\tThere can be more than one space between words. 15/38:\t2/5 1/3 1/2 2/4 1/4 2/3 2/5 3/7 1/5 7:\tAnd more than one line between paragraphs. 14/35:\t1/3 2/4 1/4 2/3 2/4 3/7 3/10 " ], # No vowels in this sentence. [ "sjkdfh sksjdfhsjkd sdfjkshdfkj sdjkfh. ", "4:\tsjkdfh sksjdfhsjkd sdfjkshdfkj sdjkfh. 0/34:\t0/6 0/11 0/11 0/6 " ], # Systematic test, showing short last word in sentence: # Sentence length 58 to 61, word length 2 to 4. [ "Mind the gap; the sentence has 58 characters now: spli t. Mind the gap; the sentence has 58 characters now: spl it. Mind the gap; the sentence has 58 characters now: sp lit. Mind the gap; the sentence has 59 characters now: sspli t. Mind the gap; the sentence has 59 characters now: sspl it. Mind the gap; the sentence has 59 characters now: ssp lit. Mind the gap; the sentence has 60 characters now: ssspli t. Mind the gap; the sentence has 60 characters now: ssspl it. Mind the gap; the sentence has 60 characters now: sssp lit. Mind the gap; the sentence has 61 characters now: sssspli t. Mind the gap; the sentence has 61 characters now: sssspl it. Mind the gap; the sentence has 61 characters now: ssssp lit. ", "11:\tMind the gap; the sentence has 58 characters now: spli t. 13/44:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 1/4 0/1 11:\tMind the gap; the sentence has 58 characters now: spl it. 13/44:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 0/3 1/2 11:\tMind the gap; the sentence has 58 characters now: sp lit. 13/44:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 0/2 1/3 11:\tMind the gap; the sentence has 59 characters now: sspli t. 13/45:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 1/5 0/1 11:\tMind the gap; the sentence has 59 characters now: sspl it. 13/45:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 0/4 1/2 11:\tMind the gap; the sentence has 59 characters now: ssp lit. 13/45:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 0/3 1/3 11:\tMind the gap; the sentence has 60 characters now: ssspli t. 13/46:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 1/6 0/1 11:\tMind the gap; the sentence has 60 characters now: ssspl it. 13/46:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 0/5 1/2 11:\tMind the gap; the sentence has 60 characters now: sssp lit. 13/46:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 0/4 1/3 11:\tMind the gap; the sentence has 61 characters now: sssspl... 13/47:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 1/7 11:\tMind the gap; the sentence has 61 characters now: sssspl... 13/47:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 0/6 11:\tMind the gap; the sentence has 61 characters now: ssssp ... 13/47:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 0/5 " ], # Systematic test, leaving part of last word in sentence: # Sentence length to 61 to 63, left part -1 to 1. (Length 60 covered above) [ "Mind the gap; the sentence has 61 characters now: sssspl it. Mind the gap; the sentence has 61 characters now: ssssp lit. Mind the gap; the sentence has 61 characters now: ssss plit. Mind the gap; the sentence has 62 characters now: sssssp lit. Mind the gap; the sentence has 62 characters now: sssss plit. Mind the gap; the sentence has 62 characters now: ssss split. Mind the gap; the sentence has 63 characters now: ssssss plit. Mind the gap; the sentence has 63 characters now: sssss split. Mind the gap; the sentence has 63 characters now: ssss ssplit. ", "11:\tMind the gap; the sentence has 61 characters now: sssspl... 13/47:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 0/6 11:\tMind the gap; the sentence has 61 characters now: ssssp ... 13/47:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 0/5 11:\tMind the gap; the sentence has 61 characters now: ssss p... 13/47:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 0/4 1/4 11:\tMind the gap; the sentence has 62 characters now: sssssp... 13/48:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 0/6 11:\tMind the gap; the sentence has 62 characters now: sssss ... 13/48:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 0/5 11:\tMind the gap; the sentence has 62 characters now: ssss s... 13/48:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 0/4 1/5 11:\tMind the gap; the sentence has 63 characters now: ssssss... 13/49:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 0/6 11:\tMind the gap; the sentence has 63 characters now: sssss ... 13/49:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 0/5 11:\tMind the gap; the sentence has 63 characters now: ssss s... 13/49:\t1/4 1/3 1/3 1/3 3/8 1/3 0/2 3/10 1/3 0/4 1/6 " ], # Systematic test, truncating internal word in sentence:b # Word length 1 to 4, left part -1 to 1. [ "Mind the dots now; 56 characters before the next word: a word. Mind the dots now; 57 characters before the next word:: a word. Mind the dots now; 58 characters before the next word::: a word. Mind the dots now; 56 characters before the next word: no word. Mind the dots now; 57 characters before the next word:: no word. Mind the dots now; 58 characters before the next word::: no word. Mind the dots now; 56 characters before the next word: the word. Mind the dots now; 57 characters before the next word:: the word. Mind the dots now; 58 characters before the next word::: the word. ", "12:\tMind the dots now; 56 characters before the next word: a... 15/48:\t1/4 1/3 1/4 1/3 0/2 3/10 3/6 1/3 1/4 1/4 1/1 12:\tMind the dots now; 57 characters before the next word:: ... 15/48:\t1/4 1/3 1/4 1/3 0/2 3/10 3/6 1/3 1/4 1/4 12:\tMind the dots now; 58 characters before the next word:::... 15/48:\t1/4 1/3 1/4 1/3 0/2 3/10 3/6 1/3 1/4 1/4 12:\tMind the dots now; 56 characters before the next word: n... 15/49:\t1/4 1/3 1/4 1/3 0/2 3/10 3/6 1/3 1/4 1/4 1/2 12:\tMind the dots now; 57 characters before the next word:: ... 15/49:\t1/4 1/3 1/4 1/3 0/2 3/10 3/6 1/3 1/4 1/4 12:\tMind the dots now; 58 characters before the next word:::... 15/49:\t1/4 1/3 1/4 1/3 0/2 3/10 3/6 1/3 1/4 1/4 12:\tMind the dots now; 56 characters before the next word: t... 15/50:\t1/4 1/3 1/4 1/3 0/2 3/10 3/6 1/3 1/4 1/4 1/3 12:\tMind the dots now; 57 characters before the next word:: ... 15/50:\t1/4 1/3 1/4 1/3 0/2 3/10 3/6 1/3 1/4 1/4 12:\tMind the dots now; 58 characters before the next word:::... 15/50:\t1/4 1/3 1/4 1/3 0/2 3/10 3/6 1/3 1/4 1/4 " ], # Some long words... what happens if there's only one [ "Antisupercalifragilisticexpialidisestablishmentarianistical. Antisupercalifragilisticexpialidisestablishmentarianisticity. Antisupercalifragilisticexpialidisestablishmentarianisticness. This is filler to get even closer to 60 characters; Antisupercalifragilisticexpialidisestablishmentarianistical. ", "1:\tAntisupercalifragilisticexpialidisestablishmentarianistical. 25/59:\t25/59 1:\tAntisupercalifragilisticexpialidisestablishmentarianistic... 26/60:\t26/60 1:\tAntisupercalifragilisticexpialidisestablishmentarianistic... 25/61:\t25/61 11:\tThis is filler to get even closer to 60 characters; A... 39/100:\t1/4 1/2 2/6 1/2 1/3 2/4 2/6 1/2 0/2 3/10 25/59 " ], # Last: 99/199 [ "Internationalizational-internationalizational-internationalizational-internationalizational-internationalizational-internationalizational-internationalizational-internationalizational-internationalizationals. ", "1:\tInternationalizational-internationalizational-internation... 99/199: 99/199 "] ); # Ok, here's the real thing. foreach my $set ( @tests ) { $test->aioee( "", $set->[0], $set->[1], "", undef ); }