Credit Card Checker - returning false even with valid credit cards - still stuck!

Hi everyone, I’m still stuck on this problem after days of trying to fix it. Here’s the link to the exercise: Credit Card Checker Link.
Here are the instructions for this section of the code:

  1. Starting from the farthest digit to the right, AKA the check digit, iterate to the left.
  2. As you iterate to the left, every other digit is doubled (the check digit is not doubled). If the number is greater than 9 after doubling, subtract 9 from its value.
  3. Sum up all the digits in the credit card number.
  4. If the sum modulo 10 is 0 (if the sum divided by 10 has a remainder of 0 ) then the number is valid, otherwise, it’s invalid.

I’ve been logging to the console after each step so I know the calculations are correct, the correct digits are doubled and are not doubled etc but I can’t figure out why the code is returning false when I enter a valid credit card number. I’d be so grateful for some help!!

// All valid credit card numbers
const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
const valid2 = [5, 5, 3, 5, 7, 6, 6, 7, 6, 8, 7, 5, 1, 4, 3, 9];
const valid3 = [3, 7, 1, 6, 1, 2, 0, 1, 9, 9, 8, 5, 2, 3, 6];
const valid4 = [6, 0, 1, 1, 1, 4, 4, 3, 4, 0, 6, 8, 2, 9, 0, 5];
const valid5 = [4, 5, 3, 9, 4, 0, 4, 9, 6, 7, 8, 6, 9, 6, 6, 6];

// All invalid credit card numbers
const invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];
const invalid2 = [5, 7, 9, 5, 5, 9, 3, 3, 9, 2, 1, 3, 4, 6, 4, 3];
const invalid3 = [3, 7, 5, 7, 9, 6, 0, 8, 4, 4, 5, 9, 9, 1, 4];
const invalid4 = [6, 0, 1, 1, 1, 2, 7, 9, 6, 1, 7, 7, 7, 9, 3, 5];
const invalid5 = [5, 3, 8, 2, 0, 1, 9, 7, 7, 2, 8, 8, 3, 8, 5, 4];

// Can be either valid or invalid
const mystery1 = [3, 4, 4, 8, 0, 1, 9, 6, 8, 3, 0, 5, 4, 1, 4];
const mystery2 = [5, 4, 6, 6, 1, 0, 0, 8, 6, 1, 6, 2, 0, 2, 3, 9];
const mystery3 = [6, 0, 1, 1, 3, 7, 7, 0, 2, 0, 9, 6, 2, 6, 5, 6, 2, 0, 3];
const mystery4 = [4, 9, 2, 9, 8, 7, 7, 1, 6, 9, 2, 1, 7, 0, 9, 3];
const mystery5 = [4, 9, 1, 3, 5, 4, 0, 4, 6, 3, 0, 7, 2, 5, 2, 3];

// An array of all the arrays above
const batch = [valid1, valid2, valid3, valid4, valid5, invalid1, invalid2, invalid3, invalid4, invalid5, mystery1, mystery2, mystery3, mystery4, mystery5];


// Add your functions below:

const validateCred = array => {
  newArray =[]
  for (var i = array.length - 2; i >= 0; i -= 2)
{ 
  let doubleValue = array[i] * 2 
     if (doubleValue > 9) {
        doubleValue -= 9;
  }     newArray.push(doubleValue)
}
  let combined =[].concat(newArray, array[j]);  
  for (var j = array.length - 1; j >= 0; j -=2) 
 {   
      if (combined.reduce((prv, cur) => prv + cur) % 10 === 0) {
          return true;
        } else {
          return false;
     }
} 
  }

console.log(validateCred(valid1))


Great work!!
There is a tiny problem in your implementation,
for (var j = array.length - 1; j >= 0; j -=2)
this loop should have only one purpose, pushhing the non doubled elements to your newArray.

so your code will end up with something like that:

const validateCred = (array) => {
  let newArray = [];
  for (let i = array.length - 2; i >= 0; i -= 2) {
    let doubleValue = array[i] * 2;
    if (doubleValue > 9) {
      doubleValue -= 9;
    }
    newArray.push(doubleValue);
  }

  for (let j = array.length - 1; j >= 0; j -= 2) {
    newArray.push(array[j]);
  }

  return newArray.reduce((prv, cur) => prv + cur) % 10 === 0;
};

====================
about this line,
return newArray.reduce((prv, cur) => prv + cur) % 10 === 0;
There is nothing different from your code. you can return the expression directly because it’s a boolean.

And of course, you still can write it like that but I think it’s just an unnecessary “if-else” statement:

if (combined.reduce((prv, cur) => prv + cur) % 10 === 0) {
          return true;
        } else {
          return false;
     }
1 Like

You have a few issues. Let’s start here:

What value is ultimately assigned to combined? Log it and see.

I also have a couple of questions.

Why use var in your for loops? Stick with let and const. There’s no need for var.

What is the purpose of your second for loop? All paths inside the loop lead to a return, so there is no repeatable code. It executes only once.

You also have a global definition here: newArray = []. Why?

One last critique. Sloppy formatting and indentation along with inconsistent use of ;'s makes your code more difficult to follow.

1 Like

Hi @midlindner, thanks for all your feedback and constructive criticism.

So, as for the second for loop, should I not place for in front of the var and just declare it as a variable?

I created newArray = [ ] as a global variable because it needs to accessed throughout the code. Was that not the right thing to do?

I’ll be honest. I don’t know when to use ;'s and when not to! I’ll also try harder with formatting and indentation.

The loop could be used to add the values that weren’t doubled as @enghosamokasha suggests, but currently your code doesn’t do that. It looks like you may have intended the line above the loop:
let combined =[].concat(newArray, array[j]); to be inside the loop to add the values. That thought process (the need to include the non-doubled values) is correct, but the implementation is flawed.

Right/Wrong? Who’s to say? Unnecessary? Yes. const is sufficient for the necessary scope (block scope).

Yeah. That is confusing for sure. One approach is to not use them where they aren’t required. That can lead to strange errors when your code is interpreted, but usually not. Here’s an article that may help. You can search for others.

@enghosamokasha has given you a working implementation of your approach to the problem, but I’d encourage you to work through this again. Consider the steps that you would take using a pencil and paper to reduce a credit card number to a single value using the Luhn algorithm, and then write those in code. You have done a good job of identifying what needs to be done, but the steps carried out in your code are a bit out of order.

I have refactored my own code for this project many, many times, and your approach actually gave me an idea I hadn’t had before which led to my new favorite method to date. :slightly_smiling_face:

2 Likes

This topic was automatically closed 41 days after the last reply. New replies are no longer allowed.