File Coverage

blib/lib/Math/NumSeq/HappySteps.pm
Criterion Covered Total %
statement 57 58 98.2
branch 5 6 83.3
condition 1 3 33.3
subroutine 15 15 100.0
pod 3 3 100.0
total 81 85 95.2


line stmt bran cond sub pod time code
1             # Copyright 2011, 2012, 2013, 2014 Kevin Ryde
2              
3             # This file is part of Math-NumSeq.
4             #
5             # Math-NumSeq is free software; you can redistribute it and/or modify
6             # it under the terms of the GNU General Public License as published by the
7             # Free Software Foundation; either version 3, or (at your option) any later
8             # version.
9             #
10             # Math-NumSeq is distributed in the hope that it will be useful, but
11             # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
12             # or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
13             # for more details.
14             #
15             # You should have received a copy of the GNU General Public License along
16             # with Math-NumSeq. If not, see .
17              
18             package Math::NumSeq::HappySteps;
19 1     1   1315 use 5.004;
  1         3  
20 1     1   4 use strict;
  1         1  
  1         21  
21              
22 1     1   3 use vars '$VERSION', '@ISA';
  1         1  
  1         58  
23             $VERSION = 72;
24              
25 1     1   4 use Math::NumSeq;
  1         2  
  1         18  
26 1     1   4 use Math::NumSeq::Base::IterateIth;
  1         1  
  1         57  
27             @ISA = ('Math::NumSeq::Base::IterateIth',
28             'Math::NumSeq');
29             *_is_infinite = \&Math::NumSeq::_is_infinite;
30              
31             # uncomment this to run the ### lines
32             #use Devel::Comments;
33              
34              
35             # use constant name => Math::NumSeq::__('Happy Steps');
36 1     1   6 use constant description => Math::NumSeq::__('How many sum of squares of digits steps to get to a repeating iteration.');
  1         2  
  1         5  
37 1     1   6 use constant i_start => 1;
  1         2  
  1         62  
38 1     1   5 use constant values_min => 1;
  1         1  
  1         36  
39 1     1   3 use constant characteristic_count => 1;
  1         2  
  1         57  
40 1     1   3 use constant characteristic_smaller => 1;
  1         1  
  1         40  
41 1     1   3 use constant characteristic_increasing => 0;
  1         2  
  1         36  
42              
43             use Math::NumSeq::Base::Digits
44 1     1   4 'parameter_info_array'; # radix parameter
  1         1  
  1         227  
45              
46             #------------------------------------------------------------------------------
47             # cf A001273 smallest happy which takes N steps
48             #
49             my @oeis_anum;
50              
51             $oeis_anum[2] = 'A078627'; # starting i=1 ...
52             # OEIS-Catalogue: A078627 radix=2
53              
54             $oeis_anum[10] = 'A193995'; # but starting i=1 ...
55             # OEIS-Catalogue: A193995
56              
57             sub oeis_anum {
58 2     2 1 6 my ($self) = @_;
59 2         3 return $oeis_anum[$self->{'radix'}];
60             }
61              
62             #------------------------------------------------------------------------------
63              
64             sub ith {
65 187     187 1 180 my ($self, $i) = @_;
66              
67 187 100       225 if ($i <= 0) {
68 6         8 return 0;
69             }
70 181 50       242 if (_is_infinite($i)) {
71 0         0 return $i;
72             }
73              
74 181         173 my $radix = $self->{'radix'};
75 181         112 my $steps = 0;
76 181         106 my %seen;
77 181         106 for (;;) {
78             ### $i
79 1375         769 my $sum = 0;
80 1375 100       1594 if ($seen{$i}) {
81 181         467 return $steps;
82             }
83 1194         889 $seen{$i} = 1;
84 1194         1225 while ($i) {
85 2276         1364 my $digit = ($i % $radix);
86 2276         1325 $sum += $digit * $digit;
87 2276         2692 $i = int($i/$radix);
88             }
89 1194         667 $i = $sum;
90 1194         672 $steps++;
91             }
92             }
93              
94             sub pred {
95 18     18 1 49 my ($self, $value) = @_;
96             ### HappySteps pred(): $value
97 18   33     55 return ($value >= 0 && $value == int($value));
98             }
99              
100             1;
101             __END__