|  line  | 
 stmt  | 
 bran  | 
 cond  | 
 sub  | 
 pod  | 
 time  | 
 code  | 
| 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Copyright 2012, 2013, 2014, 2015 Kevin Ryde  | 
| 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
3
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # This file is part of Math-PlanePath-Toothpick.  | 
| 
4
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
5
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Math-PlanePath-Toothpick is free software; you can redistribute it and/or  | 
| 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # modify it under the terms of the GNU General Public License as published  | 
| 
7
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # by the Free Software Foundation; either version 3, or (at your option) any  | 
| 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # later version.  | 
| 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
10
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Math-PlanePath-Toothpick is distributed in the hope that it will be  | 
| 
11
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of  | 
| 
12
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General  | 
| 
13
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Public License for more details.  | 
| 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
15
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # You should have received a copy of the GNU General Public License along  | 
| 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # with Math-PlanePath-Toothpick.  If not, see .  | 
| 
17
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
18
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # block_order => 'AB123'  | 
| 
19
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # block_order => 'A1B32' is depth first and finite parts first,  | 
| 
20
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # in parts=1 where single infinite spine  | 
| 
21
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
22
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # maybe tree methods same structure as ToothpickTree  | 
| 
23
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # cf A175262 odd binary length and middle digit 1  | 
| 
26
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #    A175263 odd binary length and middle digit 0  | 
| 
27
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
28
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
29
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 package Math::PlanePath::ToothpickReplicate;  | 
| 
30
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
1315
 | 
 use 5.004;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
    | 
| 
31
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
4
 | 
 use strict;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
47
 | 
    | 
| 
32
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #use List::Util 'max';  | 
| 
33
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 *max = \&Math::PlanePath::_max;  | 
| 
34
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
35
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
4
 | 
 use vars '$VERSION', '@ISA';  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
63
 | 
    | 
| 
36
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 $VERSION = 16;  | 
| 
37
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
638
 | 
 use Math::PlanePath;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
4687
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
120
 | 
    | 
