Sun, September 15, 2024
(Originally published as part of a 100 Days of Code series. Revised for clarity and purpose.)
This week has been all about code challenges, which has been glorious! One intriguing challenge was implementing a credit card validator using the Luhn algorithm, which prevents single-digit errors and adjacent transpositions like 90 → 09
. Coding the Luhn algorithm is straightforward once you break it down—so let’s walk through my implementation.
It turned out to be a great excuse to lean into some Functional Programming (FP). Instead of an imperative function where you queue up credit card numbers to test, the verification becomes a method you apply directly to credit card number variables. This modular approach increases the value of your code because it can be reused in more contexts without rewriting. One side effect of FP is that data becomes the star—not functions—which ends up looking very streamlined.
I kicked things off with an arrow function to stay aligned with the FP paradigm. While arrow functions shine in one-liners, they’re still a solid choice for readability and modern style.
Set Aside the Last Digit: Starting with the example number
4539 1488 0343 6467
, we isolate the last digit (7
) and store it in a variable calledlastDigit
. This is done with the common patternarray.length - 1
, which grabs the final element in a zero-indexed array.Reverse the Array: With the last digit set aside, we take the rest of the number—
4539 1488 0343 646
—and reverse it. That gives us:6463 3408 8841 9354
, which we store in a new array namedallExceptLastReversed
.Double Every Other Element: Starting from index
0
, we double every other digit in the reversed array. So values like6 → 12
,4 → 4
,6 → 12
,3 → 3
, and so on. If a doubled number is greater than9
, we subtract 9 to keep it in single digits (e.g.,12 → 3
). The array becomes something like[3, 4, 3, 3, ...]
.Sum the Elements and Validate: Next, we sum all the adjusted digits using
reduce
, add back thelastDigit
(7
), and check if the total is divisible by 10. If it is, the number passes the Luhn check.
This challenge was a fun way to work with both functional and imperative styles. It also reinforced how nice it is when your code stays flexible and easy to reuse. I'm looking forward to tackling more of these bite-sized problems and seeing what new patterns and tricks pop up along the way.
Here’s the complete code:
const validateCred = (cardNumber) => {
const lastDigit = cardNumber[cardNumber.length - 1];
let allExceptLastReversed = cardNumber.slice(0, -1).reverse();
for (let i = 0; i < allExceptLastReversed.length; i += 2) {
allExceptLastReversed[i] *= 2;
if (allExceptLastReversed[i] > 9) {
allExceptLastReversed[i] -= 9;
}
}
const sum = allExceptLastReversed.reduce((acc, curr) => acc + curr, 0) + lastDigit;
// sum all digits
return (sum % 10 === 0);
};
Top comments (1)
Hi Jacob, I haven’t seen any updates from you on your 100days challenge since this day 77.
Is everything alright? How is the study coming along? How’s the challenge coming along?
Have been wanting to reach out but it keeps skipping my mind.
Hope to hear from you soon.
🫡🦾🦾🦾