SlideShare une entreprise Scribd logo
1  sur  100
Télécharger pour lire hors ligne
THERE ARE SO MANY WAYS TO SHUFFLE IT




        TASMWTSI
there are so many ways to shuffle it

                koichi taniguchi
                           (@nipotan)
                         tokyo, japan
                     livedoor co.,ltd.


                         YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




the story line . . .

 •                                              …

     •
     • commit log

             In a department of our company,



                                    YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




the story line . . .

 •                                                   …

     •
     • commit log

     we each have the practice to report
     another colleague’s weekly activities with each other ...


                                         YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




the story line . . .

 •                                                …

     •
     • commit log

             at every Friday's regular meeting.



                                      YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




the story line . . .

 •                                                …

     •
     • commit log

 We each report what its own target did what in this week
 by checking the diffs out from the revision control system.


                                      YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




the story line . . .

 •                       …

     •
     •

 This changes the inside of our complicated system
 which is changing continually to be comprehensible to us.


                                     YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




the story line . . .

 •                        …

     •
     •

         And it's a good way to keep the quality of
         our entire source code.


                                      YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




the story line . . .

 •                   …

     •
     •

         Although, we need to decide that
         "who will check who?" to do it every week.


                                     YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




the story line . . .

 •                  …

     •
     •

         We each do live coding to make a decision
         in some rules of each season.


                                     YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




the story line . . .

 •       …

     •



             We call it
             "Time to Shuffle" ...


                                YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




the story line . . .

 •…                               ww

  •



      You may think "Just Shuffle? So?"
      Don't underestimate our performances.


                                YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




the story line . . .

 •…                             ww

  •



       Now I’m going to introduce you
       the masterpieces of our SHUFFLE.


                              YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




   season 1
"no rules"
This season is just to be familiar with
doing live coding for us.


                           YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




 season 1
"no rules"
  And there's NO highlights
  because it's boring.


                      YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




    season 2
"rand prohibited"
     In the second season,



                       YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




    season 2
"rand prohibited"
   rand() and similar function
   which is derived from rand() are prohibited.


                                 YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 2 "rand prohibited"
% perl -MTime::HiRes -le '@a=@b=qw(claire tracy mohinder
hiro matt nathan peter sylar);$t=Time::HiRes::time*100000%
$#b+1;for(0..$#a){print $a[$_].q{ => }.$b[($_+$t)%(scalar
@b)]}'
claire => hiro
tracy => matt
mohinder => nathan
hiro => peter
matt => sylar
nathan => claire
peter => tracy
sylar => mohinder


   First, microseconds are multiplied by hundred thousand.
   Then the random digit was made from them.


                                      YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 2 "rand prohibited"
% perl -MTime::HiRes -le '@a=@b=qw(claire tracy mohinder
hiro matt nathan peter sylar);$t=Time::HiRes::time*100000%
$#b+1;for(0..$#a){print $a[$_].q{ => }.$b[($_+$t)%(scalar
@b)]}'
claire => hiro
tracy => matt
mohinder => nathan
hiro => peter
matt => sylar
nathan => claire
peter => tracy
sylar => mohinder


     Probably all you guys come up with the same idea.



                                     YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 2 "rand prohibited"
% perl -MTime::HiRes -le '@a=@b=qw(claire tracy mohinder
hiro matt nathan peter sylar);$t=Time::HiRes::time*100000%
$#b+1;for(0..$#a){print $a[$_].q{ => }.$b[($_+$t)%(scalar
@b)]}'
claire => hiro
tracy => matt
mohinder => nathan
hiro => peter
matt => sylar
nathan => claire
peter => tracy
sylar => mohinder


        Also, it just moved the elements of the array.



                                       YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 2 "rand prohibited"