| 
38
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 @ISA = ('Math::PlanePath');  | 
| 
39
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
40
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # return ($quotient, $remainder)  | 
| 
42
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _divrem {  | 
| 
43
 | 
14
 | 
 
 | 
 
 | 
  
14
  
 | 
 
 | 
13
 | 
   my ($n, $d) = @_;  | 
| 
44
 | 
14
 | 
  
 50
  
 | 
  
 33
  
 | 
 
 | 
 
 | 
27
 | 
   if (ref $n && $n->isa('Math::BigInt')) {  | 
| 
45
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my ($quot,$rem) = $n->copy->bdiv($d);  | 
| 
46
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
     if (! ref $d || $d < 1_000_000) {  | 
| 
47
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $rem = $rem->numify;  # plain remainder if fits  | 
| 
48
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
49
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return ($quot, $rem);  | 
| 
50
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
51
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
   my $rem = $n % $d;  | 
| 
52
 | 
14
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
   return (int(($n-$rem)/$d), # exact division stays in UV  | 
| 
53
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           $rem);  | 
| 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
56
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
57
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 use Math::PlanePath::Base::Generic  | 
| 
58
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
   'is_infinite',  | 
| 
59
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
5
 | 
   'round_nearest';  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
60
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 use Math::PlanePath::Base::Digits  | 
| 
61
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
462
 | 
   'round_down_pow';  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1149
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
51
 | 
    | 
| 
62
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
63
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # uncomment this to run the ### lines  | 
| 
64
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # use Smart::Comments;  | 
| 
65
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
66
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
740
 | 
 use Math::PlanePath::ToothpickTree;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
119
 | 
    | 
| 
67
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 *new = \&Math::PlanePath::ToothpickTree::new;  | 
| 
68
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 *x_negative = \&Math::PlanePath::ToothpickTree::x_negative;  | 
| 
69
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 *y_negative = \&Math::PlanePath::ToothpickTree::y_negative;  | 
| 
70
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 *rect_to_n_range = \&Math::PlanePath::ToothpickTree::rect_to_n_range;  | 
| 
71
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 *x_minimum = \&Math::PlanePath::ToothpickTree::x_minimum;  | 
| 
72
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 *y_minimum = \&Math::PlanePath::ToothpickTree::y_minimum;  | 
| 
73
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 *sumxy_minimum    = \&Math::PlanePath::ToothpickTree::sumxy_minimum;  | 
| 
74
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 *sumabsxy_minimum = \&Math::PlanePath::ToothpickTree::sumabsxy_minimum;  | 
| 
75
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 *rsquared_minimum = \&Math::PlanePath::ToothpickTree::rsquared_minimum;  | 
| 
76
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
77
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
94
 | 
 use constant parameter_info_array =>  | 
| 
78
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   [ { name      => 'parts',  | 
| 
79
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       share_key => 'parts_toothpickreplicate',  | 
| 
80
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       display   => 'Parts',  | 
| 
81
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       type      => 'enum',  | 
| 
82
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       default   => '4',  | 
| 
83
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       choices   => ['4','3','2','1'],  | 
| 
84
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       choices_display => ['4','3','2','1'],  | 
| 
85
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       description => 'Which parts of the pattern to generate.',  | 
| 
86
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     },  | 
| 
87
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
7
 | 
   ];  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
88
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
89
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
5
 | 
 use constant n_start => 0;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
40
 | 
    | 
| 
90
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
3
 | 
 use constant class_x_negative => 1;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
35
 | 
    | 
| 
91
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
3
 | 
 use constant class_y_negative => 1;  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
107
 | 
    | 
| 
92
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
93
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 {  | 
| 
94
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my @x_negative_at_n = (undef,  | 
| 
95
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                          undef,  # 1  | 
| 
96
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                          3,      # 2  | 
| 
97
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                          6,      # 3  | 
| 
98
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                          5,      # 4  | 
| 
99
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         );  | 
| 
100
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   sub x_negative_at_n {  | 
| 
101
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     my ($self) = @_;  | 
| 
102
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return $x_negative_at_n[$self->{'parts'}];  | 
| 
103
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
104
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
105
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 {  | 
| 
106
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my @y_negative_at_n = (undef,  | 
| 
107
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                          undef,  # 1  | 
| 
108
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                          undef,  # 2  | 
| 
109
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                          2,      # 3  | 
| 
110
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                          2,      # 4  | 
| 
111
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         );  | 
| 
112
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   sub y_negative_at_n {  | 
| 
113
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
     my ($self) = @_;  | 
| 
114
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return $y_negative_at_n[$self->{'parts'}];  | 
| 
115
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
116
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
117
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
118
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # parts=1 same as parts=4  | 
| 
119
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # parts=2 same as parts=4  | 
| 
120
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # parts=3 same as parts=4  | 
| 
121
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # parts=4    33,-12  | 
| 
122
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #           133,-30  | 
| 
123
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #           333,-112  | 
| 
124
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #          1333,-230  | 
| 
125
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #          3332,-1112    -> 3,-1  | 
| 
126
 | 
1
 | 
 
 | 
 
 | 
  
1
  
 | 
 
 | 
4
 | 
 use constant dir_maximum_dxdy => (3,-1);  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
    | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1151
 | 
    | 
| 
127
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
128
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #------------------------------------------------------------------------------  | 
| 
129
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Fraction covered  | 
| 
130
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Xlevel = 2^(level+1) - 1  | 
| 
131
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Ylevel = 2^(level+1)  | 
| 
132
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Nend = (2*4^(level+1) + 1)/3 - 1  | 
| 
133
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
134
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Nend / (Xlevel*Ylevel)  | 
| 
135
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  -> ((2*4^(level+1) + 1)/3 - 1) / 4^(level+1)  | 
| 
136
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  -> (2*4^(level+1) + 1)/3 / 4^(level+1)  | 
| 
137
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  -> 2*4^(level+1)/3 / 4^(level+1)  | 
| 
138
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  -> 2/3  | 
| 
139
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
140
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # Leading diagonal 1,3, 7,11,  | 
| 
141
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #                  23,25,29,43,  +22,22,22,32  | 
| 
142
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #                  87,89,93,97,  +86,86,86,86  | 
| 
143
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #                  109,111,115,171,  +86,128  | 
| 
144
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #                  343  | 
| 
145
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # part2start = (4^level + 5)/3    = 3,7,23,87,343  | 
| 
146
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # sums of part2start(level), but +2 in second half of each  | 
| 
147
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # (3)/3=1  | 
| 
148
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # (3+ 1+5)/3=3  | 
| 
149
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # (3+ 1+5 + 4+5)/3=9  | 
| 
150
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
151
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
152
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # v              v  | 
| 
153
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # |      ->      |     part 3  | 
| 
154
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # +---h      h---+  | 
| 
155
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
156
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # +---v      h  | 
| 
157
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # |      ->  |         part 1 rot then part 3  | 
| 
158
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # h          +---v  | 
| 
159
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
160
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #     v      v  | 
| 
161
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #     |  ->  |         part 3 then part 3 again  | 
| 
162
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # h---+      +---h  | 
| 
163
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
164
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
165
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # v          +---v  | 
| 
166
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # |      ->  |         part 1  | 
| 
167
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # +---h      h  | 
| 
168
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
169
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #     v      v---+  | 
| 
170
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #     |  ->      |     part 3 then part 1 rot is +90  | 
| 
171
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # h---+          h  | 
| 
172
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
173
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # N = (2*4^level + 1)/3 + 1   is first of "level"  | 
| 
174
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # 3N-3 = 2*4^level + 1  | 
| 
175
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # 2*4^level = 3N-4  | 
| 
176
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # 4^(level+1) = 6N-8  | 
| 
177
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #  | 
| 
178
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # part = (2*4^level - 2)/3  many points in "level"  | 
| 
179
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # above = (2*4^(level+1) - 2)/3  | 
| 
180
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #       = (4*2*4^level - 2)/3  | 
| 
181
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #       = 4*(2*4^level - 2/4)/3  | 
| 
182
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #       = 4*(2*4^level - 2)/3 + 4*(+ 2 - 2/4)/3  | 
| 
183
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #       = 4*(2*4^level - 2)/3 + 2  | 
| 
184
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #       = 4*part + 2  | 
| 
185
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # part = (above-2)/4  | 
| 
186
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
187
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my @quadrant_to_hdx = (1,-1, -1,1);  | 
| 
188
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my @quadrant_to_vdy = (1, 1, -1,-1);  | 
| 
189
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
190
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub n_to_xy {  | 
| 
191
 | 
54
 | 
 
 | 
 
 | 
  
54
  
 | 
  
1
  
 | 
2738
 | 
   my ($self, $n) = @_;  | 
| 
192
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ### ToothpickReplicate n_to_xy(): $n  | 
| 
193
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
194
 | 
54
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
103
 | 
   if ($n < 0) { return; }  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
195
 | 
54
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
85
 | 
   if (is_infinite($n)) { return ($n,$n); }  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
196
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
197
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   {  | 
| 
198
 | 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
242
 | 
     my $int = int($n);  | 
| 
 
 | 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
42
 | 
    | 
| 
199
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### $int  | 
| 
200
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### $n  | 
| 
201
 | 
54
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
74
 | 
     if ($n != $int) {  | 
| 
202
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       my ($x1,$y1) = $self->n_to_xy($int);  | 
| 
203
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       my ($x2,$y2) = $self->n_to_xy($int+1);  | 
| 
204
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       my $frac = $n - $int;  # inherit possible BigFloat  | 
| 
205
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       my $dx = $x2-$x1;  | 
| 
206
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       my $dy = $y2-$y1;  | 
| 
207
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       return ($frac*$dx + $x1, $frac*$dy + $y1);  | 
| 
208
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
209
 | 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
     $n = $int;       # BigFloat int() gives BigInt, use that  | 
| 
210
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
211
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
212
 | 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
52
 | 
   my $parts = $self->{'parts'};  | 
| 
213
 | 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
41
 | 
   my $x = 0;  | 
| 
214
 | 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
49
 | 
   my $y = 0;  | 
| 
215
 | 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
31
 | 
   my $hdx = 1;  | 
| 
216
 | 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
37
 | 
   my $hdy = 0;  | 
| 
217
 | 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
33
 | 
   my $vdx = 0;  | 
| 
218
 | 
54
 | 
 
 | 
 
 | 
 
 | 
 
 | 
38
 | 
   my $vdy = 1;  | 
| 
219
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
220
 | 
54
 | 
  
 50
  
 | 
 
 | 
 
 | 
 
 | 
128
 | 
   if ($parts eq '2') {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
221
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ($n == 0) {  | 
| 
222
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       return (0,1);  | 
| 
223
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
224
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
225
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # first of a replication level  | 
| 
226
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Nlevel = 2*(2*4^level - 2)/3 + 1  | 
| 
227
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #        = (4*4^level - 4)/3 + 1  | 
| 
228
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #        = (4*4^level - 4 + 3)/3  | 
| 
229
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #        = (4*4^level - 1)/3     = 5,21  | 
| 
230
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # 3N = 4*4^level - 1  | 
| 
231
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # 4^(level+1) = 3N+1  | 
| 
232
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
233
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my ($len,$level) = round_down_pow(3*$n+1, 4);  | 
| 
234
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     my $three_parts = $len/2;  | 
| 
235
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
236
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### $len  | 
| 
237
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### $level  | 
| 
238
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### $three_parts  | 
| 
239
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### start this level: ($len-1)/3  | 
| 
240
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### n reduced: $n-($len-1)/3  | 
| 
241
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
242
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     (my $quadrant, $n) = _divrem ($n-($len-1)/3, $three_parts);  | 
| 
243
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### $quadrant  | 
| 
244
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### n remainder: $n  | 
| 
245
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### assert: $quadrant >= 0  | 
| 
246
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### assert: $quadrant <= 1  | 
| 
247
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
248
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $n += ($len/2-2)/3;  | 
| 
249
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ($quadrant) { $hdx = -1; }  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
250
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### n in quarter: $n  | 
| 
251
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
252
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif ($parts == 3) {  | 
| 
253
 | 
8
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     if ($n <= 1) {  | 
| 
254
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
5
 | 
       return (0,$n);  | 
| 
255
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
256
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Nend = 3*(2*4^level - 2)/3 + 2  | 
| 
257
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #      = (2*4^level - 2) + 2  | 
| 
258
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #      = 2*4^level     = 2,8,32  | 
| 
259
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # N-1 = 2*4^level  | 
| 
260
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # 4^(level+1) = 2N-2  | 
| 
261
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
262
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
34
 | 
     my ($len,$level) = round_down_pow(2*$n, 4);  | 
| 
263
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
50
 | 
     my $three_parts = $len/2;  | 
| 
264
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
265
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### $len  | 
| 
266
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### $level  | 
| 
267
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### $three_parts  | 
| 
268
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### start this level: ($len/2+1)  | 
| 
269
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### n reduced: $n-($len/2+1)  | 
| 
270
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
271
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     (my $quadrant, $n) = _divrem ($n-$len/2, $three_parts);  | 
| 
272
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### $quadrant  | 
| 
273
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### n remainder: $n  | 
| 
274
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### assert: $quadrant >= 0  | 
| 
275
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### assert: $quadrant <= 2  | 
| 
276
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
277
 | 
6
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     $n += ($len/2-2)/3;  | 
| 
278
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### n in quarter: $n  | 
| 
279
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
280
 | 
6
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
11
 | 
     if ($quadrant == 0) {  | 
| 
 
 | 
 
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
281
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
       $hdx = 0;  # rotate -90  | 
| 
282
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
       $hdy = -1;  | 
| 
283
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
1
 | 
       $vdx = 1;  | 
| 
284
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
       $vdy = 0;  | 
| 
285
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
       $x = -1; # offset  | 
| 
286
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($quadrant == 2) {  | 
| 
287
 | 
2
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
       $hdx = -1;  # mirror  | 
| 
288
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
289
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
290
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif ($parts == 4) {  | 
| 
291
 | 
11
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
16
 | 
     if ($n <= 2) {  | 
| 
292
 | 
3
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
5
 | 
       if ($n == 0) { return (0,0); }  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
293
 | 
2
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
3
 | 
       if ($n == 1) { return (0,1); }  | 
| 
 
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
3
 | 
    | 
| 
294
 | 
1
 | 
 
 | 
 
 | 
 
 | 
 
 | 
2
 | 
       return (0,-1);  # N==2  | 
| 
295
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
296
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # first of a replication level  | 
| 
297
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Nlevel = 4*(2*4^level - 2)/3 + 3  | 
| 
298
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #        = (8*4^level - 8)/3 + 3  | 
| 
299
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #        = (8*4^level - 8 + 9)/3  | 
| 
300
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #        = (8*4^level+1)/3           11,43,171  | 
| 
301
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # 3N = 8*4^level+1  | 
| 
302
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # 8*4^level = 3N-1  | 
| 
303
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # 4^(level+2) = 6N-2  | 
| 
304
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  | 
| 
305
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # first of this level, using level+2  | 
| 
306
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Nlevel = (4^(level+2)/2+1)/3  | 
| 
307
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #        = (4^(level+2)+2)/6  | 
| 
308
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #  | 
| 
309
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # three count = 3*(2*4^level - 2)/3 + 2  | 
| 
310
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     #             = 2*4^level  | 
| 
311
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # 43-11 = 32  | 
| 
312
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # 172-44 = 128  | 
| 
313
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
314
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # getting level+2 and len = 4^(level+2)  | 
| 
315
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
     my ($len,$level) = round_down_pow(6*$n-2, 4);  | 
| 
316
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
72
 | 
     my $three_parts = $len/8;  | 
| 
317
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
318
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### all breakdown ...  | 
| 
319
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### $level  | 
| 
320
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### $len  | 
| 
321
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### $three_parts  | 
| 
322
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### Nlevel base: ($len+2)/6  | 
| 
323
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
324
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
14
 | 
     (my $quadrant, $n) = _divrem ($n-($len+2)/6, $three_parts);  | 
| 
325
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### $quadrant  | 
| 
326
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### n remainder: $n  | 
| 
327
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### assert: $quadrant >= 0  | 
| 
328
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### assert: $quadrant <= 3  | 
| 
329
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
330
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # quarter middle  | 
| 
331
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     # Nquarter = (2*4^level - 2)/3  = 2,10,42  | 
| 
332
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
10
 | 
     $n += ($len/8-2)/3;  | 
| 
333
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
7
 | 
     $hdx = $quadrant_to_hdx[$quadrant];  | 
| 
334
 | 
8
 | 
 
 | 
 
 | 
 
 | 
 
 | 
8
 | 
     $vdy = $quadrant_to_vdy[$quadrant];  | 
| 
335
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### n in quarter: $n  | 
| 
336
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
337
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
338
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # quarter first of a replication level  | 
| 
339
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # Nlevel = 4*(2*4^level - 2)/3 + 2  | 
| 
340
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #        = (8*4^level - 8)/3 + 2  | 
| 
341
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #        = (8*4^level - 8 + 6)/3  | 
| 
342
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #        = (8*4^level - 2)/3           2,10,42  | 
| 
343
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # 3N = 8*4^level-2  | 
| 
344
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # 8*4^level = 3N+2  | 
| 
345
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # 4^(level+2) = 6N+4  | 
| 
346
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #  | 
| 
347
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # using level+1  | 
| 
348
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # Nlevel = (8*4^level - 2)/3  | 
| 
349
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #        = (2*4^(level+1) - 2)/3  | 
| 
350
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
351
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
352
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   # getting level+2 and 16*len  | 
| 
353
 | 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
192
 | 
   my ($len,$level) = round_down_pow(6*$n+4, 4);  | 
| 
354
 | 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
364
 | 
   my $part_n = (2*$len-2)/3;  | 
| 
355
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ### $level  | 
| 
356
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ### $part_n  | 
| 
357
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
358
 | 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
46
 | 
   $len = 2**$level;  | 
| 
359
 | 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
76
 | 
   for ( ;  | 
| 
360
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $level-- >= 0;  | 
| 
361
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         $len /= 2,  $part_n = ($part_n-2)/4) {  | 
| 
362
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
363
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### at: "x=$x,y=$y level=$level hxy=$hdx,$hdy vxy=$vdx,$vdy   n=$n"  | 
| 
364
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### $len  | 
| 
365
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### $part_n  | 
| 
366
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### assert: $len == 2 ** ($level+1)  | 
| 
367
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### assert: $part_n == (2 * 4 ** ($level+1) - 2)/3  | 
| 
368
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
369
 | 
145
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
186
 | 
     if ($n < $part_n) {  | 
| 
370
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       ### part 0, no change ...  | 
| 
371
 | 
55
 | 
 
 | 
 
 | 
 
 | 
 
 | 
99
 | 
       next;  | 
| 
372
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
373
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
374
 | 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
74
 | 
     $n -= $part_n;  | 
| 
375
 | 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
74
 | 
     $x += $len * ($hdx + $vdx);  # diagonal  | 
| 
376
 | 
90
 | 
 
 | 
 
 | 
 
 | 
 
 | 
67
 | 
     $y += $len * ($hdy + $vdy);  | 
| 
377
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
378
 | 
90
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
112
 | 
     if ($n == 0) {  | 
| 
379
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       ### toothpick A ...  | 
| 
380
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
22
 | 
       last;  | 
| 
381
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
382
 | 
65
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
81
 | 
     if ($n == 1) {  | 
| 
383
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       ### toothpick B ...  | 
| 
384
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
       $x += $vdx;  | 
| 
385
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
17
 | 
       $y += $vdy;  | 
| 
386
 | 
24
 | 
 
 | 
 
 | 
 
 | 
 
 | 
21
 | 
       last;  | 
| 
387
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
388
 | 
41
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
     $n -= 2;  | 
| 
389
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
390
 | 
41
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
52
 | 
     if ($n < $part_n) {  | 
| 
391
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       ### part 1, rotate ...  | 
| 
392
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
11
 | 
       $x -= $hdx; # offset  | 
| 
393
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
       $y -= $hdy;  | 
| 
394
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
19
 | 
       ($hdx,$hdy, $vdx,$vdy)    # rotate 90 in direction v toward h  | 
| 
395
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         = (-$vdx,-$vdy, $hdx,$hdy);  | 
| 
396
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
30
 | 
       next;  | 
| 
397
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
398
 | 
25
 | 
 
 | 
 
 | 
 
 | 
 
 | 
18
 | 
     $n -= $part_n;  | 
| 
399
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
400
 | 
25
 | 
  
100
  
 | 
 
 | 
 
 | 
 
 | 
32
 | 
     if ($n < $part_n) {  | 
| 
401
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       ### part 2 ...  | 
| 
402
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
16
 | 
       next;  | 
| 
403
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
404
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
15
 | 
     $n -= $part_n;  | 
| 
405
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
406
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### part 3, mirror ...  | 
| 
407
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
13
 | 
     $hdx = -$hdx;  | 
| 
408
 | 
16
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
     $hdy = -$hdy;  | 
| 
409
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
410
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
411
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ### assert: $n == 0 || $n == 1  | 
| 
412
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
413
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ### final: "x=$x y=$y"  | 
| 
414
 | 
49
 | 
 
 | 
 
 | 
 
 | 
 
 | 
82
 | 
   return ($x,$y);  | 
| 
415
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
416
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
417
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub xy_to_n {  | 
| 
418
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
0
 | 
   my ($self, $x, $y) = @_;  | 
| 
419
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ### ToothpickReplicate xy_to_n(): "$x, $y"  | 
| 
420
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
421
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $x = round_nearest ($x);  | 
| 
422
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   $y = round_nearest ($y);  | 
| 
423
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
424
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $parts = $self->{'parts'};  | 
| 
425
 | 
0
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
0
 | 
   my $rotated = ($parts == 3 && $x >= 0 && $y < 0);  | 
| 
426
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   if ($rotated) {  | 
| 
427
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     ($x,$y) = (-$y,$x+1);  # rotate +90 and shift up  | 
| 
428
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### rotated: "x=$x y=$y"  | 
| 
429
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
430
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
431
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my ($len,$level) = round_down_pow (max(abs($x), abs($y)-1),  | 
| 
432
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                                      2);  | 
| 
433
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   if (is_infinite($level)) {  | 
| 
434
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     return $level;  | 
| 
435
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
436
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ### $level  | 
| 
437
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ### $len  | 
| 
438
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
439
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $zero = $x * 0 * $y;  | 
| 
440
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $n = $zero;  | 
| 
441
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
442
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   if ($parts == 2) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
443
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ($x == 0) {  | 
| 
444
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       if ($y == 1) { return 0; }  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
445
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
446
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $n += (2*$len*$len+1)/3;   # +1,+3,+11,+43  | 
| 
447
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ($x < 0) {  | 
| 
448
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $x = -$x;  | 
| 
449
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $n += 2*$len*$len;  # second quad, +2,+8,+32  | 
| 
450
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
451
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
452
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif ($parts == 3) {  | 
| 
453
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### 3/4 ...  | 
| 
454
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ($x == 0) {  | 
| 
455
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       if ($y == 0) { return 0; }  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
456
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       if ($y == 1) { return 1; }  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
457
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
458
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $n += (10*$len*$len+2)/3;   # +4,+14,+54,+214,+854,+3414  | 
| 
459
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ($rotated) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
460
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $n -= 2*$len*$len;  # fourth quad, -2, -8, -32  | 
| 
461
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($x < 0) {  | 
| 
462
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $x = -$x;  | 
| 
463
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       if ($y > 0) {  | 
| 
464
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $n += 2*$len*$len;  # second quad, +2, +8, +32  | 
| 
465
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       } else {  | 
| 
466
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         return undef;  # third quad, empty  | 
| 
467
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
468
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
469
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } elsif ($parts == 4) {  | 
| 
470
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ($x == 0) {  | 
| 
471
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       if ($y == 0)  { return 0; }  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
472
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       if ($y == 1)  { return 1; }  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
473
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       if ($y == -1) { return 2; }  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
    | 
| 
474
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
475
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $n += (2*$len*$len+1);  | 
| 
476
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ($x < 0) {  | 
| 
477
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $x = -$x;  | 
| 
478
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       if ($y > 0) {  | 
| 
479
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $n += 2*$len*$len;  # second quad, +2, +8, +32  | 
| 
480
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       } else {  | 
| 
481
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $n += 4*$len*$len;  # third quad, +4,+16  | 
| 
482
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $y = -$y;  | 
| 
483
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
484
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
485
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       if ($y < 0) {  | 
| 
486
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $n += 6*$len*$len;  # fourth quad  | 
| 
487
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $y = -$y;  | 
| 
488
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
489
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
490
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
491
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
492
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #                              2^(level+1)-1  | 
| 
493
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #                              v  | 
| 
494
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #          +-----------+---------+  | 
| 
495
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #          |           |         | <- 2^(level+1)  | 
| 
496
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #          |   3             2   |  | 
| 
497
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #          | mirror        same  |  | 
| 
498
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #          |         --B--       | <- 2^level + 1  | 
| 
499
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #          |           |         |  | 
| 
500
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #          +--         A       --+ <- 2^level  | 
| 
501
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #                      |         |  | 
| 
502
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #                          1     |  | 
| 
503
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #                         rot    |  | 
| 
504
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #             0           +90    |  | 
| 
505
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #                    |           |  | 
| 
506
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #                    +-----------+  | 
| 
507
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #                      ^  | 
| 
508
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   #                     2^level  | 
| 
509
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
510
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   my $part_n = (2*$len*$len - 2) / 3;  | 
| 
511
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ### $part_n  | 
| 
512
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
513
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   while ($level-- > 0) {  | 
| 
514
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### at: "x=$x,y=$y  len=$len part_n=$part_n   n=$n"  | 
| 
515
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### assert: $len == 2 ** ($level+1)  | 
| 
516
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ### assert: $part_n == (2 * 4 ** ($level+1) - 2)/3  | 
| 
517
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
518
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ($x == $len) {  | 
| 
519
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       if ($y == $len) {  | 
| 
520
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ### toothpick A ...  | 
| 
521
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         return $n + $part_n;  | 
| 
522
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
523
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       if ($y == $len+1) {  | 
| 
524
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ### toothpick B ...  | 
| 
525
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         return $n + $part_n + 1;  | 
| 
526
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
527
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
528
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
529
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ($y <= $len) {  | 
| 
530
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       if ($x < $len) {  | 
| 
531
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ### part 0 ...  | 
| 
532
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       } else {  | 
| 
533
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ### part 1, rotate ...  | 
| 
534
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $n += $part_n + 2;  | 
| 
535
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         ($x,$y) = ($len-$y,$x-$len+1); # shift, rotate +90  | 
| 
536
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
537
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } else {  | 
| 
538
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       $y -= $len;  | 
| 
539
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       if ($x > $len) {  | 
| 
540
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ### part 2 ...  | 
| 
541
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $n += 2*$part_n + 2;  | 
| 
542
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $x -= $len;  | 
| 
543
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       } else {  | 
| 
544
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
         ### part 3 ...  | 
| 
545
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $n += 3*$part_n + 2;  | 
| 
546
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
         $x = $len-$x; # mirror  | 
| 
547
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       }  | 
| 
548
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
549
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
550
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $len /= 2;  | 
| 
551
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     $part_n = ($part_n-2)/4;  | 
| 
552
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
553
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
554
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   ### end loop: "x=$x y=$y   n=$n"  | 
| 
555
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
556
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   if ($x == 1) {  | 
| 
557
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
0
 | 
     if ($y == 1) {  | 
| 
 
 | 
 
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
558
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       return $n;  | 
| 
559
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     } elsif ($y == 2) {  | 
| 
560
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
       return $n + 1;  | 
| 
561
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
562
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
563
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
564
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
0
 | 
   return undef;  | 
| 
565
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
566
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
567
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #------------------------------------------------------------------------------  | 
| 
568
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # levels  | 
| 
569
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
570
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # parts=1  | 
| 
571
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # LevelPoints[k] = 4*LevelPoints[k] + 2  starting LevelPoints[0] = 2  | 
| 
572
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # LevelPoints[k] = 2 + 2*4 + 2*4^2 + ... + 2*4^(k-1) + 4^k*LevelPoints[0]  | 
| 
573
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # LevelPoints[k] = 2 + 2*4 + 2*4^2 + ... + 2*4^(k-1) + 2*4^k  | 
| 
574
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # LevelPoints[k] = 2*(4^(k+1) - 1)/3  | 
| 
575
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
576
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 my %level_to_n_range = (4 => -2,  | 
| 
577
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         3 => -3,  | 
| 
578
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         2 => -4,  | 
| 
579
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                         1 => -5,  | 
| 
580
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
                        );  | 
| 
581
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub level_to_n_range {  | 
| 
582
 | 
9
 | 
 
 | 
 
 | 
  
9
  
 | 
  
1
  
 | 
266
 | 
   my ($self, $level) = @_;  | 
| 
583
 | 
9
 | 
 
 | 
 
 | 
 
 | 
 
 | 
27
 | 
   return (0,  | 
| 
584
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
           (4**($level+1) * (2*$self->{'parts'})  | 
| 
585
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
            + $level_to_n_range{$self->{'parts'}}) / 3);  | 
| 
586
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
587
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub n_to_level {  | 
| 
588
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
  
1
  
 | 
 
 | 
   my ($self, $n) = @_;  | 
| 
589
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   if ($n < 0) { return undef; }  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
590
 | 
0
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   if (is_infinite($n)) { return $n; }  | 
| 
 
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
591
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   $n = round_nearest($n) + 1;  | 
| 
592
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   _divrem_mutate ($n, 2*$self->{'parts'});  | 
| 
593
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my ($pow, $exp) = round_down_pow (4*$n - $level_to_n_range{$self->{'parts'}}, 2);  | 
| 
594
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return $exp + 1;  | 
| 
595
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
596
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
597
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # return $remainder, modify $n  | 
| 
598
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # the scalar $_[0] is modified, but if it's a BigInt then a new BigInt is made  | 
| 
599
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 # and stored there, the bigint value is not changed  | 
| 
600
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 sub _divrem_mutate {  | 
| 
601
 | 
0
 | 
 
 | 
 
 | 
  
0
  
 | 
 
 | 
 
 | 
   my $d = $_[1];  | 
| 
602
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   my $rem;  | 
| 
603
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
   if (ref $_[0] && $_[0]->isa('Math::BigInt')) {  | 
| 
604
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     ($_[0], $rem) = $_[0]->copy->bdiv($d);  # quot,rem in array context  | 
| 
605
 | 
0
 | 
  
  0
  
 | 
  
  0
  
 | 
 
 | 
 
 | 
 
 | 
     if (! ref $d || $d < 1_000_000) {  | 
| 
606
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
       return $rem->numify;  # plain remainder if fits  | 
| 
607
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     }  | 
| 
608
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   } else {  | 
| 
609
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $rem = $_[0] % $d;  | 
| 
610
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
     $_[0] = int(($_[0]-$rem)/$d); # exact division stays in UV  | 
| 
611
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   }  | 
| 
612
 | 
0
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
   return $rem;  | 
| 
613
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 }  | 
| 
614
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
    | 
| 
615
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 #------------------------------------------------------------------------------  | 
| 
616
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 1;  | 
| 
617
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 
 | 
 __END__  |