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

Reply via email to