% perl -e '@m=@r=qw(claire tracy mohinder hiro matt nathan
peter sylar); sub r{hex(`md5sum /proc/stat|head -c8`)%@m}
while(++$c<100||scalar grep {$m[$_] eq $r[$_]} (0..$#m))
{$a=&r;$b=&r; @r[$a,$b] = @r[$b,$a]} printf "%-8s => %-8s
n", $m[$_], $r[$_] for (0..$#m);'
claire   => tracy
tracy    => peter
mohinder => hiro
hiro     => sylar
matt     => mohinder
nathan   => claire
peter    => nathan
sylar    => matt

          Next, it has the original random function.



                                       YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 2 "rand prohibited"
% perl -e '@m=@r=qw(claire tracy mohinder hiro matt nathan
peter sylar); sub r{hex(`md5sum /proc/stat|head -c8`)%@m}
while(++$c<100||scalar grep {$m[$_] eq $r[$_]} (0..$#m))
{$a=&r;$b=&r; @r[$a,$b] = @r[$b,$a]} printf "%-8s => %-8s
n", $m[$_], $r[$_] for (0..$#m);'
claire   => tracy
tracy    => peter
mohinder => hiro
hiro     => sylar
matt     => mohinder
nathan   => claire
peter    => nathan
sylar    => matt

 It recognizes a part of the produced MD5 message digest of
 kernel/system statistics (/proc/stat) as hex string,


                                     YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 2 "rand prohibited"
% perl -e '@m=@r=qw(claire tracy mohinder hiro matt nathan
peter sylar); sub r{hex(`md5sum /proc/stat|head -c8`)%@m}
while(++$c<100||scalar grep {$m[$_] eq $r[$_]} (0..$#m))
{$a=&r;$b=&r; @r[$a,$b] = @r[$b,$a]} printf "%-8s => %-8s
n", $m[$_], $r[$_] for (0..$#m);'
claire   => tracy
tracy    => peter
mohinder => hiro
hiro     => sylar
matt     => mohinder
nathan   => claire
peter    => nathan
sylar    => matt

           and the corresponding value of it
           is divided by the number of arguments.


                                      YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 2 "rand prohibited"
% perl -e '@m=@r=qw(claire tracy mohinder hiro matt nathan
peter sylar); sub r{hex(`md5sum /proc/stat|head -c8`)%@m}
while(++$c<100||scalar grep {$m[$_] eq $r[$_]} (0..$#m))
{$a=&r;$b=&r; @r[$a,$b] = @r[$b,$a]} printf "%-8s => %-8s
n", $m[$_], $r[$_] for (0..$#m);'
claire   => tracy
tracy    => peter
mohinder => hiro
hiro     => sylar
matt     => mohinder
nathan   => claire
peter    => nathan
sylar    => matt

               Then it returns the remainder.
               It is a random integer.


                                      YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 2 "rand prohibited"
% perl -e '@m=@r=qw(claire tracy mohinder hiro matt nathan
peter sylar); sub r{hex(`md5sum /proc/stat|head -c8`)%@m}
while(++$c<100||scalar grep {$m[$_] eq $r[$_]} (0..$#m))
{$a=&r;$b=&r; @r[$a,$b] = @r[$b,$a]} printf "%-8s => %-8s
n", $m[$_], $r[$_] for (0..$#m);'
claire   => tracy
tracy    => peter
mohinder => hiro
hiro     => sylar
matt     => mohinder
nathan   => claire
peter    => nathan
sylar    => matt

    And it tries to shuffle each elements completely
    but it might be given up if it spins over hundred times.


                                        YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




 season 3
  "increase
combinations
  possible"
  In the third season,



                     YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




      season 3
     "increase
   combinations
     possible"
We should increase all possible combinations
more than number of members.


                             YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




        season 3
       "increase
     combinations
       possible"
That is, just moving the elements is prohibited.
Instead, we can use rand() again from the season.


                                YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




 season 3
  "increase
combinations
  possible"
    We did it!



                 YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 3 "increase combinations possible"
-module(shuffle).
-export([main/1,comb/2]).

main(A) ->
 All = comb(A,A),
 Set = lists:nth(random:uniform(length(All)), All),
 output(Set).

output([]) -> true;
output([{A,B}|T]) ->
 io:format("~w => ~w~n", [A,B]),
 output(T).

comb([], _) -> [[]];
comb([H|T], B) ->
 [ [{H, X}|Rest] || X<-B--[H], Rest<-comb(T, B--[X]) ].


                                   Erlang?!



                                                YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 3 "increase combinations possible"
% erl
Erlang R14B (erts-5.8.1) [source] [rq:1] [async-threads:0] [hipe] [kernel-
poll:false]

Eshell V5.8.1 (abort with ^G)
1> c(shuffle).
{ok,shuffle}
2> shuffle:main([claire,mohinder,hiro,matt,nathan,peter,sylar]).
claire => mohinder
mohinder => nathan
hiro => matt
matt => sylar
nathan => claire
peter => hiro
sylar => peter
true


                    I'm not sure,
                    but it maybe works correctly.


                                                YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 3 "increase combinations possible"
% ruby -e 'a=b=%w(claire tracy mohinder hiro matt nathan
peter sylar); b=b.sort_by{rand} until (0..a.size-1).all?
{|i|a[i]!=b[i]};a.zip(b){|x,y| puts "%8s => %s" % [x,y]}'
  claire => nathan
   tracy => hiro
mohinder => peter
    hiro => matt
    matt => mohinder
  nathan => sylar
   peter => claire
   sylar => tracy


                         Ruby?!



                                    YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 3 "increase combinations possible"
% ruby -e 'a=b=%w(claire tracy mohinder hiro matt nathan
peter sylar); b=b.sort_by{rand} until (0..a.size-1).all?
{|i|a[i]!=b[i]};a.zip(b){|x,y| puts "%8s => %s" % [x,y]}'
  claire => nathan
   tracy => hiro
mohinder => peter
    hiro => matt
    matt => mohinder
  nathan => sylar
   peter => claire
   sylar => tracy


   Excuse me. This is Yet Another Perl Conference, isn't it.
   Why don't you use Perl?


                                       YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 3 "increase combinations possible"
% ruby -e 'a=b=%w(claire tracy mohinder hiro matt nathan
peter sylar); b=b.sort_by{rand} until (0..a.size-1).all?
{|i|a[i]!=b[i]};a.zip(b){|x,y| puts "%8s => %s" % [x,y]}'
  claire => nathan
   tracy => hiro
mohinder => peter
    hiro => matt
    matt => mohinder
  nathan => sylar
   peter => claire
   sylar => tracy


              By the way, is zip() cool, it isn’t?



                                         YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 3 "increase combinations possible"

% perl6 -e 'for ("foo", "bar",
"baz") Z ("qux", "quux", "corge") ->
$a, $b { say "$a => $b" }'
foo => qux
bar => quux
baz => corge


       We can use "Z" for zip() operator in perl6.
       But I’m not sure about perl6.


                                    YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




  season 4
"time trial"
  This season is like a time trial.



                           YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




     season 4
"time trial"
In addition,
it was laid down the most strict rules so far.


                               YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
•




        The rules of the season are...



                               YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
•
    •              arrayref
        arrayref




           write a perl subroutine which gets an
           arrayref of member list as the parameter ...


                                         YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
•
    •              arrayref
        arrayref




           and returns an arrayref of target members.



                                       YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
•
    •              arrayref
        arrayref
    •




               Increase all possible combinations
               more than number of members.


                                       YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
•
    •                arrayref
        arrayref
    •
    •



                   Eliminate the pairs that include
                   the target of someone is oneself.


                                           YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
•
    •              arrayref
        arrayref
    •
    •
    •


            Possibly faster than ever before.
            For comparison, we try to benchmark ...


                                       YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
•
    •              arrayref
        arrayref
    •
    •
    •


              10,000 times shuffle of 10 members,
              1,000 times shuffle of 1,000 members,


                                        YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
•
    •              arrayref
        arrayref
    •
    •
    •


            and 10 times shuffle of 10,000 members.



                                       YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
•
    •              arrayref
        arrayref
    •
    •
    •


         Then we evaluate the results comprehensively
         and assume which is the reigning champion.


                                      YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
•
    •              arrayref
        arrayref
    •
    •
    •
    •

               Preparing some tricks ahead of time
               and playing it is prohibited.


                                        YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
•
    •              arrayref
        arrayref
    •
    •
    •
    •
    •
              /

             Meet the any of following conditions,



                                        YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
•
    •               arrayref
         arrayref
    •
    •
    •
    •
    •
               /

        it gives "different results each time",
        "all possible combinations" and/or "even results".


                                         YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
sub shuffle {
    my $array = shift;
    my $array2;
    do {
        $array2 = [sort { rand(3)-1 } @$array];
    } while (grep $$array[$_] eq $$array2[$_], (0..$#$array));
    return $array2;
}




   At first, this is the interim champion.
   It’s not so fast because it’s the reference implementation.


                                        YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
sub shuffle {
   my $array = shift;
   my $n = $#$array;
   my @index = (0..$n);
   my $i;
   for (0..$n) {
       $i = int(rand($n));
       redo if $_ == $index[$i] || $i == $index[$_];
       ( $index[$_], $index[$i] ) = ( $index[$i], $index[$_] );
   }
   return [ @$array[@index] ];
}



 This is the 2nd champion.
 It works more than 4 times faster than the former champion.


                                         YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
sub shuffle {
    my @array = @{$_[0]};
    my ($i, $r) = scalar @array;
    while(--$i) {
        $r = rand($i);
        @array[$i, $r] = @array[$r, $i];
    }
    return @array;
}

    This is the 4th champion.
    Incidentally, it’s very similar to Fisher-Yates shuffle.


                                        YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
sub shuffle {
    my @array = @{$_[0]};
    my ($i, $r) = scalar @array;
    while(--$i) {
        $r = rand($i);
        @array[$i, $r] = @array[$r, $i];
    }
    return @array;
}

        You can find out the technique like this
        in perldoc -q shuffle (in perlfaq4).


                                    YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
sub shuffle {                                                    my @magic = ();
    return _shuffle(@_);                                         if ($is_odd){
    BEGIN{                                                           @sep = map{$_ + $MAGIC} @sep;
        my $MAGIC = 3;                                               @magic = @{$MAGIC[($R / $half /
        my @MAGIC = ([1,2,0], [2,0,1]);              $half) % 2]};
        srand;                                                   }
        my $R=int rand(1000000);                                 return [@$arg[@magic,
        sub _shuffle {                                                         $sep[6] .. $sep[7],
            my $arg = shift;                                                   $sep[4] .. $sep[5],
            my $n = scalar @$arg;                                              $sep[2] .. $sep[3],
            my $is_odd = $n % 2;                                               $sep[0] .. $sep[1]
            $n -= $MAGIC if $is_odd;                                    ]];
            my $half = $n / 2;                               }
            my $r_a = ($R / $half) % ($half);            }
            my $r_b = ($R % $half);                  }
            $R++;
            my @sep = (0 => $r_a,
                       $r_a+1 => $half - 1,
                       $half => $half + $r_b,
                       $half + $r_b + 1 => $n -1);



                 This is the 5th champion.
                 It doesn't shuffle accurately. It's so tricky.


                                                                YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
sub shuffle {                                                    my @magic = ();
    return _shuffle(@_);                                         if ($is_odd){
    BEGIN{                                                           @sep = map{$_ + $MAGIC} @sep;
        my $MAGIC = 3;                                               @magic = @{$MAGIC[($R / $half /
        my @MAGIC = ([1,2,0], [2,0,1]);              $half) % 2]};
        srand;                                                   }
        my $R=int rand(1000000);                                 return [@$arg[@magic,
        sub _shuffle {                                                         $sep[6] .. $sep[7],
            my $arg = shift;                                                   $sep[4] .. $sep[5],
            my $n = scalar @$arg;                                              $sep[2] .. $sep[3],
            my $is_odd = $n % 2;                                               $sep[0] .. $sep[1]
            $n -= $MAGIC if $is_odd;                                    ]];
            my $half = $n / 2;                               }
            my $r_a = ($R / $half) % ($half);            }
            my $r_b = ($R % $half);                  }
            $R++;
            my @sep = (0 => $r_a,
                       $r_a+1 => $half - 1,
                       $half => $half + $r_b,
                       $half + $r_b + 1 => $n -1);



         It works about 30% faster than Fisher-Yates shuffle.
         But It doesn't work at all under a specific condition.


                                                                YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
sub shuffle {                                                    my @magic = ();
    return _shuffle(@_);                                         if ($is_odd){
    BEGIN{                                                           @sep = map{$_ + $MAGIC} @sep;
        my $MAGIC = 3;                                               @magic = @{$MAGIC[($R / $half /
        my @MAGIC = ([1,2,0], [2,0,1]);              $half) % 2]};
        srand;                                                   }
        my $R=int rand(1000000);                                 return [@$arg[@magic,
        sub _shuffle {                                                         $sep[6] .. $sep[7],
            my $arg = shift;                                                   $sep[4] .. $sep[5],
            my $n = scalar @$arg;                                              $sep[2] .. $sep[3],
            my $is_odd = $n % 2;                                               $sep[0] .. $sep[1]
            $n -= $MAGIC if $is_odd;                                    ]];
            my $half = $n / 2;                               }
            my $r_a = ($R / $half) % ($half);            }
            my $r_b = ($R % $half);                  }
            $R++;
            my @sep = (0 => $r_a,
                       $r_a+1 => $half - 1,
                       $half => $half + $r_b,
                       $half + $r_b + 1 => $n -1);



                  If you want to read the code carefully,
                  Please wait the publication of this slide.


                                                                YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
sub shuffle {                                         MODULE = Foo PACKAGE = Foo
    return [Foo::fisher_yates(@{$_[0]})];             void
    BEGIN {                                           fisher_yates(...)
        my $use = sub {                               PROTOTYPE: @
            eval qq{ use $_[0]; };                    CODE:
            return $@ ? () : 1;                            UV i = items;
        };                                                 while (--i) {
        push @INC, qw(Foo/blib/lib Foo/blib/arch);             UV swap = (UV)(Drand01() * i);
        unless ($use->('Foo')) {                               SV *tmp = ST(swap);
            if (-d 'Foo') {                                    ST(swap) = ST(i);
                system(qw/rm -frv Foo/) && die $^E;            ST(i) = tmp;
            }                                              }
            system(qw/h2xs -A -n Foo/) && die $^E;         XSRETURN(items);
            chdir 'Foo' or die $!;                    XSUB
            open my $xs, '>', 'Foo.xs' or die $!;
            print $xs <<'XSUB';                                   close $xs;
#include "EXTERN.h"                                               (system($^X, 'Makefile.PL') ||
#include "perl.h"                                                     system('make')) && die $^E;
#include "XSUB.h"                                                 chdir '..' or die $!;
#include "ppport.h"                                               $use->('Foo') or die $@;
                                                                  print "-" x 50 . "n";
                                                              }
                                                          };
                                                      }



   This is the 6th champion. A Fisher-Yates XS implementation
   is embedded in a subroutine forcibly.


                                                                  YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial"
sub shuffle {                                         MODULE = Foo PACKAGE = Foo
    return [Foo::fisher_yates(@{$_[0]})];             void
    BEGIN {                                           fisher_yates(...)
        my $use = sub {                               PROTOTYPE: @
            eval qq{ use $_[0]; };                    CODE:
            return $@ ? () : 1;                            UV i = items;
        };                                                 while (--i) {
        push @INC, qw(Foo/blib/lib Foo/blib/arch);             UV swap = (UV)(Drand01() * i);
        unless ($use->('Foo')) {                               SV *tmp = ST(swap);
            if (-d 'Foo') {                                    ST(swap) = ST(i);
                system(qw/rm -frv Foo/) && die $^E;            ST(i) = tmp;
            }                                              }
            system(qw/h2xs -A -n Foo/) && die $^E;         XSRETURN(items);
            chdir 'Foo' or die $!;                    XSUB
            open my $xs, '>', 'Foo.xs' or die $!;
            print $xs <<'XSUB';                                   close $xs;
#include "EXTERN.h"                                               (system($^X, 'Makefile.PL') ||
#include "perl.h"                                                     system('make')) && die $^E;
#include "XSUB.h"                                                 chdir '..' or die $!;
#include "ppport.h"                                               $use->('Foo') or die $@;
                                                                  print "-" x 50 . "n";
                                                              }
                                                          };
                                                      }



                         It works about 2 times faster than
                         the former champion.


                                                                  YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial" side story




            As a side story.



                               YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial" side story




 Satoshi Ueda (gunyoki), all you saw him a little while ago,
 he is a former member of ours.


                                      YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial" side story



19:55:00 <gunyoki>      CPU                   kernel module
19:56:38 <gunyoki>            0




                     He said on IRC ...



                                         YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial" side story



19:55:00 <gunyoki>        CPU                   kernel module
19:56:38 <gunyoki>              0




       <gunyoki> I wrote a kernel module which can change
       the CPU expended time of the task structure.


                                           YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial" side story



19:55:00 <gunyoki>          CPU                   kernel module
19:56:38 <gunyoki>                0




       <gunyoki> It enable that the (not actual) time for any
       kind of calculation to be zero.


                                             YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial" side story
#include   <linux/kernel.h>                               static int proc_write(struct file *page, const char *buf,
#include   <linux/module.h>                               unsigned long len, void *data)
#include   <linux/sched.h>                                {
#include   <linux/proc_fs.h>                                      char tmp[64];
#include   <asm/uaccess.h>                                        long utime;
                                                                  struct task_struct *process;
#define PROC_NAME "driver/utime"                                  if (copy_from_user(tmp, buf, len))
                                                                          return -EFAULT;
static int pid;                                                   utime = simple_strtol(tmp, NULL, 0);
module_param(pid, int, 0666);                                     process = find_task_by_pid(pid);
                                                                  if (!process) {
static int proc_read(char *page, char **start, off_t                      printk("pid error: %dn", pid);
offset, int count, int *eof, void *data)                                  return -EFAULT;
{                                                                 }
        unsigned long outbyte;                                    printk("utime: %ld -> %ldn", process->utime,
        struct task_struct *process;                      utime);
        if (offset > 0) {                                         process->utime = utime;
                *eof = 1;                                         return len;
                return 0;                                 }
        }
        process = find_task_by_pid(pid);                  int init_module(void)
        if (!process) {                                   {
                printk("pid error: %dn", pid);                   struct proc_dir_entry *entry;
                *eof = 1;                                         entry = create_proc_entry(PROC_NAME, 0666, NULL);
                return 0;                                         if (entry == 0)
        }                                                                 return -EINVAL;
        outbyte = sprintf(page, "%ld", process->utime);           entry->read_proc = proc_read;
        printk("proc_read len = %lun", outbyte);                 entry->write_proc = proc_write;
        *eof = 1;                                                 return 0;
        return outbyte;                                   }
}
                                                          void cleanup_module(void)
                                                          {
                                                                  remove_proc_entry(PROC_NAME, NULL);


  kernel_module                                           }

                                                          MODULE_LICENSE("GPL2");



                                                                       YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial" side story
obj-m += foo.o

KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)

default:
        $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
        rm -f *.o *.ko *.mod.c




 makefile
                                   YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial" side story
sub shuffle {
    my $array = shift;
    our $pid;
    if ($pid == 0) {
        $pid = $$;
        open my $pid_file, '>/sys/module/foo/pid';
        print $pid_file $pid;
        close $pid_file;
    }
    open my $utime_file, '+</proc/driver/utime';
    my $utime = <$utime_file>;
    my $result = champion($array);
    print $utime_file $utime;
    close $utime_file;
    return $result;
}




  perl
                                                YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial" side story
sub shuffle {
    my $array = shift;
    our $pid;
    if ($pid == 0) {
        $pid = $$;
        open my $pid_file, '>/sys/module/foo/pid';
        print $pid_file $pid;
        close $pid_file;
    }
    open my $utime_file, '+</proc/driver/utime';
    my $utime = <$utime_file>;
    my $result = champion($array);
    print $utime_file $utime;
    close $utime_file;
    return $result;
}


                 He doesn’t write any shuffle code.

  perl
                                                YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




season 4 "time trial" side story
sub shuffle {
    my $array = shift;
                                                              a t
    our $pid;
    if ($pid == 0) {
                                                        h e
        $pid = $$;
        open my $pid_file, '>/sys/module/foo/pid';
                                                     c
        print $pid_file $pid;
        close $pid_file;

                                           l e
                               b
    }
    open my $utime_file, '+</proc/driver/utime';
    my $utime = <$utime_file>;


                            iva
    my $result = champion($array);


                          g
    print $utime_file $utime;


                    r
    close $utime_file;
    return $result;
}
                  o
         fHe doesn’t write any shuffle code.
      un
  perl
                                                YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




 final season
"lipstick on an
 after-image"
   Finally, it’s the final season.



                           YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




 final season
"lipstick on an
 after-image"
   This title comes from a SF novel,
   written by Yasutaka Tsutsui.


                           YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




 final season
"lipstick on an
 after-image"
  Prohibited characters are increasing
  week by week.


                           YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e ' # XXX your shuffle code here. '




                The basic format is a one-liner
                like above.


                                       YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e 'chomp(@m=<>);@i=(0..$#m);$j=@m;while
($j--) {$r=rand($j);@i[$j,$r]=@i[$r,$j]};for(0..$#m) {printf(qq{%s=>%s
n},$m[$_],$m[$i[$_]])}'




