1
\$\begingroup\$

This is my solution for the Credit problem on CS50's (Introduction to CS course) Pset1. It involves using Luhn's Algorithm to test the validity of the Credit Card Number entered and based on a few conditions attempts to identify the Credit Card Company.

check_length attempts to find the length of the number entered. check_company attempts to ID the company. check_luhn validates the number based on Luhn's Algorithm.

Lunh's Algorithm:

The formula verifies a number against its included check digit, which is usually appended to a partial account number to generate the full account number. This number must pass the following test:

From the rightmost digit and moving left, double the value of every second digit. If the result of this doubling operation is greater than 9 (e.g., 8 × 2 = 16), then add the digits of the result (e.g., 16: 1 + 6 = 7, 18: 1 + 8 = 9) or, alternatively, the same final result can be found by subtracting 9 from that result (e.g., 16: 16 − 9 = 7, 18: 18 − 9 = 9). Take the sum of all the digits. If the total modulo 10 is equal to 0 (if the total ends in zero) then the number is valid according to the Luhn formula; otherwise it is not valid. I am not very comfortable with the so many if-else conditions. I'd like to know if they can be eliminated. Any other changes are also welcome.

#include <stdio.h>
#include <cs50.h>
#include <stdbool.h>

int check_length(long);
void check_company(int,long);
bool check_luhn(long,int);
int length;

int main(void)
{
    long c = get_long("Enter Credit Card Number: ");
    check_length(c);
    check_luhn(c,length);
    if(check_luhn(c,length)==true)
    {
            check_company(length,c);
    }
    else printf("INVALID\n");

}

int check_length(long w)
{
    for(int i=12;i<16;i++)
    {
            long power = 1;
            for (int k=1;k<i+1;k++)
            {
                    power = power * 10;
            }
            int scale = w/power;
            if (scale<10 && scale>0)
            {
                    length = i+1;
            }              
   }    
   return length;
 }

 void check_company(int x,long z)
 {
    if(x == 15)
    {
            int y = z/10000000000000;           //z/10^13
            if(y==34||y==37)
            {
                    printf("AMEX\n");
            }
            else
            {
            printf("INVALID\n");
            }
    }
    else if(x==13)
    {
            int y = z/100000000000;                 //z/10^11
            if(y==4)
            {
                   printf("VISA\n");
            }
     }
     else if(x==16)
     {
             int q = z/1000000000000000;
             int y = z/100000000000000;
             if(y==51||y==52||y==53||y==54||y==55)
             {
                     printf("MASTERCARD\n");
             }
             else             
             if(q==4)
             {
                     printf("VISA\n");
             }
             else printf("INVALID\n");
     }
     else printf("INVALID\n");
  }

  bool check_luhn(long a,int b)
  {
     int f = 0;
     int j=0;
     for(int d=1;d<b+1;d++)
     {    
             int e = a%10;
             a = a/10;
             if(d%2==1)
             {
                    f = f+e;
             }
             else
             {
                     int m = 2*e;
                     int g = m%10;
                     int h = m/10;
                     j = j+g+h;
              }

      }
      int l = j + f;
      if(l%10==0)
      {
             return true;
      }
      else return false;
    }
\$\endgroup\$
3
  • 6
    \$\begingroup\$ Why the focus on the line count? Can you tell us more about the challenge you completed? Questions should stand on their own, with all relevant information included. \$\endgroup\$ – Mast Apr 21 '20 at 12:10
  • 2
    \$\begingroup\$ Please add a brief description of Luhn's Algorithm. We don't know what CS50 is and don't have access to it. \$\endgroup\$ – pacmaninbw Apr 21 '20 at 14:34
  • 1
    \$\begingroup\$ @Mast Thanks for the comment. I want to know if the code can be made simpler. I wasn't very comfortable because I'd used a lot of if-else statements. I'd like to minimze those. Any other changes would be welcome. This was not a challenge, it was a problem on an introductory CS course. \$\endgroup\$ – MelPradeep Apr 22 '20 at 3:36
2
\$\begingroup\$

Instead of all the if-else statements, you could use a switch statement, like so:

switch (x) {
  case 15:
    int y = z/10000000000000;
    if (y==34||y==37)
    ...
    ...
    ...
    break;
  case 13:
...
...
...
  default:
    printf("INVALID\n");
}

Also to make your code look cleaner, eliminate any curly brackets around if statements that execute only one statement, for example,

if (l%10==0)
{
        return true;
}

could be:

if (l%10==0) return true;

Additionally, instead of

if (y==51||y==52||y==53||y==54||y==55)

use

if (y>=51&&y<=55)
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Optionally OP could return (l%10==0), this would eliminate the else \$\endgroup\$ – Shaun H Apr 24 '20 at 10:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.