[EMAIL PROTECTED] wrote: > So as soon as you can after the game has finished, I would like > the golf "artists" to prepare a little description of your > solution, explaining how it works so beginners can understand, > describing you thought of it, and so on. > > I will give advance notice, at least: > Eugene (77 char solution) > Keith (74 char solution) > BooK (your gs solution, you know the one) > should definitely participate!
Thanks for the invitation, and thanks very much for running another contest! I see that several other people tried approaches using the ^ operator, but since mine was the shortest and probably the weirdest, I'd better explain. #!/usr/bin/perl -n $==$.&1;$=^=7 ..y*yuoeia***ord for/./g;$=||print Minus the obfuscation and golfish shortening, that's #!/usr/bin/perl -n $t = $. & 1; $t ^= 7 . tr/aeiouy// * ord for /./g; $t || print; The -n means that each line of the input file is read and assigned to $_. The next line sets a test variable to 0 if $. (the line number) is even and 1 if it's odd. The next line loops through all the letters in the line (the . in the regex doesn't match the newline, because there's no /s modifier, and /<whatever>/g in a list context returns all the matches). For each letter, the result of tr/aeiou// (1 if it's a vowel, 0 otherwise) is multiplied by the ASCII value of the letter, and then a 7 is appended to the front. The result of this strange operation is xored with the test variable. So for each letter in the word, one number is included in the xor: 797 for "a", 7101 for "e", 7105 for "i", 7111 for "o", 7117 for "u", 7121 for "y", and 70 for anything else. If you examine the bit patterns of those numbers carefully (or run an exhaustive test program), you'll find that there's no way to combine them with xor so that they produce 1, and that the only way they can produce 0 is if there's an even number of each (so that each number cancels itself out). That means the test value will never be 0 unless the line number is even and the word contains even numbers of "a"s, "e"s, "i"s, "o"s, "u"s, "y"s, and consonants. And an even number of consonants means an even length for the word if the vowel restrictions are met. The final line prints the word if the test variable is 0. It took me a while to work out a calculation that would give seven separate results (one for each vowel, and one for everything else) that could not be xored together in such a way that all the bits canceled out. I submitted a couple of entries that passed the test program but that I realized later weren't right. The first ones were this series: #!/usr/bin/perl -ln $%=0;$%^=ord for/[yuoeia]/g;$%||1&($.|y)))c)||print #!/usr/bin/perl -ln $%=$.&1;$%^=ord for/[yuoeia]/g;$%||1&y|||c||print #!/usr/bin/perl -ln $%=($.|y|||c)&1;$%^=ord for/[yuoeia]/g;$%||print Unfortunately, simply taking the ASCII value of each vowel (in these I was ignoring the consonants and checking the length separately) didn't give a set of values with the right property. The programs passed the test suite, but that was only because the test suite didn't contain any words with odd numbers of "e"s, "i"s, "u"s, and "y"s -- impudently unwieldy words such as might be used fruitlessly by flunkeyish yuppies (as I told Andrew). I withdrew the entry and substituted something longer. Later I came up with these: #!/usr/bin/perl -ln $%=($.|y|||c)&1;$%^=7+ord for/[yuoeia]/g;$%||print #!/usr/bin/perl -n $==$.&1;$=^=7+y*yuoeia***ord for/./g;$=||print But adding 7 to the ASCII values of vowels and using 7 for consonants wasn't the solution, either. I had neglected to look at the effect of the initial $.&1 term. While it wasn't possible for the values of the letters to cancel each other out, they could combine to cancel out the initial 1 resulting from an odd line number. If a word with odd numbers of "i"s and "o"s, like "point", occurred on an odd line, it would result in a 0 test variable and be printed erroneously. I conducted a search for a digit and operator that would fit the bill, and I found 7 (among other candidates) and the . operator. Alas, the . did have to be preceded by whitespace to avoid a syntax error, so I lost a stroke there. Andrew's choice of this hole was just right. Challenging enough to keep people away from their work and families until the last moment, and with multiple promising approaches. -- Keith C. Ivey <[EMAIL PROTECTED]> Washington, DC