CS50 Credit Problem – Not working for cards with 10+ digits

CS50 Credit Problem – Not working for cards with 10+ digits

Problem Description:

I’m new to programming and having a bit of trouble with the CS50 credit problem.

It seems to run ok until the firstCase function- this is where it’s supposed to calculate the product of of every other number*2, starting from the penultimate one. It seems to return the expected result, until the user input reaches 11 digits – then it gets progressively wackier! Why might this be?

The secondCase function also seems to be adding itself to the result of firstCase (which is what you want it to do ultimately, but I wasn’t aware I’d instructed it to!). Which bit of code is doing this?

I was getting INVALID (assume because of the above), so I commented out the final result, and have just been testing with printf firstSum and total.

Sorry, I know this problem has been posted many times on here, but this has got me stumped – any advice anyone can offer would be much appreciated. Thanks!

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

long getNumber(void);
int cardDigits(long number);
long returnDivisor(int cardLength);
long firstCase(long workingcc);
long secondCase(long workingcc);
int conditions(long total);
int cardType(int checkConditions, long divisor, int firstDigit, int secondDigit);

int main(void)
{

long number = getNumber();
int cardLength = cardDigits(number);
long divisor = returnDivisor(cardLength);
long workingcc = number;
int firstDigit = number / divisor;
int secondDigit = number / (divisor / 10);
long firstSum = firstCase(workingcc);
long total = secondCase(workingcc);
//int checkConditions = conditions(total);
//int cardResult = cardType(checkConditions, divisor, firstDigit, secondDigit);

//if (cardResult == 1){
  //  printf("AMEX n");}

//else if (cardResult == 2){
  //  printf("MASTERCARD n");}

//else if (cardResult == 3){
  //  printf("VISA n");}

//else if (cardResult == 4){
  //  printf("INVALID n");}


}


//Get card number from user
long getNumber(void){
long n;
do
{
n = get_long("card number ");
}
while (n <= 0);
return n;
}


//Obtain card length and divisor
int cardDigits(long number){
long n;
n = number;
int count = 0;
while (n > 0)
    {
        n = n / 10;
        count++;
    }
    return count;
}

//Obtain divisor
long returnDivisor(int cardLength){
long divisor = 10;
for (int j = 0; j < cardLength - 2; j++)
{
  divisor = divisor * 10;
}
return divisor;
}


//Obtain sum for first condition
long firstCase(long workingcc){
  int sum;
  workingcc = workingcc / 10;
while (workingcc !=0)
{
  int lastDigit = workingcc % 10;
  int timesTwo = lastDigit * 2;
  sum = sum + (timesTwo % 10) + (timesTwo / 10);
  workingcc = workingcc / 100;
}
return sum;
}


//Obtain sum for second condition
long secondCase(long workingcc){
  int sumb;
while (workingcc > 0)
{
  int lastDigit2 = workingcc % 10;
  sumb = sumb + lastDigit2;
  workingcc = workingcc / 100;
}
return sumb;
}

//Check total modulo 10 congruent to 0
int conditions(long total){
  if (total % 10 == 0){
    return 1;
  }
  else{
    return 0;
  }
}

//Check results and print card type
int cardType(int checkConditions, long divisor, int firstDigit, int secondDigit){
  if (checkConditions == 1 && divisor == 15 && (secondDigit == 34 || secondDigit == 37)){
    return 1;
  }
  else if (checkConditions == 1 && divisor == 16 && (secondDigit == 51 || secondDigit == 52 || secondDigit == 53 || secondDigit == 54 || secondDigit == 55)){
    return 2;
  }
  else if (checkConditions == 1 && divisor == (13 | 16) && firstDigit == 4){
    return 3;
  }
  else{
    return 4;
  }
}

Solution – 1

  1. Your first include was missing a ‘#’ (I updated question).

  2. firstCase(): sum is uninitialized.

  3. secondCase(): sumb is uninitialized.

  4. divisor == (13 | 16) means it the divisor equal to the binary OR which the same as divisor == 29.

  5. You don’t do anything with the result in main() so it may be optimized out entirely.

You can refactor those two functions as follows

long firstCase(long workingcc) {
    int sum = 0;
    for(workingcc /= 10; workingcc; workingcc /= 100) {
        int timesTwo = (workingcc % 10) * 2;
        sum += (timesTwo % 10) + (timesTwo / 10);
    }
    return sum;
}

long secondCase(long workingcc) {
    int sumb = 0;
    for(; workingcc; workingcc /= 100) {
        sumb += workingcc % 10;
    }
    return sumb;
}

Using the American Express test credit card number of 378282246310005 firstCase() returns 27 and secondCase() returns 33. Neither now exhibit what you observed, but you need to tell us what they should be doing to verify correctness.

Rate this post
We use cookies in order to give you the best possible experience on our website. By continuing to use this site, you agree to our use of cookies.
Accept
Reject