Credit Card Checker - Help needed

I’ve been struggling getting over this problem I have with my code, for some reason every input arrays total sum adds up to 69 for some reason.

I.e:

const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];
&
const invalid1 = [4, 5, 3, 2, 7, 7, 8, 7, 7, 1, 0, 9, 1, 7, 9, 5];

Would add up to 69 if all the odd numbers were multiplied by two and all numbers over 9 were subtracted by nine. I was wondering if anyone could see where I went wrong in my code:

const reducer = (accumulator, currentvalue) => accumulator + currentvalue;

let arr = valid1;
validateCred = (arr) => {
  nDigit = arr.pop(0, -1);
  arr = arr.slice(0, -1);
  arr.reverse();
  for (let i = 0; arr.length > i; i++){
    digit = arr[i];
    if (digit % 2 !== 0){
      arr[i] = digit * 2;
    }
    if (arr[i] > 9){
      arr[i] = arr[i] - 9;
    }
  }  
  sum = arr.reduce(reducer);
  console.log(sum);
}

I would start by adding console.log() statements after your variable assignments to see if the values match what you’re expecting. You should also get into the habit of declaring variables using const or let rather than giving them all global scope.

Thank you!!

I’m a complete dumbass, the reason my output was always the same was that I declared the arr = as another array (before the validateCred function start) but when I called the function I used the same array everytime. Thank you for the help, will start reducing the amount of global variables I declare from now on.

Also keep in mind how the Luhn algorithm should be used. You want to start from the right, so reversing the array is fine rather than working from right to left, then you want to skip the ‘check digit’ which is the last digit in the number, and double the value of every other digit beginning with the next to last digit. That in mind, is there really any reason to pop() the last digit from the array? What if we just skip it like we do the other none doubled digits?

One last thing:

We want to double values based on their index not on whether or not the digit itself is even or odd.

Yes, I was following this website: https://www.freeformatter.com/credit-card-number-generator-validator.html#howToValidate

Linked in the codeecademy prerequisites however I see now that there are differences between what that links says to do and what the actual project wants me to do. However I now have a new updated code but there is still an error somewhere because the valid numbers aren’t recognized as valid.

const reducer = (accumulator, currentvalue) => accumulator + currentvalue;

validateCred = (arr) => {
  nDigit = arr.pop();
  arr = arr.slice(0, -1);
  arr.reverse();
  for (let i = 0; arr.length > i; i++){
    if ((i + 1 )% 2 === 0){
      arr[i] = arr[i] * 2;
    }
    if (arr[i] > 9){
      arr[i] = arr[i] - 9;
    }
  }
  sum = arr.reduce(reducer);
  if ((sum + nDigit) % 10 === 0){
    console.log('True');
    return true;
  }
}

I don’t see where the code goes wrong, and I’ve checked various spots for the correct output and they all seem to be what I expected but something somewhere must have gone wrong, because multiple valid arrays are not being recognized.

Ohh yes the pop thing might actually not be worth even having inside the code now when you mention it, will try to remove it and see how it goes int he future code, thanks for that tip! :smiley:

Hey Chip - I am totally and utterly confused by this project… and I don’t even know where to start!!! would you be able to talk me through the code you have written??

The above actually removes the last 2 digits, before you run the Luhn algorithm. Keep in mind, that using arr.pop() at this point is changing the original array.

I find that carrying it out manually and studying what I end up doing is often a good guide. Pick some small corner of the problem to chip away at and when it’s done pick another.

So here is the updated code I changed the for loop a bit and added comments to make it easier to read. I got all the valid arrays except valid3 to print out that it’s true. And I got all invalid elements except invalid3 to print out that it’s false.

So I’m not sure how that happens, I even tried doing the math with valid3 manually and I also got i to false.

Here is the valid3 array: [3, 7, 1, 6, 1, 2, 0, 1, 9, 9, 8, 5, 2, 3, 6];

Here is the invalid3 array: [3, 7, 5, 7, 9, 6, 0, 8, 4, 4, 5, 9, 9, 1, 4];

Here is the code:


// Function to all array elements together
const reducer = (accumulator, currentvalue) => accumulator + currentvalue;

validateCred = (arr) => {

  // Removes last digit and stores the last digit in the array to nDigit 
  nDigit = arr[arr.length - 1];
  arr = arr.slice(0, -1);

  /* Checks integers if they are in an odd position or if they equate to a number over 9 */
  for (let i = arr.length - 1; i >= 0; i--){
    if (i % 2 === 0){
      arr[i] = arr[i] * 2;
    }
    if (arr[i] > 9){
      arr[i] = arr[i] - 9;
    }
  }
  console.log(arr);
  // Adds the integers in the array together
  sum = arr.reduce(reducer);

  /* Checks if the array is valid, if the remainder of array sum + the last digit of the array divided by ten is zero then it's valid otherwise its not */
  if ((sum + nDigit) % 10 === 0){
    console.log('True');
    return true;
  }
}
validateCred(valid3);

Sorry for taking so long to get back to this. If you’ll notice, both valid3 and invalid3 have something in common with each other that is different from all of the other arrays. They are one digit shorter. With the way you’ve written your algorithm, it fails on these 2 arrays because the wrong digits are being doubled, etc. Since you’ve decided to iterate from the left, rather than checking the index for being even or odd, you can simply start with the last digit (after removing nDigit as you have), and skip every other digit like so:

  for (let i = arr.length - 1; i >= 0; i-=2){ //i's initial value is the last element in the array, and will skip every other digit since we decrement by 2
    arr[i] = arr[i] * 2; //no need to test the value of the index, so we just proceed
    if (arr[i] > 9){
      arr[i] = arr[i] - 9;
    }
  }

Your code as written worked with the remaining arrays due to their length. Another option would be to reverse the array after making the copy. Then you’d also be doubling the correct digits regardless of the length of the array. arr = arr.slice(0, -1).reverse();

Ok! thank you so much for all the help! :smiley:

1 Like

You’re very welcome.

thanks!! Yep… been trying that… lots!! but thanks for the support!

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