Credit card checker, valid1 returns invalid

Here is my code:

// 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:
function validateCred(cardArray) {
  var lastElement = cardArray.pop();
  var reversedArray = cardArray.reverse(lastElement);
  for (var i = 0; i < reversedArray.length; i++) {
    if (cardArray[i] % 2 === 0) {
      cardArray[i] *= 2;
      if (cardArray[i] > 9) {
        cardArray[i] -= 9;
      }
    }
  };

  var newCardArray = eval(cardArray.join('+'));
  var sum = newCardArray + lastElement;
  console.log(sum)
  if (sum % 10 === 0) {
    console.log('Valid');
  } else {
    console.log('Invalid');
  }
};

validateCred(valid1);

Executing validateCred(valid1); returns invalid
I can’t figure out why is returning invalid, when the code is doing what’s supposed to do. I have the feel it might be something trivial, but can’t seem to find the issue.

Could you guys provide any guidance?

Thanks!

Hello, @keyboardtank.

Your implementation of the Luhn algorithm has a few issues. Before even getting into that, keep in mind that you should not be mutating the original array (card number), so the first step would be to make a copy of the array. After that, try going through your code with a paper and pencil. Take the array valid1, and perform the operations in your validateCred function on it manually.

One last thing. What’s with all the var's?

Okay, one more thing to consider:

The reverse() method takes no arguments.
See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reverse

This might be worth a gander as well https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval#Never_use_eval!

1 Like

I managed to get it to work, after a few tweaks. getting the first “if” right was the tricky part. Thanks for your help.

Here is the new code, for anyone interested:

function validateCred(cardArray) {
  let copyCardArray = cardArray;
  let lastElement = copyCardArray.pop();
  let reversedArray = copyCardArray.reverse();
  for (let i = 0; i < copyCardArray.length; i++) {
    if (i % 2 === 0) {
      copyCardArray[i] *= 2;
      if (copyCardArray[i] > 9) {
        copyCardArray[i] -= 9;
      }
    }
  }
  const reducer = (accumulator, currentValue) => accumulator + currentValue;
  let newCardArray = copyCardArray.reduce(reducer);
  let sum = newCardArray + lastElement;
  console.log(sum)
  if (sum % 10 === 0) {
    console.log('Valid');
  } else {
    console.log('Invalid');
  }
};
1 Like

Nice job! However, you are still mutating the original array.

This creates an additional reference to the same array, but does not make a copy.
For example:

const a = [1, 2, 3]
const b = a
b[1] *= 2
console.log(a) //[1, 4, 3]

The array assigned to a is changed. Both a and b refer to the same array. We can use the .slice() method to make a copy.

const a = [1, 2, 3]
const b = a.slice() //if we leave out the optional arguments, 0 and a.length are used by default, so we get a copy of the whole array
b[1] *= 2
console.log(a) //[1, 2, 3]
console.log(b) //[1, 4, 3]
2 Likes

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