SlideShare a Scribd company logo
Perlでおねえさんを
                           救った話
   Perl saved a lady
     2012.9.28 @hiratara
I’m a reporter of gihyo.jp
I heard a rumor
that a lady is in
    trouble.
“フカシギ”のおねえさん
  She’s in trouble.
She can’t
answer a
question.
The question seems easy :)
Combinatorial
 explosion
For 10 by 10,
it takes 250,000 years
“Teacheeeeeeer!!!!!”
“Teacheeeeeeer!!!!!”
I wish
 to help her!!!!
Look
   the FreakOut Sticker.
50ms,
or
die
Speed up
   computation
Counting ways with perl


 ZBDD speeds up counting

 Knuth introduced simpath algorithm

 I implemented Algorithm::Simpath
Count ways in 9 by 9
6 years
use   strict;
use   warnings;
use   Algorithm::Simpath;
use   Algorithm::Simpath::GridMaker;

my $edges = create_edges(9, 9);
my $zdd = solve(
    start => '0,0',
    goal => "9,9",
    edges => $edges,
);
print $zdd->count, "n";
% time perl -Ilib teacher99.pl
4.10442087026325e+19
perl -Ilib teacher99.pl 115.88s user 0.69s
system 99% cpu 1:56.70 total
% time perl -Ilib teacher99.pl
4.10442087026325e+19
perl -Ilib teacher99.pl 115.88s user 0.69s
system 99% cpu 1:56.70 total
1,630,000
   times
Algorithm
example: 1 by 2

 s



            g
Out of 2^7 patterns,
     how many answers are there?
 s            s       s       s



          g       g       g       g

 s            s       s       s



          g       g       g       g

 s            s       s       s



          g       g       g       g
Out of 2^7 patterns,
     how many answers are there?
 s            s       s       s



          g       g       g       g

 s            s       s       s



          g       g       g       g

 s            s       s       s



          g       g       g       g
Number each edge

      2       5

  1       4       7


      3       6
    my %mate = %{$node->{mate}};
    my $next_grid_node = $grid_edge->[1];



               Binary Decision diagram
    $mate{$next_grid_node} = $next_grid_node unless exists $mate{$next_grid_node};

    {mate => %mate};
}

