More than Just Lines on a Map: Best Practices for U.S Bike Routes
Pdfasslide
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