++.
You can eliminate reverse and shorten it to 55.
sub luhn {
# 1 2 3 4 5
#234567890123456789012345678901234567890123456789012345
my$s;$_=pop;~s/(.)(.)/$2.$1*2/ge;$s+=$_ for/./g;!chop$s
}
and, if you don't care for strict-ness, shave
another 5 chars, by eliminating my$s;
/prakash | [reply] [d/l] [select] |
Unfortunately, you can't simply eliminate reverse. Cody Pendant explained why in the comments in his solution; if the number has an odd number of digits, you'll end doubling the wrong digits. For example, your solution would return true for 548979844, which is not a Luhn number.
You shouldn't eliminate my$s; either. That's not there for strict-ness, but to allow the subroutine to be called more than once. Without it, $s would keep its values between calls, throwing off all the subsequent answers.
| [reply] |
If you aren't going for strictness, you can get the same initialization effect with
($_,$s)=@_
Which is one char shorter than
my$s;$_=pop
If you also want to keep strictness, you can always sidestep it by replacing $s with a global punctuation variable.
-Blake
| [reply] [d/l] [select] |
sub luhn {
$_=reverse@_;s/(.)(.)/$1.$2*2/ge;s/\B/+/g;eval=~/0$/
}
  p | [reply] [d/l] |