sub high_node($$) {                                          1
    my ($node, $grid_edge) = @_;
   s
       2
    my %mate = %{$node->{mate}};
  1                                           2                         2
    my @grid_nodes;
        3               g
    # loop detection
    return undef if ($mate{$grid_edge->[0]} / '') eq $grid_edge->[1];
                                             /
                            3                3
    for my $grid_node ($grid_edge->[0], $grid_edge->[1]) {
                                                                        3            3
        if (! exists $mate{$grid_node}) {
            push @grid_nodes, $grid_node; # That's the new grid node
        } elsif (! defined $mate{$grid_node}) { # Have already connected :/
            return undef;
        } else {
           4              4              4
            push @grid_nodes, $mate{$grid_node};
                                                     4
            $mate{$grid_node} = undef; # Connect to new grid node
                                                                 4           4       4   4
        }
    }

    $mate{$grid_nodes[0]} = $grid_nodes[1];
    $mate{$grid_nodes[1]} = $grid_nodes[0];
                                              ・・・・・・
    {mate => %mate};
            # delete mate which isn't frontier
            my $child_node = sub {
                my $new_node = shift;


                         Pruning trees
                defined $new_node or return undef;

                my $new_mate = $new_node->{mate};
                for (@done_grid_nodes) {
                    if ($_ eq $start || $_ eq $goal) {
                        return undef unless defined $new_mate->{$_} &&
                                            $new_mate->{$_} ne $_;
                    } elsif (defined $new_mate->{$_} &&
                        $new_mate->{$_} ne $_
                    ) {
               Stop computing if it will be impossible
                        return undef; # won't be connected forever
                    }
                  if 2 ways intersect
                    delete $new_node->{mate}{$_};
                }
                  if a node becomes a dead end
                return 1 if has_one_route $new_node, $start => $goal;

                $next_nodes_map{node_id $new_node} / $new_node;
                                                       /=
            };
            $node->{low} = $child_node->($low_node);
            $node->{high} = $child_node->($high_node);
BDD
                                    1
s
    2
1                           2               2
    3       g

                    3       3               3       3


        4       4       4       4       4       4   4   4

                            ・・・・・・
sub node_id($) {
                         Sharing trees
    my $node = shift;
    my $mate = $node->{mate};
    join "t", map {"$_-" . ($mate->{$_} / '')} sort keys %$mate;
                                          /
}

...
    my @active_nodes = ($top_node);
    for my $grid_edge (@grid_edges) { are connected
               Track how nodes
...
        my %next_nodes_map;
               Share 2 trees if{ they have same status
        for my $node (@active_nodes)
                                                                    of
               connections
            $next_nodes_map{node_id $new_node} / $new_node;
                                                /=
        };
...
    };
x is connected with y
                     in both diagram


    x    2   y       5           x   2   y       5

1                4       7   1               4       7


         3           6               3           6
Sharing
   the result of computation
                         1

                 2               2

         3       3               3       3


 4   4       4       4       4       4   4   4


     5                   5
Originally
we must have
2^5=16 patterns.
Now we have
only 2 patterns.
surprising
 compressibility
I’m not afraid of 不可思議.


    ※ 1不可思議 =
    1000000000000000000000
    0000000000000000000000
    000000000000000000000
Conclusion


Perl mongers had better help ladies!

Combinatorial explosion is bother.

Good algorithms are very important.
My implementation
https://github.com/hiratara/p5-Simpath

Reference
http://shogo82148.github.com/letscount/

More Related Content

PDF
Benchmarking Perl (Chicago UniForum 2006)
PDF
Business Rules with Brick
KEY
Extending Moose
PDF
CGI::Prototype (NPW 2006)
KEY
David Burgess's Presentation at Emerging Communication Conference & Awards 20...
DOCX
PERL for QA - Important Commands and applications
PDF
Regexes and-performance-testing
PPTX
Chap 3php array part 2
Benchmarking Perl (Chicago UniForum 2006)
Business Rules with Brick
Extending Moose
CGI::Prototype (NPW 2006)
David Burgess's Presentation at Emerging Communication Conference & Awards 20...
PERL for QA - Important Commands and applications
Regexes and-performance-testing
Chap 3php array part 2

What's hot (20)

PDF
Fnt Software Solutions Pvt Ltd Placement Papers - PHP Technology
PDF
Pim Elshoff "Technically DDD"
PDF
Creating a compiler in Perl 6
PPT
PHP and MySQL
PDF
Magicke metody v Pythonu
ZIP
TerminalでTwitter
PDF
Difference between mysql_fetch_array and mysql_fetch_assoc in PHP
PPTX
Php & my sql
PDF
Introdução ao Perl 6
TXT
Mythread.h
PDF
Wx::Perl::Smart
PDF
PHP Benelux 2012: Magic behind the numbers. Software metrics in practice
PPTX
OOP Is More Then Cars and Dogs - Midwest PHP 2017
TXT
Bouncingballs sh
PDF
Doctrator Symfony Live 2011 San Francisco
PDF
Internationalizing CakePHP Applications
KEY
how to hack with pack and unpack
PDF
Python dictionary : past, present, future
PDF
Ruby Topic Maps Tutorial (2007-10-10)
PDF
CakeFest 2013 keynote
Fnt Software Solutions Pvt Ltd Placement Papers - PHP Technology
Pim Elshoff "Technically DDD"
Creating a compiler in Perl 6
PHP and MySQL
Magicke metody v Pythonu
TerminalでTwitter
Difference between mysql_fetch_array and mysql_fetch_assoc in PHP
Php & my sql
Introdução ao Perl 6
Mythread.h
Wx::Perl::Smart
PHP Benelux 2012: Magic behind the numbers. Software metrics in practice
OOP Is More Then Cars and Dogs - Midwest PHP 2017
Bouncingballs sh
Doctrator Symfony Live 2011 San Francisco
Internationalizing CakePHP Applications
how to hack with pack and unpack
Python dictionary : past, present, future
Ruby Topic Maps Tutorial (2007-10-10)
CakeFest 2013 keynote
Ad

Viewers also liked (20)

KEY
Hachioji.pm in Machida の LT
PDF
Monads in python
PDF
カレーとHokkaidopm
PDF
Types and perl language
KEY
定理3
PDF
20120526 hachioji.pm
PDF
Git入門
KEY
循環参照のはなし
KEY
TraitとMoose::Role
PDF
Math::Category
PDF
Stateモナドの解説 後編
PDF
モデルから知るGit
PDF
モナモナ言うモナド入門.tar.gz
PDF
Stateモナドの解説 中編
KEY
Stateモナドの解説 前編
PDF
レンズ (ぶつかり稽古の没プレゼン)
PDF
ウヰスキーとPSGI
PDF
すべてが@__kanになる
KEY
Arrows in perl
PDF
AnyEvent and Plack
Hachioji.pm in Machida の LT
Monads in python
カレーとHokkaidopm
Types and perl language
定理3
20120526 hachioji.pm
Git入門
循環参照のはなし
TraitとMoose::Role
Math::Category
Stateモナドの解説 後編
モデルから知るGit
モナモナ言うモナド入門.tar.gz
Stateモナドの解説 中編
Stateモナドの解説 前編
レンズ (ぶつかり稽古の没プレゼン)
ウヰスキーとPSGI
すべてが@__kanになる
Arrows in perl
AnyEvent and Plack
Ad

Similar to Perl saved a lady. (20)

PDF
Monads in perl
PPTX
Perl6 a whistle stop tour
PDF
Perl6 a whistle stop tour
PPTX
Algorithms Design Exam Help
PDF
Thinking Functionally In Ruby
PPTX
How i won a golf set from reg.ru
PPT
PPTX
Algorithms Design Assignment Help
PDF
Maximum Likelihood Scaffold Assembly
PDF
MARTE Repetitive Structure Modeling
PPT
Prim's Algorithm on minimum spanning tree
PDF
Continuation Passing Style and Macros in Clojure - Jan 2012
PDF
Dades i operadors
PDF
Software Dendrology by Brandon Bloom
PDF
Advanced
PDF
Lgm pakdd2011 public
PDF
☣ ppencode ♨
PDF
Sketch sort sugiyamalab-20101026 - public
PDF
Gwt sdm public
PDF
234 rb trees2x2
Monads in perl
Perl6 a whistle stop tour
Perl6 a whistle stop tour
Algorithms Design Exam Help
Thinking Functionally In Ruby
How i won a golf set from reg.ru
Algorithms Design Assignment Help
Maximum Likelihood Scaffold Assembly
MARTE Repetitive Structure Modeling
Prim's Algorithm on minimum spanning tree
Continuation Passing Style and Macros in Clojure - Jan 2012
Dades i operadors
Software Dendrology by Brandon Bloom
Advanced
Lgm pakdd2011 public
☣ ppencode ♨
Sketch sort sugiyamalab-20101026 - public
Gwt sdm public
234 rb trees2x2

Recently uploaded (20)

PDF
Chapter 3 Spatial Domain Image Processing.pdf
PDF
Network Security Unit 5.pdf for BCA BBA.
PDF
Per capita expenditure prediction using model stacking based on satellite ima...
PPTX
Cloud computing and distributed systems.
PPTX
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
PDF
Advanced methodologies resolving dimensionality complications for autism neur...
PDF
KodekX | Application Modernization Development
PPTX
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PPTX
MYSQL Presentation for SQL database connectivity
PDF
Review of recent advances in non-invasive hemoglobin estimation
DOCX
The AUB Centre for AI in Media Proposal.docx
PPTX
A Presentation on Artificial Intelligence
PDF
Modernizing your data center with Dell and AMD
PDF
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
PPT
“AI and Expert System Decision Support & Business Intelligence Systems”
PDF
Spectral efficient network and resource selection model in 5G networks
PDF
Unlocking AI with Model Context Protocol (MCP)
PDF
Mobile App Security Testing_ A Comprehensive Guide.pdf
PPTX
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy
Chapter 3 Spatial Domain Image Processing.pdf
Network Security Unit 5.pdf for BCA BBA.
Per capita expenditure prediction using model stacking based on satellite ima...
Cloud computing and distributed systems.
VMware vSphere Foundation How to Sell Presentation-Ver1.4-2-14-2024.pptx
Advanced methodologies resolving dimensionality complications for autism neur...
KodekX | Application Modernization Development
PA Analog/Digital System: The Backbone of Modern Surveillance and Communication
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
MYSQL Presentation for SQL database connectivity
Review of recent advances in non-invasive hemoglobin estimation
The AUB Centre for AI in Media Proposal.docx
A Presentation on Artificial Intelligence
Modernizing your data center with Dell and AMD
Build a system with the filesystem maintained by OSTree @ COSCUP 2025
“AI and Expert System Decision Support & Business Intelligence Systems”
Spectral efficient network and resource selection model in 5G networks
Unlocking AI with Model Context Protocol (MCP)
Mobile App Security Testing_ A Comprehensive Guide.pdf
Detection-First SIEM: Rule Types, Dashboards, and Threat-Informed Strategy

Perl saved a lady.

  • 1. Perlでおねえさんを 救った話 Perl saved a lady 2012.9.28 @hiratara
  • 2. I’m a reporter of gihyo.jp
  • 3. I heard a rumor that a lady is in trouble.
  • 8. For 10 by 10, it takes 250,000 years
  • 11. I wish to help her!!!!
  • 12. Look the FreakOut Sticker.
  • 14. Speed up computation
  • 15. Counting ways with perl ZBDD speeds up counting Knuth introduced simpath algorithm I implemented Algorithm::Simpath
  • 16. Count ways in 9 by 9
  • 18. use strict; use warnings; use Algorithm::Simpath; use Algorithm::Simpath::GridMaker; my $edges = create_edges(9, 9); my $zdd = solve( start => '0,0', goal => "9,9", edges => $edges, ); print $zdd->count, "n";
  • 19. % time perl -Ilib teacher99.pl 4.10442087026325e+19 perl -Ilib teacher99.pl 115.88s user 0.69s system 99% cpu 1:56.70 total
  • 20. % time perl -Ilib teacher99.pl 4.10442087026325e+19 perl -Ilib teacher99.pl 115.88s user 0.69s system 99% cpu 1:56.70 total
  • 21. 1,630,000 times
  • 23. example: 1 by 2 s g
  • 24. Out of 2^7 patterns, how many answers are there? s s s s g g g g s s s s g g g g s s s s g g g g
  • 25. Out of 2^7 patterns, how many answers are there? s s s s g g g g s s s s g g g g s s s s g g g g
  • 26. Number each edge 2 5 1 4 7 3 6
  • 27.     my %mate = %{$node->{mate}};     my $next_grid_node = $grid_edge->[1]; Binary Decision diagram     $mate{$next_grid_node} = $next_grid_node unless exists $mate{$next_grid_node};     {mate => %mate}; } sub high_node($$) { 1     my ($node, $grid_edge) = @_; s 2     my %mate = %{$node->{mate}}; 1 2 2     my @grid_nodes; 3 g     # loop detection     return undef if ($mate{$grid_edge->[0]} / '') eq $grid_edge->[1]; / 3 3     for my $grid_node ($grid_edge->[0], $grid_edge->[1]) { 3 3         if (! exists $mate{$grid_node}) {             push @grid_nodes, $grid_node; # That's the new grid node         } elsif (! defined $mate{$grid_node}) { # Have already connected :/             return undef;         } else { 4 4 4             push @grid_nodes, $mate{$grid_node}; 4             $mate{$grid_node} = undef; # Connect to new grid node 4 4 4 4         }     }     $mate{$grid_nodes[0]} = $grid_nodes[1];     $mate{$grid_nodes[1]} = $grid_nodes[0]; ・・・・・・     {mate => %mate};
  • 28.             # delete mate which isn't frontier             my $child_node = sub {                 my $new_node = shift; Pruning trees                 defined $new_node or return undef;                 my $new_mate = $new_node->{mate};                 for (@done_grid_nodes) {                     if ($_ eq $start || $_ eq $goal) {                         return undef unless defined $new_mate->{$_} &&                                             $new_mate->{$_} ne $_;                     } elsif (defined $new_mate->{$_} &&                         $new_mate->{$_} ne $_                     ) { Stop computing if it will be impossible                         return undef; # won't be connected forever                     } if 2 ways intersect                     delete $new_node->{mate}{$_};                 } if a node becomes a dead end                 return 1 if has_one_route $new_node, $start => $goal;                 $next_nodes_map{node_id $new_node} / $new_node; /=             };             $node->{low} = $child_node->($low_node);             $node->{high} = $child_node->($high_node);
  • 29. BDD 1 s 2 1 2 2 3 g 3 3 3 3 4 4 4 4 4 4 4 4 ・・・・・・
  • 30. sub node_id($) { Sharing trees     my $node = shift;     my $mate = $node->{mate};     join "t", map {"$_-" . ($mate->{$_} / '')} sort keys %$mate; / } ...     my @active_nodes = ($top_node);     for my $grid_edge (@grid_edges) { are connected Track how nodes ...         my %next_nodes_map; Share 2 trees if{ they have same status         for my $node (@active_nodes) of connections             $next_nodes_map{node_id $new_node} / $new_node; /=         }; ...     };
  • 31. x is connected with y in both diagram x 2 y 5 x 2 y 5 1 4 7 1 4 7 3 6 3 6
  • 32. Sharing the result of computation 1 2 2 3 3 3 3 4 4 4 4 4 4 4 4 5 5
  • 33. Originally we must have 2^5=16 patterns. Now we have only 2 patterns.
  • 35. I’m not afraid of 不可思議. ※ 1不可思議 = 1000000000000000000000 0000000000000000000000 000000000000000000000
  • 36. Conclusion Perl mongers had better help ladies! Combinatorial explosion is bother. Good algorithms are very important.

Editor's Notes