File Coverage

blib/lib/Math/Palindrome.pm
Criterion Covered Total %
statement 85 104 81.7
branch 15 30 50.0
condition 4 8 50.0
subroutine 18 20 90.0
pod 7 7 100.0
total 129 169 76.3


line stmt bran cond sub pod time code
1             package Math::Palindrome;
2              
3             #Yes, i'd like a dush good pratices
4 1     1   17694 use strict;
  1         3  
  1         31  
5 1     1   6 use warnings;
  1         2  
  1         32  
6             #And I so like fucking everything
7 1     1   5 use Carp 'croak';
  1         5  
  1         71  
8             #Let's help you work more easy, if you can't you may not be here, get out
9              
10             BEGIN {
11 1     1   5 use Exporter;
  1         2  
  1         37  
12 1     1   5 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  1         2  
  1         152  
13 1     1   6 $VERSION = '0.021';
14 1         13 @ISA = qw(Exporter);
15             #Give a hoot don't pollute, do not export more than needed by default
16 1         2 @EXPORT = qw();
17 1         3 @EXPORT_OK = qw(is_palindrome
18             next_palindrome
19             previous_palindrome
20             increasing_sequence
21             decreasing_sequence
22             palindrome_after
23             palindrome_before);
24 1         1094 %EXPORT_TAGS = (all => [ @EXPORT_OK ]);
25             }
26              
27             ###########################################################################################
28             # This cannot be export
29              
30             # How many digits exist here
31 60     60   78 sub _digits_size {return length shift}
32              
33             #Working with just one digits
34             #If want a previous value
35             sub _previous_one_digits {
36 0     0   0 my $n = shift;
37 0 0       0 $n != 0 ? (return ($n - 1)) : croak "Just work with natural numbers!\n";
38             }
39             #If want a next value
40             sub _next_one_digits {
41 5     5   8 my $n = shift;
42 5 50       21 $n != 9 ? (return ($n + 1)) : (return 11);
43             }
44             #Finish, maybe one day I'll optimise
45              
46             #Now other stance, working with odd digits
47             #for next
48             sub _next_odd_digits {
49 25     25   22 my $n = shift;
50 25         20 my $r;
51            
52 25         33 my $n_1 = substr $n, 0, (length $n)/2; #first half part, without middle num(if exist)
53 25         30 my $n_2 = substr $n, -((length $n)/2); #second half part, without middle num(if exist)
54 25         27 my $n_3 = substr $n, 0, -((length $n)/2); #first half part, with middle num(if exist)
55            
56 25 50       51 if ($n == 999){$r = 1001}
  0 50       0  
57 0         0 elsif ($n_1 <= reverse $n_2){
58 25         21 $n_3++;
59 25         33 $r = $n_3 . (reverse substr $n_3, 0, ((length $n_3)-1));
60            
61             }
62             else{$r = $n_3 . (reverse substr $n_3, 0, ((length$n_3)-1))}
63            
64 25         63 return $r;
65             }
66             #for previous
67             sub _previous_odd_digits {
68 26     26   29 my $n = shift;
69 26         25 my $r ;
70            
71 26         40 my $n_1 = substr $n, 0, (length $n)/2; #first half part, without middle num(if exist)
72 26         42 my $n_2 = substr $n, -((length $n)/2); #second half part, without middle num(if exist)
73 26         38 my $n_3 = substr $n, 0, -((length $n)/2); #first half part, with middle num(if exist)
74            
75 26 100       61 if ($n <= 101){$r = 99}
  1 50       3  
76 0         0 elsif ($n_1 >= reverse $n_2){
77 25         25 $n_3--;
78 25         42 $r = $n_3 . (reverse substr $n_3, 0, ((length $n_3)-1));
79            
80             }
81             else{$r = $n_3 . (reverse substr $n_3, 0, ((length$n_3)-1))}
82            
83 26         120 return $r;
84             }
85              
86             #Finally, working with even number
87             #for next
88             sub _next_even_digits {
89 0     0   0 my $n = shift;
90 0         0 my $r;
91            
92 0         0 my $n_1 = substr $n, 0, -((length $n)/2);#first half part
93 0         0 my $n_2 = substr $n, ((length $n)/2); #second half part
94            
95 0 0       0 if ($n == 99){$r = 101}
  0 0       0  
96 0         0 elsif ($n_1 <= reverse$n_2){
97 0         0 $n_1++;
98 0         0 $r = $n_1 . reverse $n_1;
99             }
100             else{$r = $n_1 . reverse $n_1}
101            
102 0         0 return $r;
103             }
104             #for previous
105             sub _previous_even_digits {
106 4     4   5 my $n = shift;
107 4         3 my $r;
108            
109 4         8 my $n_1 = substr $n, 0, -((length $n)/2);#first half part
110 4         7 my $n_2 = substr $n, ((length $n)/2); #second half part
111            
112 4 50       16 if ($n <= 11){$r = 9}
  0 50       0  
113 0         0 elsif ($n_1 >= reverse $n_2){
114 4         5 $n_1--;
115 4         8 $r = $n_1 . reverse $n_1;
116             }
117             else{$r = $n_1 . reverse $n_1}
118            
119 4         18 return $r;
120             }
121             #End, without these part, nothing may work
122             ##############################################################
123              
124             ##############################################################
125             #Now, all export functions
126             #confirm if the number is palindrome
127 50 50   50 1 21130 sub is_palindrome {($_[0] == reverse $_[0]) ? return 1 : return 0}
128             #require the next palindrome
129             sub next_palindrome {
130 30     30 1 32 my $num = shift;
131 30         42 my $size = _digits_size($num);
132 30 100       57 if ($size == 1){return _next_one_digits($num)}
  5 50       10  
  25         34  
133 0         0 elsif ($size % 2 != 0){return _next_odd_digits($num)}
134             else{return _next_even_digits($num)}
135             }
136             #require the previous palindrome
137             sub previous_palindrome {
138 30     30 1 34 my $num = shift;
139 30         83 my $size = _digits_size($num);
140 30 50       74 if ($size == 1){return _previous_one_digits($num)}
  0 100       0  
  26         44  
141 4         8 elsif ($size % 2 != 0){return _previous_odd_digits($num)}
142             else{return _previous_even_digits($num)}
143             }
144             #require a crescent sequence
145             sub increasing_sequence {
146 1     1 1 11 my $len = $_[0];
147 1   50     4 my $ini = $_[1] || 0;
148 1         3 my @r;
149 1         4 for (1..$len){
150 25         36 $r[$_ - 1] = $ini = next_palindrome($ini)
151             }
152 1         23 return @r;
153             }
154             #require a decrescent sequence
155             sub decreasing_sequence {
156 1     1 1 336 my $len = $_[0];
157 1   50     5 my $ini = $_[1] || 100;
158 1         2 my @r;
159 1         5 for (1..$len){
160 25         39 $r[$_ -1] = $ini = previous_palindrome($ini)
161             }
162 1         23 return @r;
163             }
164             #making more easy for the all asshole
165             #require just last number of the decreasing sequence
166             sub palindrome_before {
167 1     1 1 4 my $len = $_[0];
168 1   50     7 my $ini = $_[1] || 100;
169 1         8 my $r;
170 1         4 for (1..$len){
171 5         9 $r = $ini = previous_palindrome($ini)
172             }
173 1         6 return $r;
174             }
175             #require just last number of the increasing sequence
176             sub palindrome_after {
177 1     1 1 404 my $len = $_[0];
178 1   50     11 my $ini = $_[1] || 0;
179 1         4 my $r;
180 1         4 for (1..$len){
181 5         12 $r = $ini = next_palindrome($ini)
182             }
183 1         5 return $r;
184             }
185             #Everything is dust in the wind
186             #####################################################################
187              
188              
189             # Now the boring part, the documentation.
190              
191              
192             =head1 NAME
193              
194             Math::Palindrome - Tool to manipulate palindromes numbers.
195              
196             =head1 SYNOPSIS
197              
198             use Math::Palindrome qw/is_palindrome
199             next_palindrome
200             previous_palindrome
201             increasing_sequence
202             decreasing_sequence
203             palindrome_after
204             palindrome_before/;
205            
206             my $n = 42; #We sujest never use '05', just '5'
207            
208             is_palindrome($n) ? print "TRUE" :print "FALSE"; # false!
209            
210             print next_palindrome($n); # 44
211            
212             print previous_palindrome($n); # 33
213            
214             #to increasing_sequence and decreasing_sequence insert
215             # the size of sequence
216             my @sequence_01 = increasing_sequence(5, $n); # 44 55 66 77 88
217             #or
218             my @sequence_01 = increasing_sequence(5); # 1 2 3 4 5
219             # default is 0
220             my @sequence_02 = decreasing_sequence(5, $n); # 33 22 11 9 8
221             #or
222             my @sequence_02 = decreasing_sequence(5); # 99 88 77 66 55
223             #default is 100
224            
225             my $last = palindrome_after(5, $n); # 88
226             # is the same $last = increasing_sequence(5, $n);
227             # this is valid too
228             my $last = palindrome_after(5); # 5
229            
230             my $first = palindrome_before(5, $n); # 8
231             # is the same $first = decreasing_sequence(5, $n);
232             # this is valid too
233             my $first = palindrome_before(5); # 55
234              
235              
236             =head1 DESCRIPTION
237              
238             This module is a alternative agains Math::NumSeq::Palindromes.
239             Can use this to find and confirm palindrome numbers.
240             In my tests it's work correctly with small and large numbers.
241             The most largest numbers was 9,99999 * 10^19. But, I think that its involved a memory capacity.
242             In this module, I used a deterministc method, maybe you can think that is a heuristic, but not.
243             I'm ready for fix a report bugs.
244              
245             =head2 is_palindrome
246              
247             Usage : is_palindrome($n)
248             Purpose : verify if the number is palindrome or not
249             Returns : return 1 if true or 0 if false
250             Comment : is the same:
251             ($n == reverse $n) ? return 1 : return 0
252             =cut
253              
254             =head2 next_palindrome
255              
256             Usage : next_palindrome($n);
257             Purpose : return the next palindrome number after $n
258              
259             =cut
260              
261             =head2 previous_palindrome
262              
263             Usage : previous_palindrome($n);
264             Purpose : return the previous palindrome number before $n
265              
266             =cut
267              
268             =head2 increasing_sequence
269              
270             Usage : increasing_sequence($size, $first_value);
271             Purpose : return the crescent sequence of palindrome number after $n
272             Argument : $size is the number of palindromes that you want
273             : $first_value is the number where it start to work, default it is 0 and never return the $first_value
274             Throws : Don't return $first_value even it's palindrome
275             Comment : Use with array.
276              
277              
278             =cut
279              
280             =head2 decreasing_sequence
281              
282             Usage : decreasing_sequence($size, $first_value);
283             Purpose : return the decrescent sequence of palindrome number beforer $n
284             Argument : $size is the number of palindromes that you want
285             : $first_value is the number where it start to work, default it is 100 and never return the $first_value
286             Throws : Don't return $first_value even it's palindrome
287             Comment : Use with array;
288              
289              
290             =cut
291              
292             =head2 palindrome_after
293              
294             Usage : palindrome_after($size, $first_value);
295             Purpose : return the last number of crescent sequence of palindrome number beforer $n
296             Argument : $size is the number of palindromes that you want
297             : $first_value is the number where it start to work, default it is 100 and never return the $first_value
298             Throws : Don't return $first_value even it's palindrome
299             Comment : Is like:
300             $n = increasing_sequence($s, $p);
301              
302            
303             =cut
304              
305             =head2 palindrome_before
306              
307             Usage : palindrome_before($size, $first_value);
308             Purpose : return the last number of decrescent sequence of palindrome number beforer $n
309             Argument : $size is the number of palindromes that you want
310             : $first_value is the number where it start to work, default it is 0 and never return the $first_value
311             Throws : Don't return $first_value even it's palindrome
312             Comment : Is like:
313             $n = decreasing_sequence($s, $p);
314              
315             =cut
316              
317              
318             =head1 THANKS
319             Bruno Buss and all community of rio.pm.org
320              
321              
322             =head1 AUTHOR
323              
324             Aureliano C. P. Guedes
325             CPAN ID: acpguedes
326             guedes.aureliano@gmail.com
327              
328             =head1 COPYRIGHT
329              
330             This program is free software; you can redistribute
331             it and/or modify it under the same terms as Perl itself.
332              
333             The full text of the license can be found in the
334             LICENSE file included with this module.
335              
336              
337             =head1 SEE ALSO
338              
339             perl(1).
340              
341             =cut
342              
343             #################### main pod documentation end ###################
344              
345             'Warning! The consumption of alcohol may cause you to think you have mystical kung-fu powers.';