Perl weekly challenge 95
Palindromic numbers
You are given a number $N
. Write a script to figure out if the given number is Palindrome. Print 1 if true otherwise 0.
There is an easy solution to this - to use "reverse" in string context to reverse the number and comparing the two strings:
sub is_palindrome_rev {
return ( $_[0] eq reverse $_[0]) ? 1 : 0;
}
But this just seems a touch too easy - so let's see if we can find an alternative solution. Something that will potentially work in any base - not just base 10!
sub is_palindrome_array {
my($n,$radix) = @_;
$radix||=10;
return 0 if $n < 0;
my @digits = $n%$radix;
push @digits, $n%$radix while $n = int ($n/$radix);
while( @digits>1 ) {
return 0 if shift @digits != pop @digits;
}
return 1;
}
- Bail out if the number is negative;
- Chop the number of digits (in our "base").
- Push the number (module the radix) onto an array of digits, repeatedly dividing by the radix until we have nothing left.
- Technically this returns the digits in the reverse order (push is more efficient than unshift), but as we are interested in palindromes that isn't an issue.
- Then we work through the array and seeing if the first and last digits are the same {if the array has only 1 entry then the first and the last digits are the same!}. Use pop/shift to return the numbers and take them from the array...
Stack
This is a simple case of creating a Stack object - basic OO coding. As this is a stack though we don't need to use a hashref as we would normally use - we can just bless an arrayref
Just a few notes on this one - mainly about good practice
- We wish to use the standard names push/pop for the stack - but these are built-ins for clarity in the code we use CORE::push & CORE::pop to make certain we are using the built-in push and pop commands
- Care needs to be taken as we may have an empty stack when making calls so should check for this in cases such as pop/min/top...
You can see my code on github at:
- https://github.com/drbaggy/perlweeklychallenge-club/tree/master/challenge-095/james-smith/
Your initial function can be simplified further.
Any time you have something like:
That should trigger your code smell senses. You can just replace it with:
Also, I'm not sure why you think this only works for base 10. It works for binary, octal, etc. If you lowercase everything, it'll work just fine for hexadecimal too.
Two things about the first comment:
As for the second one - yes if you treat this purely as a string based problem then it will work for any string - but then it is just proving strings are palindromic... Little to do with whether or not they are numbers. So I felt it was a bit of a "cop-out" to just use the palindromic property of a string....
The second solution was to look at this as a number based problem - so I could experiment with other bases [2,3,4,5,...,1001,...)
The solution works in whatever base you feel fit to choose. Yes it will tell you 1002 is palindromic base 1001 if you want to check.