2
\$\begingroup\$

How can I improve or shorten my implementation of the Luhn algorithm?

 int digits;
 cout << "enter the numer of digits" << endl;
 cin >> digits;
 int Acc_num[digits];
 int shuma = 0;

The shuma variable is the sum.

I created an array to store the digits from the string credit_card.

And asked the user how many digits his credit card has, etc. (the digits int).

 string credit_card;
 cout << "enter the identification number" << endl;
 cin >> credit_card;
 // store the digits
 for (int i = 0 ; i < digits ; i ++ ) {
 Acc_num[i] = credit_card[i];
 }
 for (int i = 0 ; i <= (digits - 1) ; i ++ ) {
 Acc_num[i] -= 48;
 }
 // Double every other
 for (int i = 1 ; i <=digits ; i ++) {
 if (i % 2 == 0) {
 Acc_num[i-1] = 2 * Acc_num[i-1];
 } else {
 Acc_num[i-1] = Acc_num [i-1];
 }
 }
 //Sum digits
 for (int i = 1 ; i <= digits ; i ++ ) {
 if (Acc_num[i-1] > 9 && i % 2 == 0) {
 int mod = Acc_num[i-1] % 10 ;
 Acc_num[i-1] = 1 + mod ;
 } else {
 Acc_num[i-1] = Acc_num[i-1];
 }
 }
 // the sum
 for (int i = 0 ; i <= (digits - 1) ; i ++ ) {
 shuma += Acc_num[i];
 }
 if (shuma % 10 == 0) {
 cout << "\nthis number is valid" << endl;
 } else {
 cout << "\nthis number is invalid" << endl;
 }
200_success
145k22 gold badges190 silver badges478 bronze badges
asked Apr 23, 2016 at 18:10
\$\endgroup\$
0

2 Answers 2

4
\$\begingroup\$

Doubling the even digits and subtracting 9 if> 10 would be mod 9 so a really simple, compact algorithm might be:

for (int i = 0; i < nDigits; i++)
{
 int digit = digitArray [i] - '0'; // Char to number
 if (i & 1) // Digit 1, 3, 5 not 0, 2, 4 - "even digits" starting at 1
 if ((digit <<= 1) >= 10) // Double it, check >= 10
 digit -= 9; // Same as summing the digits
 shuma += digit;
}
int checksum = shuma % 10;
answered Apr 23, 2016 at 19:46
\$\endgroup\$
2
  • \$\begingroup\$ Code error - should have been >= 10, not > 10 but you get the idea. Break the problem down, solve with math where possible and don't write code that "does" things, write code that "takes care of" them. \$\endgroup\$ Commented Apr 24, 2016 at 20:27
  • \$\begingroup\$ One correctness consideration is that if the number is excessively long, shuma can overflow, which will probably ruin the checksum value. To avoid that possibility, you can change shuma += digit; to if ((shuma += digit) >= 10) shuma -= 10; and eliminate the int checksum = shuma % 10; line, since shuma will already be a modulo 10 reduced residue. \$\endgroup\$ Commented Jun 29, 2018 at 23:03
1
\$\begingroup\$

It looks like you could do all of those calculations in one loop. Also, all of the places where you do Acc_num[i-1] = Acc_num [i-1]; amount to a no-op, so you could remove them.

answered Apr 23, 2016 at 18:27
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.