http://qs321.pair.com?node_id=147694

in reply to Luhn Number Golf

This is 60 characters. I've verified it by comparing the results to the referenced code from http://perl.about.com/library/weekly/aa080600h.htm.
```sub luhn {
#        1         2         3         4         5         6
#23456789012345678901234567890123456789012345678901234567890
my\$s;\$_=reverse@_;s/(.)(.)/\$1.\$2*2/ge;\$s+=\$_ for/./g;!chop\$s
}

Replies are listed 'Best First'.
Re: Re: Luhn Number Golf
by PrakashK (Pilgrim) on Feb 26, 2002 at 21:47 UTC
++. 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

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.

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

Re: Re: Luhn Number Golf
by petral (Curate) on Feb 27, 2002 at 17:02 UTC
52 chars:
```sub luhn {
\$_=reverse@_;s/(.)(.)/\$1.\$2*2/ge;s/\B/+/g;eval=~/0\$/
}