File Coverage

blib/lib/Math/NumSeq/HappySteps.pm
Criterion Covered Total %
statement 58 59 98.3
branch 5 6 83.3
condition 1 3 33.3
subroutine 15 15 100.0
pod 3 3 100.0
total 82 86 95.3


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   4481 use 5.004;
  1         5  
  1         45  
20 1     1   7 use strict;
  1         3  
  1         46  
21              
22 1     1   6 use vars '$VERSION', '@ISA';
  1         3  
  1         183  
23             $VERSION = 71;
24              
25 1     1   7 use Math::NumSeq;
  1         2  
  1         26  
26 1     1   6 use Math::NumSeq::Base::IterateIth;
  1         1  
  1         70  
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   5 use constant description => Math::NumSeq::__('How many sum of squares of digits steps to get to a repeating iteration.');
  1         2  
  1         25  
37 1     1   6 use constant i_start => 1;
  1         2  
  1         42  
38 1     1   6 use constant values_min => 1;
  1         1  
  1         46  
39 1     1   5 use constant characteristic_count => 1;
  1         2  
  1         40  
40 1     1   5 use constant characteristic_smaller => 1;
  1         2  
  1         44  
41 1     1   5 use constant characteristic_increasing => 0;
  1         2  
  1         48  
42              
43             use Math::NumSeq::Base::Digits
44 1     1   5 'parameter_info_array'; # radix parameter
  1         2  
  1         485  
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 11 my ($self) = @_;
59 2         8 return $oeis_anum[$self->{'radix'}];
60             }
61              
62             #------------------------------------------------------------------------------
63              
64             sub ith {
65 187     187 1 376 my ($self, $i) = @_;
66              
67 187 100       397 if ($i <= 0) {
68 6         14 return 0;
69             }
70 181 50       431 if (_is_infinite($i)) {
71 0         0 return $i;
72             }
73              
74 181         363 my $radix = $self->{'radix'};
75 181         224 my $steps = 0;
76 181         191 my %seen;
77 181         520 for (;;) {
78             ### $i
79 1375         1623 my $sum = 0;
80 1375 100       3165 if ($seen{$i}) {
81 181         906 return $steps;
82             }
83 1194         2138 $seen{$i} = 1;
84 1194         2431 while ($i) {
85 2276         3267 my $digit = ($i % $radix);
86 2276         2963 $sum += $digit * $digit;
87 2276         5104 $i = int($i/$radix);
88             }
89 1194         1237 $i = $sum;
90 1194         1504 $steps++;
91             }
92             }
93              
94             sub pred {
95 18     18 1 97 my ($self, $value) = @_;
96             ### HappySteps pred(): $value
97 18   33     85 return ($value >= 0 && $value == int($value));
98             }
99              
100             1;
101             __END__