Help with Step 3 in Credit Card Checker task

Hey forum!

I am currently working through the Credit Card Checker task but have been unable to solve step 3. The code below works for the following array (which i changed to test my code against the visual guide provided). I think there is an issue with my if/else statements but i haven’t been able to work it out. Any help or steer on what i am doing wrong would be greatly appreciated! Thanks in advance :slight_smile:


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

const validateCred = arr => {
  let arr_new = []
  for (i = 0; i < arr.length; i++) {
  arr_new[i] = arr[i];
  }

  let new_arr = [];
  for (let i = arr_new.length-1; i >= 0; i --)  
  {
    if (i % 2 !== 0) {
      if((arr_new[i] * 2) > 9) {
        new_arr.push((arr_new[i] * 2) - 9)
      } 
      else { 
        new_arr.push(arr_new[i] * 2) 
      }
    } 
    else {
      new_arr.push(arr_new[i]) 
    }
  }
  console.log(arr_new)
  console.log(new_arr);

  let count = 0;
  for (let j = 0; j < new_arr.length; j++){
  count += new_arr[j]
  }
  console.log(count)
  
  if (count % 10 === 0){
  console.log("Card is valid")
  } else {
  console.log("Card is invalid")
  }
}

validateCred(valid1)  - comes back as valid
validateCred(valid2) - comes back as invalid

Thanks

Hi @design1243427263

please add a link to the lesson/project as well. That makes it easier to understand the task.
If I remember the Luhn algorithm correctly, you should double every other digit, omitting the last digit.
That is not what you do. Since you started your loop from the end of the array and check if i is odd, it is out of your control if you include the check digit or exclude it. If the amount of digits is odd, you start doubling the second digit from the right – which is correct. If the amount is even, you start doubling the first digit from the right – which is the check digit.
Both ‘valid1’ and ‘valid2’ have an even amount of digits. Let’s have a look:

arr_new.length - 1 is 15.

15 % 2 !==0 is true.
If you take a look at the output of your console.log(arr_new) you’ll see that the last digit has changed.

Hi Mirja_t,

Thank you very much for taking the time to respond to my query. Apologies the link to the project is here:

https://www.codecademy.com/paths/full-stack-engineer-career-path/tracks/fscp-javascript-syntax-part-ii/modules/fecp-challenge-project-credit-card-checker/projects/credit-card-checker

A visual illustration can also be found here: https://content.codecademy.com/PRO/independent-practice-projects/credit-card-checker/diagrams/cc%20validator%20diagram%201.svg

I understand the point you made around the odd/even difference but I am still having trouble understanding how to resolve as the solution works for Valid1 which is the same length as Valid2(both 16). In order to miss out the last element, i’ve tried to use "let i = arr_new.length - 2; i -= 2 and then an if statement checking if i % 2 != 0 but still not receiving the right result (perhaps as it doesn’t include the last item?). Any further example would be appreciated as the above was very helpful. Thank you

Hey,

count in your function is 100 for the first card. That passes the test ‘count % 10 === 0’. But that is just a coincidence. If everything is done correctly, count is 80.

That would mean that in case of an array with an even amount of digits you start doubling the 3rd digit from the right because i is even (14) when you reached the second digit from the right and therefore wouldn’t pass the test if (i % 2 !== 0).

Example:
valid1 has an amount of 16 digits.
arr_new.length-2 is 14. (arr_new[14] is the second digit from the right that should be doubled)
14 % 2 !== 0 (fails the test and isn’t doubled)
13 % 2 !== 0 (passes the test, but is the 3rd digit from the right)

Therefore, with your approach, you would have to find a way to check whether the array has an even or an odd amount of digits and adjust the condition (currently: if (i % 2 !== 0)) depending on the length of the array.

Extra hint

For example
If it is even:
if (i % 2 === 0)
and if it is odd:
if (i % 2 === 1)

This would result in a lot of code. You could try to find a way where you would not have to start the loop from the end.

Hi there,

Having read the above i have tried to accommodate for different lengths of array with the following code:

