Uploaded on

 

More in: Technology , Business
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Be the first to comment
    Be the first to like this
No Downloads

Views

Total Views
467
On Slideshare
0
From Embeds
0
Number of Embeds
0

Actions

Shares
Downloads
2
Comments
0
Likes
0

Embeds 0

No embeds

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
    No notes for slide

Transcript

  • 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