# CS50 Pset1 credit

after 2 days and half i did it it's tricky at first but this problem made me understand loops and array much deeper , the question is my code is good as style and design ? any ideas should consider

``````#include<stdio.h>
#include<cs50.h>
#include<math.h>
unsigned long long get_long_long(string prompt);

int main(void)
{
unsigned long long card = get_long_long("Number:");
unsigned long long card1 = card ;
int sum, sum1, counter = 0 ;
while (card1 != 0)
{
card1 = card1 / 10 ;
counter++ ;
}

if (counter != 15 && counter != 16)
{
printf("INVALID\n") ;
}

int cc[counter];
for (int i = 0; i < counter; i++)
{
cc[i] = card % 10 ;
card = card / 10 ;
}

int cc1[counter];
for (int i = 0; i < counter; i++)
{
cc1[i] = cc[i];
}

for (int i = 1; i < counter; i += 2)
{
cc1[i] =  cc1[i] * 2 ;
if (cc1[i] >= 10)
{
for (int j = 0; j < 2; j++)
{
int first_degit = cc1[i] / 10 ;
int secnd_degit = cc1[i] % 10 ;
cc1[i] = first_degit + secnd_degit ;
}
}
sum = sum + cc1[i] ;
}

for (int i = 0; i < counter; i += 2)
{
sum1 = sum1 + cc1[i] ;
}

int sum2 = sum1 + sum ;
sum2  = sum2 % 10 ;

if (counter == 15)
{
if (sum2 == 0)
{
if (cc == 3 && cc == 7)
{
printf("AMEX\n");
}
else
{
printf("INVALID\n");
}
}
else
{
printf("INVALID\n");
}
}

if (counter == 16)
{
if (sum2 == 0)
{
if ((cc == 5 && cc == 5) || (cc == 5 && cc == 1) || (cc == 5 && cc == 3))
{
printf("MASTERCARD\n");
}
else if (cc == 4)
{
printf("VISA\n");
}
else
{
printf("INVALID\n");
}
}
else
{
printf("INVALID\n");
}
}
}
unsigned long long get_long_long(string prompt)
{
long long n ;
do
{
n = get_long("%s", prompt) ;
}
while (n < 1) ;
return n ;
}
``````

While your program will likely pass the automated tests of C50, in terms of design, you could think of the following:

1. As per the problem description,

Visa uses 13- and 16-digit numbers

Your program seems to consider a 13-digit number invalid

1. You may not necessarily need to duplicate `card` into `card1` and run them digit-to-digit twice to do the checks. Surely, it is fast anyway, but you asked about design. You get card number as `long long int` anyway, so you could just say something like:
``````    if (card < 999999999999 || card > 9999999999999999 ||
(card > 9999999999999 && card < 99999999999999))
{
printf("INVALID\n");
return 1;
}
``````

and be done with it in terms of number of digits.

1. In terms of VISA / MC/ AMEX detection, a series of `if` statements may do the job, but a somewhat more elegant solution (after all other checks) could be a switch statement like this:
``````    if (last_digit == 4)
{
printf("VISA\n");
return 0;
}

int digits = last_digit * 10 + prev_digit;

switch (digits)
{
case 34:
case 37:
// Check 15 digits
// ...
printf("AMEX\n");
break;
// Otherwise invalid
// ...
case 51:
case 52:
case 53:
case 54:
case 55:
// Check 16 digits
// ...
printf("MASTERCARD\n");
break;
// Otherwise invalid
// ...
default:
printf("INVALID\n");
return 1;
}
``````

This allows you to add more number checks (MC actually uses some of the 2* range).

• yeah you right i did my code for now to pass the cs50 automate tests after long hours digging ,, i like the idea of switch case more cool and simple , that's my reason to not do multi credit card valid options cuz will be too complex to carry on when someone else see it , really appreciate your answer and good luck ! – Hassan Abdelazeam Jul 13 '19 at 19:46