Const validateCred = arr => {
  let arr_new = arr.reverse()

  let new_arr = [];
  for (let i = arr_new.length-1; i >= 0; i --)  
  { if ((i + 1) % 2 === 0) {
      if (i % 2 !== 0) {
        if((arr_new[i] * 2) > 9){
          new_arr.push((arr_new[i] * 2) - 9)
      } else { 
        new_arr.push(arr_new[i] * 2) 
      }
    } 
    }
    else {
      if ((i + 1) % 2 !== 0) {
        new_arr.push(arr_new[i]) }
      }
   }

I’ve added a check for the length of array but do not get a full set of correct results - any further help would be appreciated!

Thank you

Hey,
if you stick with your former approach (without reversing the array), you will have to check whether the array itself has an even or odd amount of digits – not the position of each digit.
That means that you need to check if new_arr.length is even or odd. And you need to do that just once for each card array – outside the loop.
If you reverse the array, you don’t need to do that distiction at all – that’s what I meant with finding a way where you would not have to start the loop from the end. That would be a different approach.
If you follow that make sure that you make a copy of the array first: the .reverse() method mutates the original array.

Hi Mirja_t,

Thank you for coming back on this. I’ve put together the below based on your advice about not reversing the original array etc:

const validateCred = arr => {
  let arr_new = []

  for (i = 0; i < arr.length; i++) {
  arr_new[i] = arr[i];
  }

  let new_arr = [];

  if (arr_new.length % 2 === 0) {
    for (let i = arr_new.length-1; i >= 0; i--)  
  {
    if (i % 2 === 0) { 
      if ((arr_new[i] * 2) > 9){
        new_arr.push((arr_new[i] * 2) - 9)
      }
      else {
        new_arr.push(arr_new[i] * 2)
      }
    else {
      new_arr.push(arr_new[i])

Is this along the lines of what you were suggesting - i.e run the for loop after checking the length of the array? Would you be able to give a stronger steer if possible please?

I’m a little bit unclear on this as that array is empty before the for loop is run? Thanks again for taking the time to help me on this

This is going in the right direction, have you finished that? If you did, could you post the complete code because from this part of your code, I cannot tell where it’s going wrong.

If you completed that, it’ll be very long. I would recommend that you follow the other approach (reversing the array), too. With that approach, you don’t have to check the array length and your code will be more concise. But I think it would be a good practice to finish both.

You run the length check and the loop with this array: arr_new
By the time you run it, it’s not empty anymore because you filled it before with this loop:

I have put together the below but seem to get card invalid when testing Valid1 array.

const validateCred = arr => {
  let arr_new = []

  for (i = 0; i < arr.length; i++) {
  arr_new[i] = arr[i];
  }

  let new_arr = [];

  if (arr_new.length % 2 === 0) {
    for (let i = arr_new.length-1; i >= 0; i--)  
  {
    if (i % 2 === 0) { 
      if ((arr_new[i] * 2) > 9) {
        new_arr.push((arr_new[i] * 2) - 9)
      }
      else {
        new_arr.push(arr_new[i] * 2)
      }
    }
    else {
      new_arr.push(arr_new[i])
    }
  }
 }
  
  console.log(new_arr)
  let count = 0;
  for (let j = 0; j < new_arr.length; j++){
  count += new_arr[j]
  }
  console.log(count)

  if (count % 10 === 0){
  console.log("Card is valid")
  } else {
  console.log("Card is invalid")
  }
}

validateCred(valid1)

Output:

[ 4, 1, 3, 9, 6, 7, 9, 7, 8, 5, 7, 0, 5, 5, 9, 7 ]
92
Card is invalid

Ok, I will look back on this approach once current approach works. Thanks for looking.

Hi,
two things I observe:

  1. I don’t know if the card ‘valid1’ from your first post is a valid card, indeed. The card I have as ‘valid1’ in my sandbox looks different:
    const valid1 = [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8];.
    And when I run your code with that, it logs: “Card is valid”. count is 80.
  2. I assume you are aware that your code now only works for arrays with an even amount of digits, right? You still need to do the ‘else’ condition.

Hi Mirja_t,

Apologies i had realised this and was in the middle or replying to your comment, i’ve changed the array back and added in the else condition and it is now all working correctly.

Thanks again for taking all the time to help me with this!

1 Like