Filename | /Users/ap13/perl5/lib/perl5/Graph/UnionFind.pm |
Statements | Executed 3 statements in 484µs |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 12µs | 25µs | BEGIN@3 | Graph::UnionFind::
0 | 0 | 0 | 0s | 0s | _parent | Graph::UnionFind::
0 | 0 | 0 | 0s | 0s | _rank | Graph::UnionFind::
0 | 0 | 0 | 0s | 0s | add | Graph::UnionFind::
0 | 0 | 0 | 0s | 0s | find | Graph::UnionFind::
0 | 0 | 0 | 0s | 0s | has | Graph::UnionFind::
0 | 0 | 0 | 0s | 0s | new | Graph::UnionFind::
0 | 0 | 0 | 0s | 0s | same | Graph::UnionFind::
0 | 0 | 0 | 0s | 0s | union | Graph::UnionFind::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | package Graph::UnionFind; | ||||
2 | |||||
3 | 2 | 482µs | 2 | 38µs | # spent 25µs (12+13) within Graph::UnionFind::BEGIN@3 which was called:
# once (12µs+13µs) by Graph::BEGIN@31 at line 3 # spent 25µs making 1 call to Graph::UnionFind::BEGIN@3
# spent 13µs making 1 call to strict::import |
4 | |||||
5 | sub _PARENT () { 0 } | ||||
6 | sub _RANK () { 1 } | ||||
7 | |||||
8 | sub new { | ||||
9 | my $class = shift; | ||||
10 | bless { }, $class; | ||||
11 | } | ||||
12 | |||||
13 | sub add { | ||||
14 | my ($self, $elem) = @_; | ||||
15 | $self->{ $elem } = [ $elem, 0 ] unless defined $self->{$elem}; | ||||
16 | } | ||||
17 | |||||
18 | sub has { | ||||
19 | my ($self, $elem) = @_; | ||||
20 | exists $self->{ $elem }; | ||||
21 | } | ||||
22 | |||||
23 | sub _parent { | ||||
24 | return undef unless defined $_[1]; | ||||
25 | if (@_ == 2) { | ||||
26 | exists $_[0]->{ $_[ 1 ] } ? $_[0]->{ $_[1] }->[ _PARENT ] : undef; | ||||
27 | } elsif (@_ == 3) { | ||||
28 | $_[0]->{ $_[1] }->[ _PARENT ] = $_[2]; | ||||
29 | } else { | ||||
30 | require Carp; | ||||
31 | Carp::croak(__PACKAGE__ . "::_parent: bad arity"); | ||||
32 | } | ||||
33 | } | ||||
34 | |||||
35 | sub _rank { | ||||
36 | return unless defined $_[1]; | ||||
37 | if (@_ == 2) { | ||||
38 | exists $_[0]->{ $_[1] } ? $_[0]->{ $_[1] }->[ _RANK ] : undef; | ||||
39 | } elsif (@_ == 3) { | ||||
40 | $_[0]->{ $_[1] }->[ _RANK ] = $_[2]; | ||||
41 | } else { | ||||
42 | require Carp; | ||||
43 | Carp::croak(__PACKAGE__ . "::_rank: bad arity"); | ||||
44 | } | ||||
45 | } | ||||
46 | |||||
47 | sub find { | ||||
48 | my ($self, $x) = @_; | ||||
49 | my $px = $self->_parent( $x ); | ||||
50 | return unless defined $px; | ||||
51 | $self->_parent( $x, $self->find( $px ) ) if $px ne $x; | ||||
52 | $self->_parent( $x ); | ||||
53 | } | ||||
54 | |||||
55 | sub union { | ||||
56 | my ($self, $x, $y) = @_; | ||||
57 | $self->add($x) unless $self->has($x); | ||||
58 | $self->add($y) unless $self->has($y); | ||||
59 | my $px = $self->find( $x ); | ||||
60 | my $py = $self->find( $y ); | ||||
61 | return if $px eq $py; | ||||
62 | my $rx = $self->_rank( $px ); | ||||
63 | my $ry = $self->_rank( $py ); | ||||
64 | # print "union($x, $y): px = $px, py = $py, rx = $rx, ry = $ry\n"; | ||||
65 | if ( $rx > $ry ) { | ||||
66 | $self->_parent( $py, $px ); | ||||
67 | } else { | ||||
68 | $self->_parent( $px, $py ); | ||||
69 | $self->_rank( $py, $ry + 1 ) if $rx == $ry; | ||||
70 | } | ||||
71 | } | ||||
72 | |||||
73 | sub same { | ||||
74 | my ($uf, $u, $v) = @_; | ||||
75 | my $fu = $uf->find($u); | ||||
76 | return undef unless defined $fu; | ||||
77 | my $fv = $uf->find($v); | ||||
78 | return undef unless defined $fv; | ||||
79 | $fu eq $fv; | ||||
80 | } | ||||
81 | |||||
82 | 1 | 2µs | 1; | ||
83 | __END__ |