2

The logic from hacker1:

  1. Multiply every other digit by 2, starting with the number's second-to-last digit, and then add those products' digits together.
  2. Add the sum to the sum of the digits that weren't multiplied by 2.
  3. If the total's last digit is 0 (or, put more formally, if the total modulo 10 is congruent to 0), the number is valid!

Following for 5105105105105100...

-> 5  1  0  5  1  0  5  1  0  5  1  0  5  1  0  0

1.    2     10    0     2     10    0     2     0
      2  +  1+0 + 0  +  2  +  1+0 + 0  +  2  +  0 = 8

2. 5     0     1     5     0     1     5     0    = 17
                                                    17 + 8 = 25

3. 25 -> 5 != 0
   INVALID

But for check50, 5105105105105100 is MASTERCARD. Where am I wrong?

Output for my code:

:) credit.c exists
:) credit.c compiles
:) identifies 378282246310005 as AMEX
:) identifies 371449635398431 as AMEX
:) identifies 5555555555554444 as MASTERCARD
:( identifies 5105105105105100 as MASTERCARD
   \ expected output, but not "INVALID\n"
:( identifies 4111111111111111 as VISA
   \ expected output, but not "INVALID\n"
:( identifies 4012888888881881 as VISA
   \ expected output, but not "INVALID\n"
:) identifies 1234567890 as INVALID
:) rejects a non-numeric input of "foo"
:) rejects a non-numeric input of ""
1

Multiply every other digit by 2, starting with the number's second-to-last digit, and then add those products' digits together.

| improve this answer | |
  • I don't understand English very well yet. It still confusing to me. So to multiply starting with the number's second-to-last digit, considering an array of 5 digits, I have to multiply digits 0, 2 and 4, not digits 1 and 3? =/ Thanks. – Mateus Pires Jun 14 '14 at 19:16
  • Or I start from the end to the beginning... – Mateus Pires Jun 14 '14 at 19:22
  • In your 5105105105105100 example you multiplied starting with the last number that's why you got 25. – kide Jun 14 '14 at 19:23
  • Got it! I put the value on an array following the order of the digits and considered the element at 0 as the first. Thanks! – Mateus Pires Jun 14 '14 at 19:52
3

Multiply every other digit by 2, starting with the number's second-to-last digit, and then add those products' digits together.

Given a number that consists of an odd (i.e., not divisible by 2) number of digits, it won't really matter where you start.

Example:

12345

The second-to-last digit is 4, not 2. However, if you started with 2, you'd still get the same result as if you started with 4.

So,

(4 x 2) + (2 x 2) = 12

is the same as

(2 x 2) + (4 x 2) = 12

But, this really matters when you have a number that consist of an even (i.e., divisible by 2) number of digits.

Example:

123456

Again, the second-to-last is 5, not 2, but unfortunately,

(2 x 2) + (4 x 2) + (6 x 2) = 24

is NOT the same as

(5 x 2) + (3 x 2) + (1 x 2) = 18
| improve this answer | |
  • Got it! Thanks! – Mateus Pires Jun 15 '14 at 17:21
  • I am stuck on PSET 1! How can I stimulate the adding of alternate digits on C???? And I don't know how to multiply the alternate digits then adding them up... Any help guys? – Happytreat Jun 18 '14 at 0:04
  • @HappyTreat, here's an answer to your question cs50.stackexchange.com/a/1210/1161 – Kareem Jun 18 '14 at 3:15
0

My approach was to take the mod 10 value and divide the number by 10 until I reached 0. This means I am processing the digits back to front. I also had a boolean which was false to begin (last digit is not multiplied by two) and toggled as I finished each digit. I kept two sums.

int get_checksum(long long ccnum)
{
    int sum_non_mult = 0;
    int sum_mult_dig = 0;
    long long cur_num = ccnum;
    bool mult_digit = false; // when true, multiply by 2 and sum the digits
    while (cur_num > 0) {
        int cur_digit = cur_num % 10;
        if (mult_digit) {
            int work_prod = cur_digit * 2;
            int new_sum = 0;
            while (work_prod > 0)
            {
                int tmp_digit = work_prod % 10;
                new_sum += tmp_digit;
                work_prod /= 10;
            }
            sum_mult_dig += new_sum;
        }
        else
        {
            sum_non_mult += cur_digit;
        }
        mult_digit = !mult_digit;
        cur_num /= 10;
    }
    return ((sum_non_mult + sum_mult_dig) % 10);
}

What I don't care for about my solution is that I have to separately validate the length and starting digits for each issuing company.

| improve this answer | |

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .