| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Path::Hilbert::BigInt; |
|
2
|
|
|
|
|
|
|
|
|
3
|
1
|
|
|
1
|
|
349
|
use strict; |
|
|
1
|
|
|
|
|
3
|
|
|
|
1
|
|
|
|
|
41
|
|
|
4
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
22
|
|
|
5
|
1
|
|
|
1
|
|
26
|
use 5.012; |
|
|
1
|
|
|
|
|
4
|
|
|
|
1
|
|
|
|
|
42
|
|
|
6
|
1
|
|
|
1
|
|
4
|
use utf8; |
|
|
1
|
|
|
|
|
1
|
|
|
|
1
|
|
|
|
|
8
|
|
|
7
|
|
|
|
|
|
|
|
|
8
|
1
|
|
|
1
|
|
609
|
use Math::BigRat try => 'GMP,Pari,Calc'; |
|
|
1
|
|
|
|
|
90912
|
|
|
|
1
|
|
|
|
|
5
|
|
|
9
|
1
|
|
|
1
|
|
1546
|
use Math::BigInt try => 'GMP,Pari,Calc'; |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
4
|
|
|
10
|
|
|
|
|
|
|
|
|
11
|
1
|
|
|
1
|
|
685
|
use Exporter qw( import ); |
|
|
1
|
|
|
|
|
2
|
|
|
|
1
|
|
|
|
|
653
|
|
|
12
|
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
our @EXPORT = qw( xy2d d2xy ); |
|
14
|
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
our $VERSION = '1.203'; |
|
16
|
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# optional constructor if you want OO-style |
|
18
|
|
|
|
|
|
|
sub new { |
|
19
|
0
|
|
|
0
|
0
|
0
|
my $class = shift; |
|
20
|
0
|
|
|
|
|
0
|
my ($n) = @_; |
|
21
|
0
|
|
|
|
|
0
|
return bless { n => $n } => $class; |
|
22
|
|
|
|
|
|
|
} |
|
23
|
|
|
|
|
|
|
|
|
24
|
|
|
|
|
|
|
# convert (x,y) to d |
|
25
|
|
|
|
|
|
|
sub xy2d { |
|
26
|
1360
|
|
|
1360
|
0
|
149886
|
my ($side, $x, $y) = @_; |
|
27
|
1360
|
|
|
|
|
3129
|
my $n = _valid_n($side); |
|
28
|
1360
|
|
|
|
|
35522
|
($x, $y) = map { Math::BigInt->new("$_") } ($x, $y); |
|
|
2720
|
|
|
|
|
40922
|
|
|
29
|
1360
|
|
|
|
|
37734
|
my $d = Math::BigInt->bzero(); |
|
30
|
1360
|
|
|
|
|
22194
|
for (my $s = $n->copy()->brsft(1); $s->bcmp(0) > 0; $s->brsft(1)) { |
|
31
|
19720
|
100
|
|
|
|
3913385
|
my $rx = Math::BigInt->new($x->copy()->band($s)->bcmp(0) > 0 ? "1" : "0"); |
|
32
|
19720
|
100
|
|
|
|
4324686
|
my $ry = Math::BigInt->new($y->copy()->band($s)->bcmp(0) > 0 ? "1" : "0"); |
|
33
|
19720
|
|
|
|
|
4307337
|
my $three_rx = $rx->copy()->bmul("3"); |
|
34
|
19720
|
|
|
|
|
1867933
|
my $s_squared = $s->copy()->bpow("2"); |
|
35
|
19720
|
|
|
|
|
2423141
|
$d->badd($s_squared->bmul($three_rx->bxor($ry))); |
|
36
|
19720
|
|
|
|
|
2110939
|
($x, $y) = _rot($s, $x, $y, $rx, $ry); |
|
37
|
|
|
|
|
|
|
} |
|
38
|
1360
|
|
|
|
|
277094
|
return Math::BigRat->new($d); |
|
39
|
|
|
|
|
|
|
} |
|
40
|
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
# convert d to (x,y) |
|
42
|
|
|
|
|
|
|
sub d2xy { |
|
43
|
1360
|
|
|
1360
|
0
|
6591
|
my ($side, $d) = @_; |
|
44
|
1360
|
|
|
|
|
3246
|
my $n = _valid_n($side); |
|
45
|
1360
|
|
|
|
|
47387
|
my $t = Math::BigInt->new($d); |
|
46
|
1360
|
|
|
|
|
29413
|
my ($x, $y) = map { Math::BigInt->bzero() } (1 .. 2); |
|
|
2720
|
|
|
|
|
34688
|
|
|
47
|
1360
|
|
|
|
|
21981
|
for (my $s = Math::BigInt->bone(); $s->bcmp($n) < 0; $s->blsft(1)) { |
|
48
|
19720
|
|
|
|
|
3726868
|
my $rx = $t->copy()->brsft(1)->band(Math::BigInt->bone()); |
|
49
|
19720
|
|
|
|
|
3098140
|
my $ry = $t->copy()->bxor($rx)->band(Math::BigInt->bone()); |
|
50
|
19720
|
|
|
|
|
2171060
|
($x, $y) = _rot($s, $x, $y, $rx, $ry); |
|
51
|
19720
|
|
|
|
|
44563
|
my $Dx = $s->copy()->bmul($rx); |
|
52
|
19720
|
|
|
|
|
983015
|
my $Dy = $s->copy()->bmul($ry); |
|
53
|
19720
|
50
|
|
|
|
879757
|
$Dx >= 0 ? $x->badd($Dx) : $x->bsub($Dx->copy()->babs()); |
|
54
|
19720
|
50
|
|
|
|
2621605
|
$Dy >= 0 ? $y->badd($Dy) : $y->bsub($Dy->copy()->babs()); |
|
55
|
19720
|
|
|
|
|
2530177
|
$t->brsft(2); |
|
56
|
|
|
|
|
|
|
} |
|
57
|
1360
|
|
|
|
|
257586
|
return map { Math::BigRat->new($_) } ($x, $y); |
|
|
2720
|
|
|
|
|
156869
|
|
|
58
|
|
|
|
|
|
|
} |
|
59
|
|
|
|
|
|
|
|
|
60
|
|
|
|
|
|
|
# rotate/flip a quadrant appropriately |
|
61
|
|
|
|
|
|
|
sub _rot { |
|
62
|
39440
|
|
|
39440
|
|
55245
|
my ($n, $x, $y, $rx, $ry) = @_; |
|
63
|
39440
|
100
|
|
|
|
97185
|
if (!$ry) { |
|
64
|
36134
|
100
|
|
|
|
786003
|
if ($rx > 0) { |
|
65
|
1224
|
|
|
|
|
128819
|
$x = $n - 1 - $x; |
|
66
|
1224
|
|
|
|
|
247578
|
$y = $n - 1 - $y; |
|
67
|
|
|
|
|
|
|
} |
|
68
|
36134
|
|
|
|
|
3755328
|
($x, $y) = ($y, $x); |
|
69
|
|
|
|
|
|
|
} |
|
70
|
39440
|
|
|
|
|
203883
|
return ($x, $y); |
|
71
|
|
|
|
|
|
|
} |
|
72
|
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
sub _valid_n { |
|
74
|
2720
|
|
|
2720
|
|
7742
|
my $n = _extract_side(shift(@_)); |
|
75
|
2720
|
|
100
|
|
|
5179
|
$n = 2 ** int((eval { (log($n) / log(2)) } || 0) + 0.5); |
|
76
|
2720
|
|
|
|
|
10608
|
return Math::BigInt->new(int($n)); |
|
77
|
|
|
|
|
|
|
} |
|
78
|
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
sub _extract_side { |
|
80
|
2720
|
|
|
2720
|
|
3475
|
my ($side) = @_; |
|
81
|
2720
|
50
|
33
|
|
|
10788
|
$side = $side->{ n } if ref($side) eq 'HASH' && exists $side->{ n }; |
|
82
|
2720
|
|
|
|
|
4361
|
return $side; |
|
83
|
|
|
|
|
|
|
} |
|
84
|
|
|
|
|
|
|
|
|
85
|
|
|
|
|
|
|
1; |
|
86
|
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
__END__ |