As seen today on fun-with-perl, the code that calculates the next power of two:

sub next_power_of_two { my %s; @s{1..shift} = (); local $_ = %s; return m{/(.*)}; }

(I've changed the original code a bit to pass "use warnings"), -- so the annual Perl Code Joke prize goes to shmem!

Replies are listed 'Best First'.
Re: next power of two
by jmcnamara (Monsignor) on Nov 26, 2007 at 14:47 UTC

    I don't know if it is the original that you refer to but here is a obfu/joke node from 2002 where I use this technique: Power Twool.
    sub powa2 { ; local %_ = @_ ; keys %_ = pop ; $_ = %_ ; split '\/' ; pop }

    --
    John.

      Well, I have been the poster to fwp... and I looked up your node after I posted (but I definitely knew there must be something around like that in the monastery). Here is the exciting answer from Uri:
      >>>>> "s" == shmem <gm@cruft.de> writes: s> You forgot an obscure corner of hashes: hashes in scalar context. s> Here's a a use - calculate the next power of 2 of a given number: s> sub next_power_of_two { s> my %s; s> @s{1..shift} = (); s> %s =~ '/'; s> return $'; s> } s> ;-) GACK!!! and that assume knowledge of the internals of hashes. not a good thing to teach! :) uri

      but your version is much more elegant, except perhaps the %s =~ '/' thingy ;-D

      update: and I posted it only because the discussion went into discussing the pros and cons of dispatch tables, oo, inheritance etc pp... in short, to introduce some fun again ;-)

      --shmem

      _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                    /\_¯/(q    /
      ----------------------------  \__(m.====·.(_("always off the crowd"))."·
      ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
Re: next power of two
by ikegami (Patriarch) on Nov 26, 2007 at 15:50 UTC

    It always returns 1 for me, unless you intend for your function to be called in list context. And since local $_ is buggy, you'd be best off avoid it.

    sub next_power_of_two { my %s; @s{1..shift} = (); return %s =~ m{/(.*)} && $1; }

    Update: Added local $_ fix.

Re: next power of two
by Anonymous Monk on Nov 26, 2007 at 13:07 UTC
    My perl uses 8 as the minimum number of buckets, so it's incorrect for values which are less than 4.
Re: next power of two
by trizen (Hermit) on Sep 11, 2011 at 10:54 UTC
    Or a faster version without using any regexp
    sub next_power_of_two ($) { my %s; @s{1..$_[0]} = (); return substr(%s,1+index(%s,'/')); } print next_power_of_two(257);

      About 50x faster still :)

      sub b{ my %s; keys %s = shift; undef $s{1}; substr %s, 1+index( %s,'/' ); }

      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
        ...and here is the fastest :-)

        sub next_power_of_two {2 << log($_[0]) / log(2)}
Re: next power of two
by JavaFan (Canon) on Sep 11, 2011 at 15:15 UTC
    Hmmm, doesn't always work:
    $ perl -wE '@h{1..shift}=(); say scalar %h;' 16384 12812/32768 $ perl -wE '@h{1..shift}=(); say scalar %h;' 32768 20636/32768