prohibits:



         At the start, there was no prohibited characters.



                                             YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e 'chomp(@m=<>);@i=(0..$#m);$j=@m;while
($j--) {$r=rand($j);@i[$j,$r]=@i[$r,$j]};for(0..$#m) {printf(qq{%s=>%s
n},$m[$_],$m[$i[$_]])}'




prohibits:



             Next, using "0", "s" and "t" were prohibited.



                                             YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e 'chomp(@m=<>);@i=(()..$#m);
$j=@m;while($j--) {$r=rand($j);@i[$j,$r]=@i[$r,$j]};for(()..
$#m) {warn $m[$_]." => ".$m[$i[$_]]."n"}'




prohibits: 0 s t



        In the early stage, we couldn’t use printf().
        warn() was used instead of it to output the result.


                                         YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e 'chomp(@m=<>);@i=(()..$#m);
$j=@m;while($j--) {$r=rand($j);@i[$j,$r]=@i[$r,$j]};for(()..
$#m) {warn $m[$_]." => ".$m[$i[$_]]."n"}'




prohibits: 0 s t



        Next, using "h", "k", "q" and " (double quotation)
        were prohibited.


                                         YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '@m=<>;@i=(1-1..$#m);$j=$#m;for(;
$j;$j--){$r=rand($j);@i[$j,$r]=@i[$r,$j]};for(()..$#m){warn $m
[$_].''' => '''.$m[$i[$_]]}'




prohibits: " 0 h k q s t



            We couldn’t use while().
            And quotation operators made us painful.


                                       YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '@m=<>;@i=(1-1..$#m);$j=$#m;for(;
$j;$j--){$r=rand($j);@i[$j,$r]=@i[$r,$j]};for(()..$#m){warn $m
[$_].''' => '''.$m[$i[$_]]}'




