Eugene van der Pijll wrote: > > Among the entries, there were some that had something extra. They used a > new, unique or surprising technique, used an unusual method, or were > just ununderstandable. Some of these are: > > Kolakoski: Rick Klement (54.25) > Mtv Europe (56.18) > Rick Klement (57.20) > > I'd like to invite the authors of these solutions to explain these > solutions to the public, or at least the original bits.
57.20 s/./$ARGV[1&pos]x$&/ge*/.{$ARGV[$_||=2]}/?print$&,$/:do$0 The infamous "[$_||=2]" perl bug. hehehe. This started life (almost) as: $_=2;s/./@ARGV[$|--]x$&/geuntil$|=/(.{$ARGV[2]})./;print$+,$/ then I found the pos trick, to: $_=2;s/./@ARGV[1&pos]x$&/geuntil/(.{$ARGV[2]})./;print$+,$/ I wanted to pull the extra . in the pattern (because it look messy, and I hoped to save those three strokes. That . is really there to make sure the s/// runs at least once, because otherwise /.{$ARGV[2]}/ would match and the s/// would not run. To force s/// to run, I reshuffled to: $_||=2until s/./@ARGV[1&pos]x$&/ge,/.{$ARGV[2]}/;print$&,$/ Since one of the tricks of golf is to remove duplicated elements, I looked at the two '2's, and ask the natural question "can I get away with only one '2'?" Well, my natural impulse was to move the ||=2 inside the subscript, which lead to: s/./$ARGV[1&pos]x$&/geuntil/(.{$ARGV[$_||=2]})./;print$+,$/ Now I only used one '2', and it looked shorter, so I quickly ran it through the test program to get a score, and it worked :) Then I took a good stare at it: it couldn't work. I'll get back to that. I kept staring at that awkward /(.{$ARGV[2]})./ and wanted to get to /.{$ARGV[2]}/ to save three strokes. The problem was that I started with an initial value of '2', so I had to run the s/// once before I could do the test, and the until tests first (do{}until would fix that, but at too high a cost). That lead me to: 1until s/./@ARGV[1&pos]x$&/ge,/.{$ARGV[$_||=2]}/;print$&,$/ which won't work, because the initialization happens after the first run of s///, so that lead to: 1until s/./@ARGV[1&pos]x$&/ge*/.{$ARGV[$_||=2]}/;print$&,$/ which does work, because the first s/// fails (empty string), while the first // succeeds, so it goes around again, where the s/// will succeed, but the // will fail until the sequence is long enough. The * is there so that both must succeed before the print. I kept looking at the $_||=2 as stuck at a value of 2 (perl bug - I said it couldn't work). Now the 1until ; is eight strokes where ?:do$0 is six, so I could quickly shorten it to: s/./$ARGV[1&pos]x$&/ge*/.{$ARGV[$_||=2]}/?print$&,$/:do$0 which is the 57.20 I submitted, and how I got to it. The perl bug: If you assume that [$_||=2] somehow sticks at 2, it's a perl bug, and with that bug, the whole thing makes perfect sense. Bugs are OK according to the rules: "however, it's perfectly fine to abuse perl 5.6.1 bugs". I figured that was what was happening here. It would have been interesting to chase down exactly what the bug was, but there was still a golf game in progress, and I had more golfing to do - there's always more golfing to do until the game ends. This solution quickly (16 hours later) got replaced by a shorter one that did not have the $_||=2 in it, so I stopped thinking about it. It turns out the whole situation can be interpreted as not a bug at all. Adding some debug, it shows that the subscript in question really is the Kolakoski number , and since that is a large number, usually refers to an undefined element of the @ARGV array. Substituting an undefined value into the regex gives /.{}/ and since (from perlre) the empty {} is not a recognized quantifier, it is really interpreted as /.\{\}/, which will not match. also see: regcomp.c: "regcurly - a little FSA that accepts {\d+,?\d*}" How does it stop? It's expected behavior - hehehe. I refer you to: http:[EMAIL PROTECTED]/msg00552.html So eventually (really pretty quickly) the Kolakoski number overflows and a subscript of -1 is used, which points to the correct count. Lesson to be learned: try something before you say "that can't work" :) -- Rick Klement