GolfScript, 44 chars
-1%{16%}%2/1,\+{(\.{0=2*.9>9*-+}{;}if+}*10%!
Selected commentary
Interestingly, the first two items below demonstrate three completely different uses of the % operator: array selection, map, and mod. Most GolfScript operators are "context-sensitive", giving them hugely divergent behaviours depending on what types the arguments are.
-1% reverses the string. This is important as the digit pairs are counted from the right.
{16%}% converts all the ASCII digits into numbers, by modding them with 16.
2/ splits the array into groups of 2.
1, is a cheap way to do [0].
\+ effectively prepends the 0 to the digits array. It does this by swapping then concatenating.
The 0 is prepended in preparation for the fold that comes in next. Rather than taking an explicit initial value, GolfScript's fold uses the first item in the array as the initial value.
Now, let's look at the actual fold function. This function takes two arguments: the folded value, and the current item on the array (which in this case will be an array of 2 or (uncommonly) 1, because of the 2/ earlier). Let's assume the arguments are 1 [2 3].
(\. splits out the leftmost array element, moves the remaining array to the front, then copies it. Stack now looks like: 1 2 [3] [3].
- The
if checks if the array is empty (which is the case for the last group when dealing with an odd-sized account number). If so, then no special processing happens (just pop off the empty array).
- For an even group:
0= grabs the first (only, in this case) element of the array. 1 2 3
2* doubles the number. 1 2 6
.9>9*- subtracts 9 from the number if it's greater than 9. Implemented as: copy the number, compare with 9, multiply the result (which is either 0 or 1) with 9, then subtract. 1 2 6
+ finally adds that to the first number. 1 8
+ (after the if) adds the result of the if to the original value, resulting in the new folded value.
After the folding completes, we simply mod with 10 (10%), and negate the result (!), so that we return 1 iff the sum is a multiple of 10.