prohibits: " 0 h k q s t



               Next, "y", "," and ";" were prohibited.



                                           YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{@m=<> xor @i=(1-1..$#m) xor
$j=@m} for(1..--$j){$r=rand($j) xor @i[$j--=>$r]=@i[$r=>$j]}
for(()..$#m){warn $m[$_].''' => '''.$m[$i[$_]]}'




prohibits: " , 0 ; h k q s t y



                We started to join each statements
                by "xor" operator.


                                        YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{@m=<> xor @i=(1-1..$#m) xor
$j=@m} for(1..--$j){$r=rand($j) xor @i[$j--=>$r]=@i[$r=>$j]}
for(()..$#m){warn $m[$_].''' => '''.$m[$i[$_]]}'




prohibits: " , 0 ; h k q s t y



                      Next, "o" was prohibited.



                                          YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{@m=<>} {@i=(1-1..$#m)} {$j=@m}
{map {{$r=rand($j)}=>{@i[$j--=>$r]=@i[$r=>$j]}} (1..--$j)} map
{warn $m[$_].''' => '''.$m[$i[$_]]} (()..$#m)'




prohibits: " , 0 ; h k o q s t y



                    xor was no longer available.



                                          YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{@m=<>} {@i=(1-1..$#m)} {$j=@m}
{map {{$r=rand($j)}=>{@i[$j--=>$r]=@i[$r=>$j]}} (1..--$j)} map
{warn $m[$_].''' => '''.$m[$i[$_]]} (()..$#m)'




prohibits: " , 0 ; h k o q s t y



                      Next, "-" was prohibited.



                                          YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{ $x=eval("x2d1") } {@m=<>} {@i=
(()..$#m)} {$j=@m} {map {{$r=rand($j)}=>{@i[$j=>$r]=@i[$r=>
$j]} => $j+=$x} (1..($j+=$x))} map {warn $m[$_].''' => '''.
$m[$i[$_]]} (()..$#m)'




prohibits: " , - 0 ; h k o q s t y



           We needed to require some creative thinking
           to do -1.


                                            YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{ $x=eval("x2d1") } {@m=<>} {@i=
(()..$#m)} {$j=@m} {map {{$r=rand($j)}=>{@i[$j=>$r]=@i[$r=>
$j]} => $j+=$x} (1..($j+=$x))} map {warn $m[$_].''' => '''.
$m[$i[$_]]} (()..$#m)'




prohibits: " , - 0 ; h k o q s t y



                      Next, "r" was prohibited.



                                            YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{ $x=eval("x2d1") } {@m=<>} {@i=
(()..$#m)} {$j=@m} {$v=$$}{map {{$v *= $v}=> {$p = $v % $j}=>
{@i[$j=>$p]=@i[$p=>$j]} => $j+=$x} (1..($j+=$x))} {@d = map
{ $m[$_].''' => '''.$m[$i[$_]]} (()..$#m)} {die @d}'




prohibits: " , - 0 ; h k o q r s t y



     We couldn’t use rand().
     And also warn() was not available to output the result.


                                              YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{ $x=eval("x2d1") } {@m=<>} {@i=
(()..$#m)} {$j=@m} {$v=$$}{map {{$v *= $v}=> {$p = $v % $j}=>
{@i[$j=>$p]=@i[$p=>$j]} => $j+=$x} (1..($j+=$x))} {@d = map
{ $m[$_].''' => '''.$m[$i[$_]]} (()..$#m)} {die @d}'




prohibits: " , - 0 ; h k o q r s t y



                    We considered that die() was
                    the last way to output.


                                              YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{ $x=eval("x2d1") } {@m=<>} {@i=
(()..$#m)} {$j=@m} {$v=$$}{map {{$v *= $v}=> {$p = $v % $j}=>
{@i[$j=>$p]=@i[$p=>$j]} => $j+=$x} (1..($j+=$x))} {@d = map
{ $m[$_].''' => '''.$m[$i[$_]]} (()..$#m)} {die @d}'




prohibits: " , - 0 ; h k o q r s t y



                      Next, "e" was prohibited.



                                              YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{ $x='''L1'''^'''a''' }
{@m=<>} {@i=(()..$#m)} {$j=@m} {$v=$$}{map {{$v = (45 * $v +
555) % (4 ** 5)}=> {$p = $v % $j}=>{@i[$j=>$p]=@i[$p=>$j]} =>
$j+=$x} (1..($j+=$x))} {map { $d .= $m[$_].''' => '''.$m[$i
[$_]]} (()..$#m)} &$d'




prohibits: " , - 0 ; e h k o q r s t y



                          We couldn’t eval().
                          We couldn’t die().


                                            YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{ $x='''L1'''^'''a''' }
{@m=<>} {@i=(()..$#m)} {$j=@m} {$v=$$}{map {{$v = (45 * $v +
555) % (4 ** 5)}=> {$p = $v % $j}=>{@i[$j=>$p]=@i[$p=>$j]} =>
$j+=$x} (1..($j+=$x))} {map { $d .= $m[$_].''' => '''.$m[$i
[$_]]} (()..$#m)} &$d'




prohibits: " , - 0 ; e h k o q r s t y



      The output result was like;
      "Undefined subroutine &main::clair => hiro ... called
      at -e line 1, <> line 7."
                                            YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{ $x='''L1'''^'''a''' }
{@m=<>} {@i=(()..$#m)} {$j=@m} {$v=$$}{map {{$v = (45 * $v +
555) % (4 ** 5)}=> {$p = $v % $j}=>{@i[$j=>$p]=@i[$p=>$j]} =>
$j+=$x} (1..($j+=$x))} {map { $d .= $m[$_].''' => '''.$m[$i
[$_]]} (()..$#m)} &$d'




prohibits: " , - 0 ; e h k o q r s t y



     Also, we started to use Linear congruential generators
     (LCGs) to generate a random digit.


                                            YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{ $x='''L1'''^'''a''' }
{@m=<>} {@i=(()..$#m)} {$j=@m} {$v=$$}{map {{$v = (45 * $v +
555) % (4 ** 5)}=> {$p = $v % $j}=>{@i[$j=>$p]=@i[$p=>$j]} =>
$j+=$x} (1..($j+=$x))} {map { $d .= $m[$_].''' => '''.$m[$i
[$_]]} (()..$#m)} &$d'




prohibits: " , - 0 ; e h k o q r s t y



             To tell you the truth, I’m not sure about it.
             Wikipedia it for ourselves.


                                            YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{ $x='''L1'''^'''a''' }
{@m=<>} {@i=(()..$#m)} {$j=@m} {$v=$$}{map {{$v = (45 * $v +
555) % (4 ** 5)}=> {$p = $v % $j}=>{@i[$j=>$p]=@i[$p=>$j]} =>
$j+=$x} (1..($j+=$x))} {map { $d .= $m[$_].''' => '''.$m[$i
[$_]]} (()..$#m)} &$d'




prohibits: " , - 0 ; e h k o q r s t y



                      Next, "p" was prohibited.



                                            YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{ $x='''L1'''^'''a''' }
{@m=<>} {@i=(()..$#m)} {$j=@m} {$v=$$} {$zz='''z''' x ($j+=
$x)} {$zz=~/z(??{({$v = (45 * $v + 555) % (4 ** 5)}=> {$z = $v
% $j}=>{@i[$j=>$z]=@i[$z=>$j]} => $j+=$x) })/} {$zz='''z'''
x @m}{$zz=~/z(??{( $d .= $m[$zzz].''' => '''.$m[$i[$zzz+
+]] ) })/ } &$d'




prohibits: " , - 0 ; e h k o p q r s t y



             map() the last built-in function was gone.



                                            YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{ $x='''L1'''^'''a''' }
{@m=<>} {@i=(()..$#m)} {$j=@m} {$v=$$} {$zz='''z''' x ($j+=
$x)} {$zz=~/z(??{({$v = (45 * $v + 555) % (4 ** 5)}=> {$z = $v
% $j}=>{@i[$j=>$z]=@i[$z=>$j]} => $j+=$x) })/} {$zz='''z'''
x @m}{$zz=~/z(??{( $d .= $m[$zzz].''' => '''.$m[$i[$zzz+
+]] ) })/ } &$d'




prohibits: " , - 0 ; e h k o p q r s t y



On this ocation, prohibited "a", "b", "c", "d", "f", "g", "i", "j",
"l", "m", "n", "u", "v", "w" and "z" (every alphabet except "x").


                                            YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{ $x='''%'''|'''('''.1 }
{@xx=<>} {@xxx=(()..$#xx)} {$xxxx=@xx} {$xxxxx=$$}
{$xxxxxx='''x''' x ($xxxx+=$x)} {$xxxxxx=~/x(??{({$xxxxx =
(45 * $xxxxx + 555) % (4 ** 5)}=> {$xxxxxxx = $xxxxx % $xxxx}
=>{@xxx[$xxxx=>$xxxxxxx]=@xxx[$xxxxxxx=>$xxxx]} => $xxxx+=
$x) })/} {$xxxxxx='''x''' x @xx}{$xxxxxx=~/x(??
{( $xxxxxxxxx .= $xx[$xxxxxxxx].''' => '''.$xx[$xxx
[$xxxxxxxx++]] ) })/ } &$xxxxxxxxx'



prohibits: " , - 0 ; a b c d e f g h i j k l m n o p q r s t u v w y z



     Does anybody fix my J’ai perdu le do de ma clarinette?



                                              YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{ $x='''%'''|'''('''.1 }
{@xx=<>} {@xxx=(()..$#xx)} {$xxxx=@xx} {$xxxxx=$$}
{$xxxxxx='''x''' x ($xxxx+=$x)} {$xxxxxx=~/x(??{({$xxxxx =
(45 * $xxxxx + 555) % (4 ** 5)}=> {$xxxxxxx = $xxxxx % $xxxx}
=>{@xxx[$xxxx=>$xxxxxxx]=@xxx[$xxxxxxx=>$xxxx]} => $xxxx+=
$x) })/} {$xxxxxx='''x''' x @xx}{$xxxxxx=~/x(??
{( $xxxxxxxxx .= $xx[$xxxxxxxx].''' => '''.$xx[$xxx
[$xxxxxxxx++]] ) })/ } &$xxxxxxxxx'



prohibits: " , - 0 ; a b c d e f g h i j k l m n o p q r s t u v w y z



                              And finally,



                                              YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{ $x='''%'''|'''('''.1 }
{@xx=<>} {@xxx=(()..$#xx)} {$xxxx=@xx} {$xxxxx=$$}
{$xxxxxx='''x''' x ($xxxx+=$x)} {$xxxxxx=~/x(??{({$xxxxx =
(45 * $xxxxx + 555) % (4 ** 5)}=> {$xxxxxxx = $xxxxx % $xxxx}
=>{@xxx[$xxxx=>$xxxxxxx]=@xxx[$xxxxxxx=>$xxxx]} => $xxxx+=
$x) })/} {$xxxxxx='''x''' x @xx}{$xxxxxx=~/x(??
{( $xxxxxxxxx .= $xx[$xxxxxxxx].''' => '''.$xx[$xxx
[$xxxxxxxx++]] ) })/ } &$xxxxxxxxx'



prohibits: " , - 0 ; a b c d e f g h i j k l m n o p q r s t u v w y z



            We decided to prohibit the last best hope,
            "x".


                                              YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{ $_1='''%'''|'''('''.1 } {$/
=''''''} {$_2=<>} {$*=1} {@_3=()} {$_2=~/^(.+?)$(??{{$_3
[$#_3+1]=$1}{$#_3?$_4.='''_''':''''''}{'''^'''}})/}
{@_6=(()..$#_3)} {$_7=$#_3} {$_5=$$} {$_4=~/_(??{({$_5 = (45 *
$_5 + 555) % (4 ** 5)}=> {$_11 = $_5 % $_7}=>{@_6[$_7=>$_11]
=@_6[$_11=>$_7]} => $_7+=$_1) })/} {$_4.='''_'''}{$_4=~/_(??
{( $_8 .= $_3[$_9].''' => '''.$_3[$_6[$_9++]].'''
''' ) })/ } &$_8'



prohibits: " , - 0 ; a b c d e f g h i j k l m n o p q r s t u v w x y z



           This is the final form without using alphabet.



                                              YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{ $_1='''%'''|'''('''.1 } {$/
=''''''} {$_2=<>} {$*=1} {@_3=()} {$_2=~/^(.+?)$(??{{$_3
[$#_3+1]=$1}{$#_3?$_4.='''_''':''''''}{'''^'''}})/}
{@_6=(()..$#_3)} {$_7=$#_3} {$_5=$$} {$_4=~/_(??{({$_5 = (45 *
$_5 + 555) % (4 ** 5)}=> {$_11 = $_5 % $_7}=>{@_6[$_7=>$_11]
=@_6[$_11=>$_7]} => $_7+=$_1) })/} {$_4.='''_'''}{$_4=~/_(??
{( $_8 .= $_3[$_9].''' => '''.$_3[$_6[$_9++]].'''
''' ) })/ } &$_8'



prohibits: " , - 0 ; a b c d e f g h i j k l m n o p q r s t u v w x y z



Actually, it doesn’t work with perl 5.10.x or later
because $*, (deprecated) variable has been removed.


                                              YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




final season "lipstick on an after-image"
% cat members.txt | perl -e '{ $_1='''%'''|'''('''.1 } {$/
=''''''} {$_2=<>} {$*=1} {@_3=()} {$_2=~/^(.+?)$(??{{$_3
[$#_3+1]=$1}{$#_3?$_4.='''_''':''''''}{'''^'''}})/}
{@_6=(()..$#_3)} {$_7=$#_3} {$_5=$$} {$_4=~/_(??{({$_5 = (45 *
$_5 + 555) % (4 ** 5)}=> {$_11 = $_5 % $_7}=>{@_6[$_7=>$_11]
=@_6[$_11=>$_7]} => $_7+=$_1) })/} {$_4.='''_'''}{$_4=~/_(??
{( $_8 .= $_3[$_9].''' => '''.$_3[$_6[$_9++]].'''
''' ) })/ } &$_8'



prohibits: " , - 0 ; a b c d e f g h i j k l m n o p q r s t u v w x y z



                We are seeking a mature individual
                with excellent shuffle skills.


                                              YAPC::ASIA 2010 LIGHTNING TALKS
THERE ARE SO MANY WAYS TO SHUFFLE IT




the end
          YAPC::ASIA 2010 LIGHTNING TALKS

Contenu connexe

Dernier

TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostZilliz
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024Lorenzo Miniero
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsPixlogix Infotech
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr BaganFwdays
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLScyllaDB
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupFlorian Wilhelm
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxhariprasad279825
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfAlex Barbosa Coqueiro
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DaySri Ambati
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningLars Bell
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfAddepto
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 

Dernier (20)

TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage CostLeverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
Leverage Zilliz Serverless - Up to 50X Saving for Your Vector Storage Cost
 
SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024SIP trunking in Janus @ Kamailio World 2024
SIP trunking in Janus @ Kamailio World 2024
 
The Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and ConsThe Ultimate Guide to Choosing WordPress Pros and Cons
The Ultimate Guide to Choosing WordPress Pros and Cons
 
"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan"ML in Production",Oleksandr Bagan
"ML in Production",Oleksandr Bagan
 
Developer Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQLDeveloper Data Modeling Mistakes: From Postgres to NoSQL
Developer Data Modeling Mistakes: From Postgres to NoSQL
 
Streamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project SetupStreamlining Python Development: A Guide to a Modern Project Setup
Streamlining Python Development: A Guide to a Modern Project Setup
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
Artificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptxArtificial intelligence in cctv survelliance.pptx
Artificial intelligence in cctv survelliance.pptx
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Unraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdfUnraveling Multimodality with Large Language Models.pdf
Unraveling Multimodality with Large Language Models.pdf
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo DayH2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
H2O.ai CEO/Founder: Sri Ambati Keynote at Wells Fargo Day
 
Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
DSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine TuningDSPy a system for AI to Write Prompts and Do Fine Tuning
DSPy a system for AI to Write Prompts and Do Fine Tuning
 
Gen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdfGen AI in Business - Global Trends Report 2024.pdf
Gen AI in Business - Global Trends Report 2024.pdf
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 

En vedette

AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfmarketingartwork
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Applitools
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at WorkGetSmarter
 

En vedette (20)

AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
Unlocking the Power of ChatGPT and AI in Testing - A Real-World Look, present...
 
12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work12 Ways to Increase Your Influence at Work
12 Ways to Increase Your Influence at Work
 
ChatGPT webinar slides
ChatGPT webinar slidesChatGPT webinar slides
ChatGPT webinar slides
 
More than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike RoutesMore than Just Lines on a Map: Best Practices for U.S Bike Routes
More than Just Lines on a Map: Best Practices for U.S Bike Routes
 

Many Ways to Shuffle It

  • 1. THERE ARE SO MANY WAYS TO SHUFFLE IT TASMWTSI there are so many ways to shuffle it koichi taniguchi (@nipotan) tokyo, japan livedoor co.,ltd. YAPC::ASIA 2010 LIGHTNING TALKS
  • 2. THERE ARE SO MANY WAYS TO SHUFFLE IT the story line . . . • … • • commit log In a department of our company, YAPC::ASIA 2010 LIGHTNING TALKS
  • 3. THERE ARE SO MANY WAYS TO SHUFFLE IT the story line . . . • … • • commit log we each have the practice to report another colleague’s weekly activities with each other ... YAPC::ASIA 2010 LIGHTNING TALKS
  • 4. THERE ARE SO MANY WAYS TO SHUFFLE IT the story line . . . • … • • commit log at every Friday's regular meeting. YAPC::ASIA 2010 LIGHTNING TALKS
  • 5. THERE ARE SO MANY WAYS TO SHUFFLE IT the story line . . . • … • • commit log We each report what its own target did what in this week by checking the diffs out from the revision control system. YAPC::ASIA 2010 LIGHTNING TALKS
  • 6. THERE ARE SO MANY WAYS TO SHUFFLE IT the story line . . . • … • • This changes the inside of our complicated system which is changing continually to be comprehensible to us. YAPC::ASIA 2010 LIGHTNING TALKS
  • 7. THERE ARE SO MANY WAYS TO SHUFFLE IT the story line . . . • … • • And it's a good way to keep the quality of our entire source code. YAPC::ASIA 2010 LIGHTNING TALKS
  • 8. THERE ARE SO MANY WAYS TO SHUFFLE IT the story line . . . • … • • Although, we need to decide that "who will check who?" to do it every week. YAPC::ASIA 2010 LIGHTNING TALKS
  • 9. THERE ARE SO MANY WAYS TO SHUFFLE IT the story line . . . • … • • We each do live coding to make a decision in some rules of each season. YAPC::ASIA 2010 LIGHTNING TALKS
  • 10. THERE ARE SO MANY WAYS TO SHUFFLE IT the story line . . . • … • We call it "Time to Shuffle" ... YAPC::ASIA 2010 LIGHTNING TALKS
  • 11. THERE ARE SO MANY WAYS TO SHUFFLE IT the story line . . . •… ww • You may think "Just Shuffle? So?" Don't underestimate our performances. YAPC::ASIA 2010 LIGHTNING TALKS
  • 12. THERE ARE SO MANY WAYS TO SHUFFLE IT the story line . . . •… ww • Now I’m going to introduce you the masterpieces of our SHUFFLE. YAPC::ASIA 2010 LIGHTNING TALKS
  • 13. THERE ARE SO MANY WAYS TO SHUFFLE IT season 1 "no rules" This season is just to be familiar with doing live coding for us. YAPC::ASIA 2010 LIGHTNING TALKS
  • 14. THERE ARE SO MANY WAYS TO SHUFFLE IT season 1 "no rules" And there's NO highlights because it's boring. YAPC::ASIA 2010 LIGHTNING TALKS
  • 15. THERE ARE SO MANY WAYS TO SHUFFLE IT season 2 "rand prohibited" In the second season, YAPC::ASIA 2010 LIGHTNING TALKS
  • 16. THERE ARE SO MANY WAYS TO SHUFFLE IT season 2 "rand prohibited" rand() and similar function which is derived from rand() are prohibited. YAPC::ASIA 2010 LIGHTNING TALKS
  • 17. THERE ARE SO MANY WAYS TO SHUFFLE IT season 2 "rand prohibited" % perl -MTime::HiRes -le '@a=@b=qw(claire tracy mohinder hiro matt nathan peter sylar);$t=Time::HiRes::time*100000% $#b+1;for(0..$#a){print $a[$_].q{ => }.$b[($_+$t)%(scalar @b)]}' claire => hiro tracy => matt mohinder => nathan hiro => peter matt => sylar nathan => claire peter => tracy sylar => mohinder First, microseconds are multiplied by hundred thousand. Then the random digit was made from them. YAPC::ASIA 2010 LIGHTNING TALKS
  • 18. THERE ARE SO MANY WAYS TO SHUFFLE IT season 2 "rand prohibited" % perl -MTime::HiRes -le '@a=@b=qw(claire tracy mohinder hiro matt nathan peter sylar);$t=Time::HiRes::time*100000% $#b+1;for(0..$#a){print $a[$_].q{ => }.$b[($_+$t)%(scalar @b)]}' claire => hiro tracy => matt mohinder => nathan hiro => peter matt => sylar nathan => claire peter => tracy sylar => mohinder Probably all you guys come up with the same idea. YAPC::ASIA 2010 LIGHTNING TALKS
  • 19. THERE ARE SO MANY WAYS TO SHUFFLE IT season 2 "rand prohibited" % perl -MTime::HiRes -le '@a=@b=qw(claire tracy mohinder hiro matt nathan peter sylar);$t=Time::HiRes::time*100000% $#b+1;for(0..$#a){print $a[$_].q{ => }.$b[($_+$t)%(scalar @b)]}' claire => hiro tracy => matt mohinder => nathan hiro => peter matt => sylar nathan => claire peter => tracy sylar => mohinder Also, it just moved the elements of the array. YAPC::ASIA 2010 LIGHTNING TALKS
  • 20. THERE ARE SO MANY WAYS TO SHUFFLE IT season 2 "rand prohibited" % perl -e '@m=@r=qw(claire tracy mohinder hiro matt nathan peter sylar); sub r{hex(`md5sum /proc/stat|head -c8`)%@m} while(++$c<100||scalar grep {$m[$_] eq $r[$_]} (0..$#m)) {$a=&r;$b=&r; @r[$a,$b] = @r[$b,$a]} printf "%-8s => %-8s n", $m[$_], $r[$_] for (0..$#m);' claire => tracy tracy => peter mohinder => hiro hiro => sylar matt => mohinder nathan => claire peter => nathan sylar => matt Next, it has the original random function. YAPC::ASIA 2010 LIGHTNING TALKS
  • 21. THERE ARE SO MANY WAYS TO SHUFFLE IT season 2 "rand prohibited" % perl -e '@m=@r=qw(claire tracy mohinder hiro matt nathan peter sylar); sub r{hex(`md5sum /proc/stat|head -c8`)%@m} while(++$c<100||scalar grep {$m[$_] eq $r[$_]} (0..$#m)) {$a=&r;$b=&r; @r[$a,$b] = @r[$b,$a]} printf "%-8s => %-8s n", $m[$_], $r[$_] for (0..$#m);' claire => tracy tracy => peter mohinder => hiro hiro => sylar matt => mohinder nathan => claire peter => nathan sylar => matt It recognizes a part of the produced MD5 message digest of kernel/system statistics (/proc/stat) as hex string, YAPC::ASIA 2010 LIGHTNING TALKS
  • 22. THERE ARE SO MANY WAYS TO SHUFFLE IT season 2 "rand prohibited" % perl -e '@m=@r=qw(claire tracy mohinder hiro matt nathan peter sylar); sub r{hex(`md5sum /proc/stat|head -c8`)%@m} while(++$c<100||scalar grep {$m[$_] eq $r[$_]} (0..$#m)) {$a=&r;$b=&r; @r[$a,$b] = @r[$b,$a]} printf "%-8s => %-8s n", $m[$_], $r[$_] for (0..$#m);' claire => tracy tracy => peter mohinder => hiro hiro => sylar matt => mohinder nathan => claire peter => nathan sylar => matt and the corresponding value of it is divided by the number of arguments. YAPC::ASIA 2010 LIGHTNING TALKS
  • 23. THERE ARE SO MANY WAYS TO SHUFFLE IT season 2 "rand prohibited" % perl -e '@m=@r=qw(claire tracy mohinder hiro matt nathan peter sylar); sub r{hex(`md5sum /proc/stat|head -c8`)%@m} while(++$c<100||scalar grep {$m[$_] eq $r[$_]} (0..$#m)) {$a=&r;$b=&r; @r[$a,$b] = @r[$b,$a]} printf "%-8s => %-8s n", $m[$_], $r[$_] for (0..$#m);' claire => tracy tracy => peter mohinder => hiro hiro => sylar matt => mohinder nathan => claire peter => nathan sylar => matt Then it returns the remainder. It is a random integer. YAPC::ASIA 2010 LIGHTNING TALKS
  • 24. THERE ARE SO MANY WAYS TO SHUFFLE IT season 2 "rand prohibited" % perl -e '@m=@r=qw(claire tracy mohinder hiro matt nathan peter sylar); sub r{hex(`md5sum /proc/stat|head -c8`)%@m} while(++$c<100||scalar grep {$m[$_] eq $r[$_]} (0..$#m)) {$a=&r;$b=&r; @r[$a,$b] = @r[$b,$a]} printf "%-8s => %-8s n", $m[$_], $r[$_] for (0..$#m);' claire => tracy tracy => peter mohinder => hiro hiro => sylar matt => mohinder nathan => claire peter => nathan sylar => matt And it tries to shuffle each elements completely but it might be given up if it spins over hundred times. YAPC::ASIA 2010 LIGHTNING TALKS
  • 25. THERE ARE SO MANY WAYS TO SHUFFLE IT season 3 "increase combinations possible" In the third season, YAPC::ASIA 2010 LIGHTNING TALKS
  • 26. THERE ARE SO MANY WAYS TO SHUFFLE IT season 3 "increase combinations possible" We should increase all possible combinations more than number of members. YAPC::ASIA 2010 LIGHTNING TALKS
  • 27. THERE ARE SO MANY WAYS TO SHUFFLE IT season 3 "increase combinations possible" That is, just moving the elements is prohibited. Instead, we can use rand() again from the season. YAPC::ASIA 2010 LIGHTNING TALKS
  • 28. THERE ARE SO MANY WAYS TO SHUFFLE IT season 3 "increase combinations possible" We did it! YAPC::ASIA 2010 LIGHTNING TALKS
  • 29. THERE ARE SO MANY WAYS TO SHUFFLE IT season 3 "increase combinations possible" -module(shuffle). -export([main/1,comb/2]). main(A) ->  All = comb(A,A),  Set = lists:nth(random:uniform(length(All)), All),  output(Set). output([]) -> true; output([{A,B}|T]) ->  io:format("~w => ~w~n", [A,B]),  output(T). comb([], _) -> [[]]; comb([H|T], B) ->  [ [{H, X}|Rest] || X<-B--[H], Rest<-comb(T, B--[X]) ]. Erlang?! YAPC::ASIA 2010 LIGHTNING TALKS
  • 30. THERE ARE SO MANY WAYS TO SHUFFLE IT season 3 "increase combinations possible" % erl Erlang R14B (erts-5.8.1) [source] [rq:1] [async-threads:0] [hipe] [kernel- poll:false] Eshell V5.8.1 (abort with ^G) 1> c(shuffle). {ok,shuffle} 2> shuffle:main([claire,mohinder,hiro,matt,nathan,peter,sylar]). claire => mohinder mohinder => nathan hiro => matt matt => sylar nathan => claire peter => hiro sylar => peter true I'm not sure, but it maybe works correctly. YAPC::ASIA 2010 LIGHTNING TALKS
  • 31. THERE ARE SO MANY WAYS TO SHUFFLE IT season 3 "increase combinations possible" % ruby -e 'a=b=%w(claire tracy mohinder hiro matt nathan peter sylar); b=b.sort_by{rand} until (0..a.size-1).all? {|i|a[i]!=b[i]};a.zip(b){|x,y| puts "%8s => %s" % [x,y]}' claire => nathan tracy => hiro mohinder => peter hiro => matt matt => mohinder nathan => sylar peter => claire sylar => tracy Ruby?! YAPC::ASIA 2010 LIGHTNING TALKS
  • 32. THERE ARE SO MANY WAYS TO SHUFFLE IT season 3 "increase combinations possible" % ruby -e 'a=b=%w(claire tracy mohinder hiro matt nathan peter sylar); b=b.sort_by{rand} until (0..a.size-1).all? {|i|a[i]!=b[i]};a.zip(b){|x,y| puts "%8s => %s" % [x,y]}' claire => nathan tracy => hiro mohinder => peter hiro => matt matt => mohinder nathan => sylar peter => claire sylar => tracy Excuse me. This is Yet Another Perl Conference, isn't it. Why don't you use Perl? YAPC::ASIA 2010 LIGHTNING TALKS
  • 33. THERE ARE SO MANY WAYS TO SHUFFLE IT season 3 "increase combinations possible" % ruby -e 'a=b=%w(claire tracy mohinder hiro matt nathan peter sylar); b=b.sort_by{rand} until (0..a.size-1).all? {|i|a[i]!=b[i]};a.zip(b){|x,y| puts "%8s => %s" % [x,y]}' claire => nathan tracy => hiro mohinder => peter hiro => matt matt => mohinder nathan => sylar peter => claire sylar => tracy By the way, is zip() cool, it isn’t? YAPC::ASIA 2010 LIGHTNING TALKS
  • 34. THERE ARE SO MANY WAYS TO SHUFFLE IT season 3 "increase combinations possible" % perl6 -e 'for ("foo", "bar", "baz") Z ("qux", "quux", "corge") -> $a, $b { say "$a => $b" }' foo => qux bar => quux baz => corge We can use "Z" for zip() operator in perl6. But I’m not sure about perl6. YAPC::ASIA 2010 LIGHTNING TALKS
  • 35. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" This season is like a time trial. YAPC::ASIA 2010 LIGHTNING TALKS
  • 36. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" In addition, it was laid down the most strict rules so far. YAPC::ASIA 2010 LIGHTNING TALKS
  • 37. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" • The rules of the season are... YAPC::ASIA 2010 LIGHTNING TALKS
  • 38. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" • • arrayref arrayref write a perl subroutine which gets an arrayref of member list as the parameter ... YAPC::ASIA 2010 LIGHTNING TALKS
  • 39. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" • • arrayref arrayref and returns an arrayref of target members. YAPC::ASIA 2010 LIGHTNING TALKS
  • 40. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" • • arrayref arrayref • Increase all possible combinations more than number of members. YAPC::ASIA 2010 LIGHTNING TALKS
  • 41. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" • • arrayref arrayref • • Eliminate the pairs that include the target of someone is oneself. YAPC::ASIA 2010 LIGHTNING TALKS
  • 42. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" • • arrayref arrayref • • • Possibly faster than ever before. For comparison, we try to benchmark ... YAPC::ASIA 2010 LIGHTNING TALKS
  • 43. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" • • arrayref arrayref • • • 10,000 times shuffle of 10 members, 1,000 times shuffle of 1,000 members, YAPC::ASIA 2010 LIGHTNING TALKS
  • 44. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" • • arrayref arrayref • • • and 10 times shuffle of 10,000 members. YAPC::ASIA 2010 LIGHTNING TALKS
  • 45. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" • • arrayref arrayref • • • Then we evaluate the results comprehensively and assume which is the reigning champion. YAPC::ASIA 2010 LIGHTNING TALKS
  • 46. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" • • arrayref arrayref • • • • Preparing some tricks ahead of time and playing it is prohibited. YAPC::ASIA 2010 LIGHTNING TALKS
  • 47. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" • • arrayref arrayref • • • • • / Meet the any of following conditions, YAPC::ASIA 2010 LIGHTNING TALKS
  • 48. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" • • arrayref arrayref • • • • • / it gives "different results each time", "all possible combinations" and/or "even results". YAPC::ASIA 2010 LIGHTNING TALKS
  • 49. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" sub shuffle {     my $array = shift;     my $array2;     do {         $array2 = [sort { rand(3)-1 } @$array];     } while (grep $$array[$_] eq $$array2[$_], (0..$#$array));     return $array2; } At first, this is the interim champion. It’s not so fast because it’s the reference implementation. YAPC::ASIA 2010 LIGHTNING TALKS
  • 50. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" sub shuffle {    my $array = shift;    my $n = $#$array;    my @index = (0..$n);    my $i;    for (0..$n) {        $i = int(rand($n));        redo if $_ == $index[$i] || $i == $index[$_];        ( $index[$_], $index[$i] ) = ( $index[$i], $index[$_] );    }    return [ @$array[@index] ]; } This is the 2nd champion. It works more than 4 times faster than the former champion. YAPC::ASIA 2010 LIGHTNING TALKS
  • 51. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" sub shuffle {     my @array = @{$_[0]};     my ($i, $r) = scalar @array;     while(--$i) {         $r = rand($i);         @array[$i, $r] = @array[$r, $i];     }     return @array; } This is the 4th champion. Incidentally, it’s very similar to Fisher-Yates shuffle. YAPC::ASIA 2010 LIGHTNING TALKS
  • 52. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" sub shuffle {     my @array = @{$_[0]};     my ($i, $r) = scalar @array;     while(--$i) {         $r = rand($i);         @array[$i, $r] = @array[$r, $i];     }     return @array; } You can find out the technique like this in perldoc -q shuffle (in perlfaq4). YAPC::ASIA 2010 LIGHTNING TALKS
  • 53. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" sub shuffle {             my @magic = ();     return _shuffle(@_);             if ($is_odd){     BEGIN{                 @sep = map{$_ + $MAGIC} @sep;         my $MAGIC = 3;                 @magic = @{$MAGIC[($R / $half /         my @MAGIC = ([1,2,0], [2,0,1]); $half) % 2]};         srand;             }         my $R=int rand(1000000);             return [@$arg[@magic,         sub _shuffle {                           $sep[6] .. $sep[7],             my $arg = shift;                           $sep[4] .. $sep[5],             my $n = scalar @$arg;                           $sep[2] .. $sep[3],             my $is_odd = $n % 2;                           $sep[0] .. $sep[1]             $n -= $MAGIC if $is_odd;                    ]];             my $half = $n / 2;         }             my $r_a = ($R / $half) % ($half);     }             my $r_b = ($R % $half); }             $R++;             my @sep = (0 => $r_a,                        $r_a+1 => $half - 1,                        $half => $half + $r_b,                        $half + $r_b + 1 => $n -1); This is the 5th champion. It doesn't shuffle accurately. It's so tricky. YAPC::ASIA 2010 LIGHTNING TALKS
  • 54. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" sub shuffle {             my @magic = ();     return _shuffle(@_);             if ($is_odd){     BEGIN{                 @sep = map{$_ + $MAGIC} @sep;         my $MAGIC = 3;                 @magic = @{$MAGIC[($R / $half /         my @MAGIC = ([1,2,0], [2,0,1]); $half) % 2]};         srand;             }         my $R=int rand(1000000);             return [@$arg[@magic,         sub _shuffle {                           $sep[6] .. $sep[7],             my $arg = shift;                           $sep[4] .. $sep[5],             my $n = scalar @$arg;                           $sep[2] .. $sep[3],             my $is_odd = $n % 2;                           $sep[0] .. $sep[1]             $n -= $MAGIC if $is_odd;                    ]];             my $half = $n / 2;         }             my $r_a = ($R / $half) % ($half);     }             my $r_b = ($R % $half); }             $R++;             my @sep = (0 => $r_a,                        $r_a+1 => $half - 1,                        $half => $half + $r_b,                        $half + $r_b + 1 => $n -1); It works about 30% faster than Fisher-Yates shuffle. But It doesn't work at all under a specific condition. YAPC::ASIA 2010 LIGHTNING TALKS
  • 55. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" sub shuffle {             my @magic = ();     return _shuffle(@_);             if ($is_odd){     BEGIN{                 @sep = map{$_ + $MAGIC} @sep;         my $MAGIC = 3;                 @magic = @{$MAGIC[($R / $half /         my @MAGIC = ([1,2,0], [2,0,1]); $half) % 2]};         srand;             }         my $R=int rand(1000000);             return [@$arg[@magic,         sub _shuffle {                           $sep[6] .. $sep[7],             my $arg = shift;                           $sep[4] .. $sep[5],             my $n = scalar @$arg;                           $sep[2] .. $sep[3],             my $is_odd = $n % 2;                           $sep[0] .. $sep[1]             $n -= $MAGIC if $is_odd;                    ]];             my $half = $n / 2;         }             my $r_a = ($R / $half) % ($half);     }             my $r_b = ($R % $half); }             $R++;             my @sep = (0 => $r_a,                        $r_a+1 => $half - 1,                        $half => $half + $r_b,                        $half + $r_b + 1 => $n -1); If you want to read the code carefully, Please wait the publication of this slide. YAPC::ASIA 2010 LIGHTNING TALKS
  • 56. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" sub shuffle { MODULE = Foo PACKAGE = Foo     return [Foo::fisher_yates(@{$_[0]})]; void     BEGIN { fisher_yates(...)         my $use = sub { PROTOTYPE: @             eval qq{ use $_[0]; }; CODE:             return $@ ? () : 1; UV i = items;         }; while (--i) {         push @INC, qw(Foo/blib/lib Foo/blib/arch); UV swap = (UV)(Drand01() * i);         unless ($use->('Foo')) { SV *tmp = ST(swap);             if (-d 'Foo') { ST(swap) = ST(i);                 system(qw/rm -frv Foo/) && die $^E; ST(i) = tmp;             } }             system(qw/h2xs -A -n Foo/) && die $^E; XSRETURN(items);             chdir 'Foo' or die $!; XSUB             open my $xs, '>', 'Foo.xs' or die $!;             print $xs <<'XSUB';             close $xs; #include "EXTERN.h"             (system($^X, 'Makefile.PL') || #include "perl.h" system('make')) && die $^E; #include "XSUB.h"             chdir '..' or die $!; #include "ppport.h"             $use->('Foo') or die $@;             print "-" x 50 . "n";         }     }; } This is the 6th champion. A Fisher-Yates XS implementation is embedded in a subroutine forcibly. YAPC::ASIA 2010 LIGHTNING TALKS
  • 57. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" sub shuffle { MODULE = Foo PACKAGE = Foo     return [Foo::fisher_yates(@{$_[0]})]; void     BEGIN { fisher_yates(...)         my $use = sub { PROTOTYPE: @             eval qq{ use $_[0]; }; CODE:             return $@ ? () : 1; UV i = items;         }; while (--i) {         push @INC, qw(Foo/blib/lib Foo/blib/arch); UV swap = (UV)(Drand01() * i);         unless ($use->('Foo')) { SV *tmp = ST(swap);             if (-d 'Foo') { ST(swap) = ST(i);                 system(qw/rm -frv Foo/) && die $^E; ST(i) = tmp;             } }             system(qw/h2xs -A -n Foo/) && die $^E; XSRETURN(items);             chdir 'Foo' or die $!; XSUB             open my $xs, '>', 'Foo.xs' or die $!;             print $xs <<'XSUB';             close $xs; #include "EXTERN.h"             (system($^X, 'Makefile.PL') || #include "perl.h" system('make')) && die $^E; #include "XSUB.h"             chdir '..' or die $!; #include "ppport.h"             $use->('Foo') or die $@;             print "-" x 50 . "n";         }     }; } It works about 2 times faster than the former champion. YAPC::ASIA 2010 LIGHTNING TALKS
  • 58. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" side story As a side story. YAPC::ASIA 2010 LIGHTNING TALKS
  • 59. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" side story Satoshi Ueda (gunyoki), all you saw him a little while ago, he is a former member of ours. YAPC::ASIA 2010 LIGHTNING TALKS
  • 60. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" side story 19:55:00 <gunyoki> CPU kernel module 19:56:38 <gunyoki> 0 He said on IRC ... YAPC::ASIA 2010 LIGHTNING TALKS
  • 61. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" side story 19:55:00 <gunyoki> CPU kernel module 19:56:38 <gunyoki> 0 <gunyoki> I wrote a kernel module which can change the CPU expended time of the task structure. YAPC::ASIA 2010 LIGHTNING TALKS
  • 62. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" side story 19:55:00 <gunyoki> CPU kernel module 19:56:38 <gunyoki> 0 <gunyoki> It enable that the (not actual) time for any kind of calculation to be zero. YAPC::ASIA 2010 LIGHTNING TALKS
  • 63. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" side story #include <linux/kernel.h> static int proc_write(struct file *page, const char *buf, #include <linux/module.h> unsigned long len, void *data) #include <linux/sched.h> { #include <linux/proc_fs.h>         char tmp[64]; #include <asm/uaccess.h>         long utime;         struct task_struct *process; #define PROC_NAME "driver/utime"         if (copy_from_user(tmp, buf, len))                 return -EFAULT; static int pid;         utime = simple_strtol(tmp, NULL, 0); module_param(pid, int, 0666);         process = find_task_by_pid(pid);         if (!process) { static int proc_read(char *page, char **start, off_t                 printk("pid error: %dn", pid); offset, int count, int *eof, void *data)                 return -EFAULT; {         }         unsigned long outbyte;         printk("utime: %ld -> %ldn", process->utime,         struct task_struct *process; utime);         if (offset > 0) {         process->utime = utime;                 *eof = 1;         return len;                 return 0; }         }         process = find_task_by_pid(pid); int init_module(void)         if (!process) { {                 printk("pid error: %dn", pid);         struct proc_dir_entry *entry;                 *eof = 1;         entry = create_proc_entry(PROC_NAME, 0666, NULL);                 return 0;         if (entry == 0)         }                 return -EINVAL;         outbyte = sprintf(page, "%ld", process->utime);         entry->read_proc = proc_read;         printk("proc_read len = %lun", outbyte);         entry->write_proc = proc_write;         *eof = 1;         return 0;         return outbyte; } } void cleanup_module(void) {         remove_proc_entry(PROC_NAME, NULL); kernel_module } MODULE_LICENSE("GPL2"); YAPC::ASIA 2010 LIGHTNING TALKS
  • 64. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" side story obj-m += foo.o KDIR := /lib/modules/$(shell uname -r)/build PWD := $(shell pwd) default:         $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules clean:         rm -f *.o *.ko *.mod.c makefile YAPC::ASIA 2010 LIGHTNING TALKS
  • 65. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" side story sub shuffle {     my $array = shift;     our $pid;     if ($pid == 0) {         $pid = $$;         open my $pid_file, '>/sys/module/foo/pid';         print $pid_file $pid;         close $pid_file;     }     open my $utime_file, '+</proc/driver/utime';     my $utime = <$utime_file>;     my $result = champion($array);     print $utime_file $utime;     close $utime_file;     return $result; } perl YAPC::ASIA 2010 LIGHTNING TALKS
  • 66. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" side story sub shuffle {     my $array = shift;     our $pid;     if ($pid == 0) {         $pid = $$;         open my $pid_file, '>/sys/module/foo/pid';         print $pid_file $pid;         close $pid_file;     }     open my $utime_file, '+</proc/driver/utime';     my $utime = <$utime_file>;     my $result = champion($array);     print $utime_file $utime;     close $utime_file;     return $result; } He doesn’t write any shuffle code. perl YAPC::ASIA 2010 LIGHTNING TALKS
  • 67. THERE ARE SO MANY WAYS TO SHUFFLE IT season 4 "time trial" side story sub shuffle {     my $array = shift; a t     our $pid;     if ($pid == 0) { h e         $pid = $$;         open my $pid_file, '>/sys/module/foo/pid'; c         print $pid_file $pid;         close $pid_file; l e b     }     open my $utime_file, '+</proc/driver/utime';     my $utime = <$utime_file>; iva     my $result = champion($array); g     print $utime_file $utime; r     close $utime_file;     return $result; } o fHe doesn’t write any shuffle code. un perl YAPC::ASIA 2010 LIGHTNING TALKS
  • 68. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" Finally, it’s the final season. YAPC::ASIA 2010 LIGHTNING TALKS
  • 69. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" This title comes from a SF novel, written by Yasutaka Tsutsui. YAPC::ASIA 2010 LIGHTNING TALKS
  • 70. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" Prohibited characters are increasing week by week. YAPC::ASIA 2010 LIGHTNING TALKS
  • 71. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e ' # XXX your shuffle code here. ' The basic format is a one-liner like above. YAPC::ASIA 2010 LIGHTNING TALKS
  • 72. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e 'chomp(@m=<>);@i=(0..$#m);$j=@m;while ($j--) {$r=rand($j);@i[$j,$r]=@i[$r,$j]};for(0..$#m) {printf(qq{%s=>%s n},$m[$_],$m[$i[$_]])}' prohibits: At the start, there was no prohibited characters. YAPC::ASIA 2010 LIGHTNING TALKS
  • 73. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e 'chomp(@m=<>);@i=(0..$#m);$j=@m;while ($j--) {$r=rand($j);@i[$j,$r]=@i[$r,$j]};for(0..$#m) {printf(qq{%s=>%s n},$m[$_],$m[$i[$_]])}' prohibits: Next, using "0", "s" and "t" were prohibited. YAPC::ASIA 2010 LIGHTNING TALKS
  • 74. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e 'chomp(@m=<>);@i=(()..$#m); $j=@m;while($j--) {$r=rand($j);@i[$j,$r]=@i[$r,$j]};for(().. $#m) {warn $m[$_]." => ".$m[$i[$_]]."n"}' prohibits: 0 s t In the early stage, we couldn’t use printf(). warn() was used instead of it to output the result. YAPC::ASIA 2010 LIGHTNING TALKS
  • 75. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e 'chomp(@m=<>);@i=(()..$#m); $j=@m;while($j--) {$r=rand($j);@i[$j,$r]=@i[$r,$j]};for(().. $#m) {warn $m[$_]." => ".$m[$i[$_]]."n"}' prohibits: 0 s t Next, using "h", "k", "q" and " (double quotation) were prohibited. YAPC::ASIA 2010 LIGHTNING TALKS
  • 76. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '@m=<>;@i=(1-1..$#m);$j=$#m;for(; $j;$j--){$r=rand($j);@i[$j,$r]=@i[$r,$j]};for(()..$#m){warn $m [$_].''' => '''.$m[$i[$_]]}' prohibits: " 0 h k q s t We couldn’t use while(). And quotation operators made us painful. YAPC::ASIA 2010 LIGHTNING TALKS
  • 77. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '@m=<>;@i=(1-1..$#m);$j=$#m;for(; $j;$j--){$r=rand($j);@i[$j,$r]=@i[$r,$j]};for(()..$#m){warn $m [$_].''' => '''.$m[$i[$_]]}' prohibits: " 0 h k q s t Next, "y", "," and ";" were prohibited. YAPC::ASIA 2010 LIGHTNING TALKS
  • 78. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{@m=<> xor @i=(1-1..$#m) xor $j=@m} for(1..--$j){$r=rand($j) xor @i[$j--=>$r]=@i[$r=>$j]} for(()..$#m){warn $m[$_].''' => '''.$m[$i[$_]]}' prohibits: " , 0 ; h k q s t y We started to join each statements by "xor" operator. YAPC::ASIA 2010 LIGHTNING TALKS
  • 79. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{@m=<> xor @i=(1-1..$#m) xor $j=@m} for(1..--$j){$r=rand($j) xor @i[$j--=>$r]=@i[$r=>$j]} for(()..$#m){warn $m[$_].''' => '''.$m[$i[$_]]}' prohibits: " , 0 ; h k q s t y Next, "o" was prohibited. YAPC::ASIA 2010 LIGHTNING TALKS
  • 80. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{@m=<>} {@i=(1-1..$#m)} {$j=@m} {map {{$r=rand($j)}=>{@i[$j--=>$r]=@i[$r=>$j]}} (1..--$j)} map {warn $m[$_].''' => '''.$m[$i[$_]]} (()..$#m)' prohibits: " , 0 ; h k o q s t y xor was no longer available. YAPC::ASIA 2010 LIGHTNING TALKS
  • 81. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{@m=<>} {@i=(1-1..$#m)} {$j=@m} {map {{$r=rand($j)}=>{@i[$j--=>$r]=@i[$r=>$j]}} (1..--$j)} map {warn $m[$_].''' => '''.$m[$i[$_]]} (()..$#m)' prohibits: " , 0 ; h k o q s t y Next, "-" was prohibited. YAPC::ASIA 2010 LIGHTNING TALKS
  • 82. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{ $x=eval("x2d1") } {@m=<>} {@i= (()..$#m)} {$j=@m} {map {{$r=rand($j)}=>{@i[$j=>$r]=@i[$r=> $j]} => $j+=$x} (1..($j+=$x))} map {warn $m[$_].''' => '''. $m[$i[$_]]} (()..$#m)' prohibits: " , - 0 ; h k o q s t y We needed to require some creative thinking to do -1. YAPC::ASIA 2010 LIGHTNING TALKS
  • 83. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{ $x=eval("x2d1") } {@m=<>} {@i= (()..$#m)} {$j=@m} {map {{$r=rand($j)}=>{@i[$j=>$r]=@i[$r=> $j]} => $j+=$x} (1..($j+=$x))} map {warn $m[$_].''' => '''. $m[$i[$_]]} (()..$#m)' prohibits: " , - 0 ; h k o q s t y Next, "r" was prohibited. YAPC::ASIA 2010 LIGHTNING TALKS
  • 84. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{ $x=eval("x2d1") } {@m=<>} {@i= (()..$#m)} {$j=@m} {$v=$$}{map {{$v *= $v}=> {$p = $v % $j}=> {@i[$j=>$p]=@i[$p=>$j]} => $j+=$x} (1..($j+=$x))} {@d = map { $m[$_].''' => '''.$m[$i[$_]]} (()..$#m)} {die @d}' prohibits: " , - 0 ; h k o q r s t y We couldn’t use rand(). And also warn() was not available to output the result. YAPC::ASIA 2010 LIGHTNING TALKS
  • 85. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{ $x=eval("x2d1") } {@m=<>} {@i= (()..$#m)} {$j=@m} {$v=$$}{map {{$v *= $v}=> {$p = $v % $j}=> {@i[$j=>$p]=@i[$p=>$j]} => $j+=$x} (1..($j+=$x))} {@d = map { $m[$_].''' => '''.$m[$i[$_]]} (()..$#m)} {die @d}' prohibits: " , - 0 ; h k o q r s t y We considered that die() was the last way to output. YAPC::ASIA 2010 LIGHTNING TALKS
  • 86. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{ $x=eval("x2d1") } {@m=<>} {@i= (()..$#m)} {$j=@m} {$v=$$}{map {{$v *= $v}=> {$p = $v % $j}=> {@i[$j=>$p]=@i[$p=>$j]} => $j+=$x} (1..($j+=$x))} {@d = map { $m[$_].''' => '''.$m[$i[$_]]} (()..$#m)} {die @d}' prohibits: " , - 0 ; h k o q r s t y Next, "e" was prohibited. YAPC::ASIA 2010 LIGHTNING TALKS
  • 87. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{ $x='''L1'''^'''a''' } {@m=<>} {@i=(()..$#m)} {$j=@m} {$v=$$}{map {{$v = (45 * $v + 555) % (4 ** 5)}=> {$p = $v % $j}=>{@i[$j=>$p]=@i[$p=>$j]} => $j+=$x} (1..($j+=$x))} {map { $d .= $m[$_].''' => '''.$m[$i [$_]]} (()..$#m)} &$d' prohibits: " , - 0 ; e h k o q r s t y We couldn’t eval(). We couldn’t die(). YAPC::ASIA 2010 LIGHTNING TALKS
  • 88. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{ $x='''L1'''^'''a''' } {@m=<>} {@i=(()..$#m)} {$j=@m} {$v=$$}{map {{$v = (45 * $v + 555) % (4 ** 5)}=> {$p = $v % $j}=>{@i[$j=>$p]=@i[$p=>$j]} => $j+=$x} (1..($j+=$x))} {map { $d .= $m[$_].''' => '''.$m[$i [$_]]} (()..$#m)} &$d' prohibits: " , - 0 ; e h k o q r s t y The output result was like; "Undefined subroutine &main::clair => hiro ... called at -e line 1, <> line 7." YAPC::ASIA 2010 LIGHTNING TALKS
  • 89. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{ $x='''L1'''^'''a''' } {@m=<>} {@i=(()..$#m)} {$j=@m} {$v=$$}{map {{$v = (45 * $v + 555) % (4 ** 5)}=> {$p = $v % $j}=>{@i[$j=>$p]=@i[$p=>$j]} => $j+=$x} (1..($j+=$x))} {map { $d .= $m[$_].''' => '''.$m[$i [$_]]} (()..$#m)} &$d' prohibits: " , - 0 ; e h k o q r s t y Also, we started to use Linear congruential generators (LCGs) to generate a random digit. YAPC::ASIA 2010 LIGHTNING TALKS
  • 90. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{ $x='''L1'''^'''a''' } {@m=<>} {@i=(()..$#m)} {$j=@m} {$v=$$}{map {{$v = (45 * $v + 555) % (4 ** 5)}=> {$p = $v % $j}=>{@i[$j=>$p]=@i[$p=>$j]} => $j+=$x} (1..($j+=$x))} {map { $d .= $m[$_].''' => '''.$m[$i [$_]]} (()..$#m)} &$d' prohibits: " , - 0 ; e h k o q r s t y To tell you the truth, I’m not sure about it. Wikipedia it for ourselves. YAPC::ASIA 2010 LIGHTNING TALKS
  • 91. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{ $x='''L1'''^'''a''' } {@m=<>} {@i=(()..$#m)} {$j=@m} {$v=$$}{map {{$v = (45 * $v + 555) % (4 ** 5)}=> {$p = $v % $j}=>{@i[$j=>$p]=@i[$p=>$j]} => $j+=$x} (1..($j+=$x))} {map { $d .= $m[$_].''' => '''.$m[$i [$_]]} (()..$#m)} &$d' prohibits: " , - 0 ; e h k o q r s t y Next, "p" was prohibited. YAPC::ASIA 2010 LIGHTNING TALKS
  • 92. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{ $x='''L1'''^'''a''' } {@m=<>} {@i=(()..$#m)} {$j=@m} {$v=$$} {$zz='''z''' x ($j+= $x)} {$zz=~/z(??{({$v = (45 * $v + 555) % (4 ** 5)}=> {$z = $v % $j}=>{@i[$j=>$z]=@i[$z=>$j]} => $j+=$x) })/} {$zz='''z''' x @m}{$zz=~/z(??{( $d .= $m[$zzz].''' => '''.$m[$i[$zzz+ +]] ) })/ } &$d' prohibits: " , - 0 ; e h k o p q r s t y map() the last built-in function was gone. YAPC::ASIA 2010 LIGHTNING TALKS
  • 93. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{ $x='''L1'''^'''a''' } {@m=<>} {@i=(()..$#m)} {$j=@m} {$v=$$} {$zz='''z''' x ($j+= $x)} {$zz=~/z(??{({$v = (45 * $v + 555) % (4 ** 5)}=> {$z = $v % $j}=>{@i[$j=>$z]=@i[$z=>$j]} => $j+=$x) })/} {$zz='''z''' x @m}{$zz=~/z(??{( $d .= $m[$zzz].''' => '''.$m[$i[$zzz+ +]] ) })/ } &$d' prohibits: " , - 0 ; e h k o p q r s t y On this ocation, prohibited "a", "b", "c", "d", "f", "g", "i", "j", "l", "m", "n", "u", "v", "w" and "z" (every alphabet except "x"). YAPC::ASIA 2010 LIGHTNING TALKS
  • 94. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{ $x='''%'''|'''('''.1 } {@xx=<>} {@xxx=(()..$#xx)} {$xxxx=@xx} {$xxxxx=$$} {$xxxxxx='''x''' x ($xxxx+=$x)} {$xxxxxx=~/x(??{({$xxxxx = (45 * $xxxxx + 555) % (4 ** 5)}=> {$xxxxxxx = $xxxxx % $xxxx} =>{@xxx[$xxxx=>$xxxxxxx]=@xxx[$xxxxxxx=>$xxxx]} => $xxxx+= $x) })/} {$xxxxxx='''x''' x @xx}{$xxxxxx=~/x(?? {( $xxxxxxxxx .= $xx[$xxxxxxxx].''' => '''.$xx[$xxx [$xxxxxxxx++]] ) })/ } &$xxxxxxxxx' prohibits: " , - 0 ; a b c d e f g h i j k l m n o p q r s t u v w y z Does anybody fix my J’ai perdu le do de ma clarinette? YAPC::ASIA 2010 LIGHTNING TALKS
  • 95. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{ $x='''%'''|'''('''.1 } {@xx=<>} {@xxx=(()..$#xx)} {$xxxx=@xx} {$xxxxx=$$} {$xxxxxx='''x''' x ($xxxx+=$x)} {$xxxxxx=~/x(??{({$xxxxx = (45 * $xxxxx + 555) % (4 ** 5)}=> {$xxxxxxx = $xxxxx % $xxxx} =>{@xxx[$xxxx=>$xxxxxxx]=@xxx[$xxxxxxx=>$xxxx]} => $xxxx+= $x) })/} {$xxxxxx='''x''' x @xx}{$xxxxxx=~/x(?? {( $xxxxxxxxx .= $xx[$xxxxxxxx].''' => '''.$xx[$xxx [$xxxxxxxx++]] ) })/ } &$xxxxxxxxx' prohibits: " , - 0 ; a b c d e f g h i j k l m n o p q r s t u v w y z And finally, YAPC::ASIA 2010 LIGHTNING TALKS
  • 96. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{ $x='''%'''|'''('''.1 } {@xx=<>} {@xxx=(()..$#xx)} {$xxxx=@xx} {$xxxxx=$$} {$xxxxxx='''x''' x ($xxxx+=$x)} {$xxxxxx=~/x(??{({$xxxxx = (45 * $xxxxx + 555) % (4 ** 5)}=> {$xxxxxxx = $xxxxx % $xxxx} =>{@xxx[$xxxx=>$xxxxxxx]=@xxx[$xxxxxxx=>$xxxx]} => $xxxx+= $x) })/} {$xxxxxx='''x''' x @xx}{$xxxxxx=~/x(?? {( $xxxxxxxxx .= $xx[$xxxxxxxx].''' => '''.$xx[$xxx [$xxxxxxxx++]] ) })/ } &$xxxxxxxxx' prohibits: " , - 0 ; a b c d e f g h i j k l m n o p q r s t u v w y z We decided to prohibit the last best hope, "x". YAPC::ASIA 2010 LIGHTNING TALKS
  • 97. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{ $_1='''%'''|'''('''.1 } {$/ =''''''} {$_2=<>} {$*=1} {@_3=()} {$_2=~/^(.+?)$(??{{$_3 [$#_3+1]=$1}{$#_3?$_4.='''_''':''''''}{'''^'''}})/} {@_6=(()..$#_3)} {$_7=$#_3} {$_5=$$} {$_4=~/_(??{({$_5 = (45 * $_5 + 555) % (4 ** 5)}=> {$_11 = $_5 % $_7}=>{@_6[$_7=>$_11] =@_6[$_11=>$_7]} => $_7+=$_1) })/} {$_4.='''_'''}{$_4=~/_(?? {( $_8 .= $_3[$_9].''' => '''.$_3[$_6[$_9++]].''' ''' ) })/ } &$_8' prohibits: " , - 0 ; a b c d e f g h i j k l m n o p q r s t u v w x y z This is the final form without using alphabet. YAPC::ASIA 2010 LIGHTNING TALKS
  • 98. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{ $_1='''%'''|'''('''.1 } {$/ =''''''} {$_2=<>} {$*=1} {@_3=()} {$_2=~/^(.+?)$(??{{$_3 [$#_3+1]=$1}{$#_3?$_4.='''_''':''''''}{'''^'''}})/} {@_6=(()..$#_3)} {$_7=$#_3} {$_5=$$} {$_4=~/_(??{({$_5 = (45 * $_5 + 555) % (4 ** 5)}=> {$_11 = $_5 % $_7}=>{@_6[$_7=>$_11] =@_6[$_11=>$_7]} => $_7+=$_1) })/} {$_4.='''_'''}{$_4=~/_(?? {( $_8 .= $_3[$_9].''' => '''.$_3[$_6[$_9++]].''' ''' ) })/ } &$_8' prohibits: " , - 0 ; a b c d e f g h i j k l m n o p q r s t u v w x y z Actually, it doesn’t work with perl 5.10.x or later because $*, (deprecated) variable has been removed. YAPC::ASIA 2010 LIGHTNING TALKS
  • 99. THERE ARE SO MANY WAYS TO SHUFFLE IT final season "lipstick on an after-image" % cat members.txt | perl -e '{ $_1='''%'''|'''('''.1 } {$/ =''''''} {$_2=<>} {$*=1} {@_3=()} {$_2=~/^(.+?)$(??{{$_3 [$#_3+1]=$1}{$#_3?$_4.='''_''':''''''}{'''^'''}})/} {@_6=(()..$#_3)} {$_7=$#_3} {$_5=$$} {$_4=~/_(??{({$_5 = (45 * $_5 + 555) % (4 ** 5)}=> {$_11 = $_5 % $_7}=>{@_6[$_7=>$_11] =@_6[$_11=>$_7]} => $_7+=$_1) })/} {$_4.='''_'''}{$_4=~/_(?? {( $_8 .= $_3[$_9].''' => '''.$_3[$_6[$_9++]].''' ''' ) })/ } &$_8' prohibits: " , - 0 ; a b c d e f g h i j k l m n o p q r s t u v w x y z We are seeking a mature individual with excellent shuffle skills. YAPC::ASIA 2010 LIGHTNING TALKS
  • 100. THERE ARE SO MANY WAYS TO SHUFFLE IT the end YAPC::ASIA 2010 LIGHTNING TALKS