Need help to figure out what's wrong with my code for the credit card question in Week 1 of CS50

64 Views Asked by At

So i need help to figure out what's wrong with my code. Its capable of testing all the invalid cases but sometimes misses the other cases. I have added detailed comments to explain my thought process.

Here is a link to the question : https://cs50.harvard.edu/x/2023/psets/1/credit/

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

long get_card_number(void);
int get_length(long cardno);
int calculate_sum(long cardno);
void printtype(int sum, int length_cardno, long cardno);


int main(void)
{

    long cardno = get_card_number();    // Get card number from user

    int length_cardno = get_length(cardno); // Calculate length of the card number

    int sum = calculate_sum(cardno);    // To calculate total = sum_digit + alt_digit + last_digit

    printtype(sum, length_cardno, cardno); // To check what type of credit card it is, based on the different parameters

}

long get_card_number(void) // Function to get the card number from the user
{
    long cardno;
    do
    {
        cardno = get_long("Number: ");
    }
    while(cardno < 0);
    return cardno;
}

int get_length(long cardno) // Function to get the length of the card and to get the length of altdigit*2
{
    int i;
    for(i = 0; cardno != 0; i++)
    {
        cardno = cardno/10;
    }
    return i;
}

int calculate_sum(long cardno) // Function to get sum of the digits
{
    int alt_digit = 0;
    int alt_sum = 0;
    int digit = 0;
    int sum = 0;
    int total = 0;
    int last_digit = cardno % 10;

    cardno = cardno/10; // To get rid of the last digit
    bool Alternate_number = true; // To start with 2nd last digit

    while(cardno > 0)
    {
        if(Alternate_number == true) // Alt digits are the 2nd last digit, 4th last digit, 6th last digit and so on (even)
        {
            alt_digit = cardno % 10;
            alt_digit = alt_digit*2;
            if(alt_digit >= 10)          // To add the first and second digits of the 2 digit alt product separately
            {
                int first_alt_digit = alt_digit/100;
                int second_alt_digit = alt_digit/10;
                alt_sum += first_alt_digit + second_alt_digit;
            }
            else
            {
                alt_sum += alt_digit;
            }
            cardno = cardno/10;
        }
        else    // Digits are the 3rd last digit, 5th last digit, 7th last digit and so on (odd)
        {
            digit = cardno % 10;
            sum += digit;
            cardno = cardno/10;
        }
        Alternate_number = !Alternate_number; // To keep alternating

    }
    total = alt_sum + sum + last_digit; // Adding both of them together along with the last digit we removed at the start
    return total;

}

void printtype(int sum, int length_cardno, long cardno) // Function to know the type of card
{
    int zero_or_not = sum % 10; // To only look at the unit's place to see if sum ends with 0
    int first_digit = 0;
    int second_digit = 0;

    if(length_cardno == 13) // If statement to know the first two digits of the credit card number
    {
        first_digit = cardno/10^13;
    }
    else if(length_cardno == 15)
    {
        first_digit = cardno/10^15;
        second_digit = cardno/10^14;
    }
    else if(length_cardno == 16)
    {
        first_digit = cardno/10^16;
        second_digit = cardno/10^15;
    }

    if((length_cardno == 13 || length_cardno == 15 || length_cardno == 16) && (zero_or_not == 0)) // If statement to print the card type based on length, and the first and second digits
    {
        if((length_cardno == 15) && (first_digit == 3) && (second_digit == 4 || second_digit == 7))
        {
            printf("AMEX\n");

        }
        else if(length_cardno == 16 && (first_digit == 5) && (second_digit == 1 || second_digit == 2 || second_digit == 3 || second_digit == 4 || second_digit == 5))
        {
            printf("MASTERCARD\n");
        }
        else if((length_cardno == 13 || length_cardno == 16) && (first_digit == 4))
        {
            printf("VISA\n");
        }
        else
        {
            printf("INVALID\n");
        }
    }
    else
    {
        printf("INVALID\n");
    }

}

I tried finding out the problem but I couldn't, so I'd greatly appreciate if someone could help me out. I'm assuming that it has something to do with how I wrote the calculate sum function. Here are the errors it showed:

:( identifies 378282246310005 as AMEX
    expected "AMEX\n", not "INVALID\n"
:( identifies 371449635398431 as AMEX
    expected "AMEX\n", not "INVALID\n"
:( identifies 5555555555554444 as MASTERCARD
    expected "MASTERCARD\n", not "INVALID\n"
:( identifies 5105105105105100 as MASTERCARD
    expected "MASTERCARD\n", not "INVALID\n"
:( identifies 4111111111111111 as VISA
    expected "VISA\n", not "INVALID\n"
:( identifies 4012888888881881 as VISA
    expected "VISA\n", not "INVALID\n"
:( identifies 4222222222222 as VISA
    expected "VISA\n", not "INVALID\n"

Edits: 1) Changed first_digit to first_alt_digit and second_digit to second_alt_digit.

  1. Also added + sign to alt_digit = first_alt_digit + second_alt_digit.

  2. Removed the usage of the function for checking the length of alt_digit and used alt_digit >= 10 instead.

1

There are 1 best solutions below

5
King Brain On

The problem is with how I calculated the first_digit and second_digit of the cardno in the printtype function.

I used the symbol ^ to raise 10 to the power of 13, 15 and 16 for each length case. But that is not the symbol for exponential. The correct thing to do here is it calculate exponential using the (long)pow(10,13) function, by including the math.h library.

Also, my initial expression for the second_digit did not take the unit's place after the division and instead took a 2 digit number. So i had to write the expression for second_digit as follows:

second_digit = (cardno/(long)pow(10,14)) % 10;