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