line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Algorithm::RectanglesContainingDot; |
2
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
24858
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
39
|
|
4
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
1411
|
|
5
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
our $VERSION = '0.02'; |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
package |
9
|
|
|
|
|
|
|
Algorithm::RectanglesContainingDot::Perl; |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
our $MIN_DIV = 8; |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
sub new { |
14
|
2
|
|
|
2
|
|
24
|
my $class = shift; |
15
|
2
|
|
|
|
|
7
|
my $self = { rects => [], |
16
|
|
|
|
|
|
|
names => [] }; |
17
|
2
|
|
|
|
|
9
|
bless $self, $class; |
18
|
|
|
|
|
|
|
} |
19
|
|
|
|
|
|
|
|
20
|
0
|
|
|
0
|
|
0
|
sub _reset { delete shift->{div} } |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
sub add_rectangle { |
23
|
20000
|
|
|
20000
|
|
96153
|
my ($self, $name, $x0, $y0, $x1, $y1) = @_; |
24
|
|
|
|
|
|
|
|
25
|
20000
|
50
|
|
|
|
37217
|
($x0, $x1) = ($x1, $x0) if $x0 > $x1; |
26
|
20000
|
50
|
|
|
|
33355
|
($y0, $y1) = ($y1, $y0) if $y0 > $y1; |
27
|
|
|
|
|
|
|
|
28
|
20000
|
|
|
|
|
18630
|
push @{$self->{rects}}, ($x0, $y0, $x1, $y1); |
|
20000
|
|
|
|
|
44695
|
|
29
|
20000
|
|
|
|
|
20793
|
push @{$self->{names}}, $name; |
|
20000
|
|
|
|
|
49815
|
|
30
|
20000
|
|
|
|
|
44250
|
delete $self->{div}; |
31
|
|
|
|
|
|
|
} |
32
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
|
sub rectangles_containing_dot { |
34
|
2000
|
|
|
2000
|
|
1897373
|
my $self = shift; |
35
|
2000
|
|
66
|
|
|
11872
|
my $div = $self->{div} || $self->_init_div; |
36
|
2000
|
|
|
|
|
11149
|
@{$self->{names}}[_rectangles_containing_dot($div, $self->{rects}, @_)]; |
|
2000
|
|
|
|
|
41840
|
|
37
|
|
|
|
|
|
|
} |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
sub _rectangles_containing_dot_ref { |
40
|
2000
|
|
|
2000
|
|
14472
|
my ($self, $x, $y) = @_; |
41
|
2000
|
|
|
|
|
4546
|
my $names = $self->{names}; |
42
|
2000
|
|
|
|
|
4333
|
my $rects = $self->{rects}; |
43
|
2000
|
|
|
|
|
2598
|
my @ret; |
44
|
2000
|
|
|
|
|
6905
|
for (0..$#$names) { |
45
|
20000000
|
|
|
|
|
18581439
|
my $i0 = $_ * 4; |
46
|
20000000
|
100
|
100
|
|
|
53297819
|
if ($rects->[$i0] <= $x and |
|
|
|
100
|
|
|
|
|
|
|
|
100
|
|
|
|
|
47
|
|
|
|
|
|
|
$rects->[$i0+1] <= $y and |
48
|
|
|
|
|
|
|
$rects->[$i0+2] >= $x and |
49
|
|
|
|
|
|
|
$rects->[$i0+3] >= $y) { |
50
|
37926
|
|
|
|
|
77487
|
push @ret, $names->[$_]; |
51
|
|
|
|
|
|
|
} |
52
|
|
|
|
|
|
|
} |
53
|
2000
|
|
|
|
|
62806
|
@ret; |
54
|
|
|
|
|
|
|
} |
55
|
|
|
|
|
|
|
|
56
|
|
|
|
|
|
|
# div is: |
57
|
|
|
|
|
|
|
# x/y, right_div, left_div, point, all |
58
|
|
|
|
|
|
|
|
59
|
|
|
|
|
|
|
sub _init_div { |
60
|
1
|
|
|
1
|
|
5
|
my $self = shift; |
61
|
1
|
|
|
|
|
3
|
$self->{div} = [undef, undef, undef, undef, [0..$#{$self->{names}}]] |
|
1
|
|
|
|
|
2254
|
|
62
|
|
|
|
|
|
|
} |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
sub _rectangles_containing_dot { |
65
|
2000
|
|
|
2000
|
|
4765
|
my ($div, $rects, $x, $y) = @_; |
66
|
|
|
|
|
|
|
# print "."; |
67
|
2000
|
|
|
|
|
3678
|
while (1) { |
68
|
27750
|
|
66
|
|
|
73827
|
my $dir = $div->[0] || _divide_rects($div, $rects); |
69
|
|
|
|
|
|
|
|
70
|
27750
|
100
|
|
|
|
61324
|
if ($dir eq 'n') { |
71
|
2000
|
|
|
|
|
3322
|
my @ret; |
72
|
2000
|
|
|
|
|
3535
|
for (@{$div->[4]}) { |
|
2000
|
|
|
|
|
6998
|
|
73
|
83175
|
|
|
|
|
130590
|
my ($x0, $y0, $x1, $y1) = @{$rects}[4*$_ .. 4*$_+3]; |
|
83175
|
|
|
|
|
158466
|
|
74
|
83175
|
100
|
100
|
|
|
456887
|
push @ret, $_ |
|
|
|
100
|
|
|
|
|
|
|
|
66
|
|
|
|
|
75
|
|
|
|
|
|
|
if ($x >= $x0 and $x <= $x1 and $y >= $y0 && $y <= $y1); |
76
|
|
|
|
|
|
|
} |
77
|
2000
|
|
|
|
|
11059
|
return @ret; |
78
|
|
|
|
|
|
|
} |
79
|
|
|
|
|
|
|
|
80
|
25750
|
100
|
|
|
|
78170
|
$div = $div->[(($dir eq 'x') ? ($x <= $div->[3]) : ($y <= $div->[3])) ? 1 : 2]; |
|
|
100
|
|
|
|
|
|
81
|
|
|
|
|
|
|
} |
82
|
|
|
|
|
|
|
} |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
sub _find_best_div { |
85
|
2072
|
|
|
2072
|
|
3086
|
my ($dr, $rects, $off) = @_; |
86
|
|
|
|
|
|
|
|
87
|
2072
|
|
|
|
|
6141
|
my @v0 = map { @{$rects}[$_*4+$off] } @$dr; |
|
486478
|
|
|
|
|
504468
|
|
|
486478
|
|
|
|
|
960104
|
|
88
|
2072
|
|
|
|
|
23031
|
my @v1 = map { @{$rects}[$_*4+2+$off] } @$dr; |
|
486478
|
|
|
|
|
515262
|
|
|
486478
|
|
|
|
|
740885
|
|
89
|
2072
|
|
|
|
|
25341
|
@v0 = sort { $a <=> $b } @v0; |
|
3561999
|
|
|
|
|
3273639
|
|
90
|
2072
|
|
|
|
|
9657
|
@v1 = sort { $a <=> $b } @v1; |
|
3591172
|
|
|
|
|
3195535
|
|
91
|
|
|
|
|
|
|
|
92
|
2072
|
|
|
|
|
4906
|
my $med = 0.5 * @$dr; |
93
|
2072
|
|
|
|
|
3862
|
my $op = 0; |
94
|
2072
|
|
|
|
|
2436
|
my $cl = 0; |
95
|
2072
|
|
|
|
|
5272
|
my $best = @$dr * @$dr; |
96
|
2072
|
|
|
|
|
3038
|
my $bestv; |
97
|
|
|
|
|
|
|
# my ($bestop, $bestcl); |
98
|
2072
|
|
66
|
|
|
13026
|
while (@v0 and @v1) { |
99
|
41563
|
100
|
|
|
|
79962
|
my $v = ($v0[0] <= $v1[0]) ? $v0[0] : $v1[0]; |
100
|
41563
|
|
100
|
|
|
153776
|
while (@v0 and $v0[0] == $v) { |
101
|
486478
|
|
|
|
|
446388
|
$op++; |
102
|
486478
|
|
|
|
|
1803866
|
shift @v0; |
103
|
|
|
|
|
|
|
} |
104
|
41563
|
|
66
|
|
|
169121
|
while (@v1 and $v1[0] == $v) { |
105
|
238343
|
|
|
|
|
223789
|
$cl++; |
106
|
238343
|
|
|
|
|
866526
|
shift @v1; |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
|
109
|
41563
|
|
|
|
|
56012
|
my $l = $op - $med; |
110
|
41563
|
|
|
|
|
55108
|
my $r = @$dr - $cl - $med; |
111
|
41563
|
|
|
|
|
57175
|
my $good = $l * $l + $r * $r; |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
#{ no warnings; print STDERR "med: $med, op: $op, cl: $cl, good: $good, best: $best, bestv: $bestv\n"; } |
114
|
|
|
|
|
|
|
|
115
|
41563
|
100
|
|
|
|
115564
|
if ($good < $best) { |
116
|
29536
|
|
|
|
|
28981
|
$best = $good; |
117
|
29536
|
|
|
|
|
127082
|
$bestv = $v; |
118
|
|
|
|
|
|
|
# $bestop = $op; |
119
|
|
|
|
|
|
|
# $bestcl = $cl; |
120
|
|
|
|
|
|
|
} |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
# print "off: $off, best: $best, bestv: $bestv, bestop: $bestop, bestcl: $bestcl, size-bestcl: ".(@$dr-$bestcl)."\n"; |
123
|
2072
|
|
|
|
|
14692
|
return ($best, $bestv); |
124
|
|
|
|
|
|
|
} |
125
|
|
|
|
|
|
|
|
126
|
|
|
|
|
|
|
sub _divide_rects { |
127
|
1036
|
|
|
1036
|
|
2156
|
my ($div, $rects) = @_; |
128
|
1036
|
|
|
|
|
1610
|
my $dr = $div->[4]; |
129
|
1036
|
50
|
|
|
|
2924
|
return $div->[0] = 'n' if (@$dr <= $MIN_DIV); |
130
|
1036
|
|
|
|
|
2363
|
my $bestreq = 0.24 * @$dr * @$dr; |
131
|
1036
|
|
|
|
|
2803
|
my ($bestx, $bestxx) = _find_best_div($dr, $rects, 0); |
132
|
1036
|
50
|
|
|
|
4716
|
my ($besty, $bestyy) = ($bestx == 0) ? 1 : _find_best_div($dr, $rects, 1); |
133
|
|
|
|
|
|
|
# print "bestx: $bestx, bestxx: $bestxx, besty: $besty, bestyy: $bestyy, bestreq: $bestreq\n"; |
134
|
1036
|
100
|
|
|
|
4005
|
if ($bestx < $besty) { |
135
|
509
|
100
|
|
|
|
2020
|
if ($bestx < $bestreq) { |
136
|
365
|
|
|
|
|
1891
|
@{$div}[1,2] = _part_rects($dr, $rects, $bestxx, 0); |
|
365
|
|
|
|
|
1238
|
|
137
|
365
|
|
|
|
|
775
|
$div->[3] = $bestxx; |
138
|
365
|
|
|
|
|
548
|
pop @$div; |
139
|
365
|
|
|
|
|
10749
|
return $div->[0] = 'x'; |
140
|
|
|
|
|
|
|
} |
141
|
|
|
|
|
|
|
} |
142
|
|
|
|
|
|
|
else { |
143
|
527
|
100
|
|
|
|
2645
|
if ($besty < $bestreq) { |
144
|
327
|
|
|
|
|
1486
|
@{$div}[1,2] = _part_rects($dr, $rects, $bestyy, 1); |
|
327
|
|
|
|
|
1261
|
|
145
|
327
|
|
|
|
|
755
|
$div->[3] = $bestyy; |
146
|
327
|
|
|
|
|
424
|
pop @$div; |
147
|
327
|
|
|
|
|
5307
|
return $div->[0] = 'y'; |
148
|
|
|
|
|
|
|
} |
149
|
|
|
|
|
|
|
} |
150
|
344
|
|
|
|
|
2382
|
return $div->[0] = 'n'; |
151
|
|
|
|
|
|
|
} |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
sub _part_rects { |
154
|
692
|
|
|
692
|
|
1743
|
my ($dr, $rects, $bestv, $off) = @_; |
155
|
692
|
|
|
|
|
1186
|
my (@l, @r); |
156
|
692
|
|
|
|
|
2267
|
for (@$dr) { |
157
|
202863
|
100
|
|
|
|
484496
|
push @l, $_ if ($bestv >= $rects->[$_ * 4 + $off]); |
158
|
202863
|
100
|
|
|
|
463676
|
push @r, $_ if ($bestv < $rects->[$_ * 4 + $off + 2]); |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
# print "off: $off, left: ".scalar(@l).", right: ".scalar(@r)."\n"; |
161
|
692
|
|
|
|
|
6013
|
return ([undef, undef, undef, undef, \@l], |
162
|
|
|
|
|
|
|
[undef, undef, undef, undef, \@r]) |
163
|
|
|
|
|
|
|
} |
164
|
|
|
|
|
|
|
|
165
|
|
|
|
|
|
|
package Algorithm::RectanglesContainingDot; |
166
|
|
|
|
|
|
|
|
167
|
|
|
|
|
|
|
our @ISA; |
168
|
|
|
|
|
|
|
if (eval "require Algorithm::RectanglesContainingDot_XS") { |
169
|
|
|
|
|
|
|
@ISA = qw(Algorithm::RectanglesContainingDot_XS); |
170
|
|
|
|
|
|
|
} |
171
|
|
|
|
|
|
|
else { |
172
|
|
|
|
|
|
|
@ISA = qw(Algorithm::RectanglesContainingDot::Perl); |
173
|
|
|
|
|
|
|
} |
174
|
|
|
|
|
|
|
|
175
|
|
|
|
|
|
|
1; |
176
|
|
|
|
|
|
|
__END__ |