Credit Card Checker Challenge Project (JavaScript)

I used a lengthy technique to add the card companies as I wanted to avoid duplicates as per the instructions. But I noticed a switch statement in the official code.

I also commented out (but left in) many console.log statements I used to find out what my code was doing behind the scenes.

Feel free to examine here:

Please review my work

You can check my solution here!

https://github.com/Siba1993/ValidateCreditCards/blob/main/creditcards

Here is my solution:
Any improvement is welcomed!!

1 Like

Hi @blopezpi
I just finished this project and broke my head about the validateCard extra function. I found a solution (https://discuss.codecademy.com/t/credit-card-checker-validate-cards/576841), but I don’t think it’s very elegant.
Would you mind telling me, what’s the idea behind yours?
I get that you store the returned rest of the sum % 10 (excluding the last digit) from the validateCred function and append it to the invalid card array. That increases the number of digits in most cards to 17. But why would it always pass the Luhn check if you get the rest excluding the last digit and append it to the card number?

Hi @mirja_t,
I refactored the code: https://gist.github.com/401dcd62b958f3756d87bb849fb94369
The function validateCred have two parameters, and it depends if valid is true or false. It is true it will try to validate the Luhn algorithm, otherwise, if the value of valid parameter is false this is used to transform the invalid credit cards into valid credit cards. I remove the last digit for this only because I can calculate the value to convert the invalid card into a valid one. I made some calculations at hand and I see different behavior in cards with odd length number.
I would try to refactor to remove the loops.

Thank for answering @blopezpi
I think I got what you’re doing there, just not really why you’re doing it: You get the rest from the Luhn checking function once the second parameter is set to false. Then you move all digits to a new array and append the rest value to it. But since you don’t take the last digit into the calculation, how do you know that the new array would pass the test?
My intention is indeed to refactor the function and get rid of the loops. What I do here is just alter single digits by one until it passes the test, without knowing in advance when it will. That’s why I’m asking for the logic behind your function. You seem to have some math masterplan behind it I don’t get yet.

Hi @mirja_t,
I don’t create any array in this function. I just sum all the numbers for the credit card. And I test if the result is divisible by 10. I don’t know if reduce will work here, maybe with callback function to check it if index is divisible by 2 you need to multiply it. Let me check it. There isn’t any math masterplan.
The first loop do a loop without the last digit (this is used to multiply it by 2) and sum into the result variable (I will jump by 2 in the array). The second loop is only to sum it, I removed the two last values and make it (in this one I will jump by 2 too). I don’t know if you understand my explanation.

1 Like

Hi @mirja_t,
I test my project with reduce array function and here you can see the result: https://gist.github.com/bf6d1266f83231a729eb9ab68d3cc061

1 Like

Hey @blopezpi
thanks for your effort! But unfortunately I still don’t get how you know that your rectified card will pass the test when you ignore the last digit in your calculation (or maybe you don’t and it’s a misunderstanding).
But I found a solution that works without a loop and therefore is a lot simpler and lighter than my initial version. Also it’s much closer to my original idea (and yours, I guess).
In contrast to your solution, I don’t add a digit to the card number and get the rest value from the whole invalid card number after Luhn check. Then I subtract the rest from the last digit and if it’s below 0, I add 10. So easy. Spent ages missing the forest through the trees :woman_facepalming:
Thanks again for your patience!

1 Like

Hi @mirja_t,
Ahh ok, I will explain why I remove the last digit. This digit is the check digit and I don’t need in the result variable, because the only thing that I need is to change the last digit of the credit card. So I take the result in a variable and try to make divisible by 10. ¿How? I get the mod of the division and do a subtraction by 10 to know what digit is necessary to get the result divisible by 10. In your case you can get the same doing a subtraction of the last element of the array and do the same operation. But I see you get it. Congrats!

1 Like

Hi there!!! I dont know if anyone will ever read this, but this is my first time publishing something on Github :relaxed:

Im 37 years old and I love codecademy!!! I will start publishing all the other things I have on the computer, even if I dont have too many :crazy_face:

Here is my solution

// 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=(arr)=>{
  let evenIndex =0;
  let oddIndex =0;
  let everySecondItem = arr.filter((element, index)=>{
    return index % 2 ===0;})
  let whatsLeft = arr.filter((element, index)=>{
    return index % 2 !==0;});
  for(let i= 0;i<whatsLeft.length;i++){
      oddIndex+=whatsLeft[i];
    } 
  for(let i= 0;i<everySecondItem.length;i++){
    if((everySecondItem[i]*2) > 9){
      evenIndex+=((everySecondItem[i]*2)-9);
    }else{
      evenIndex+=(everySecondItem[i]*2);
    }
  }
  if((evenIndex+oddIndex)%10 === 0){
    return true;
  }else{
    return false;
  }
}

const findInvalidCards=(arr)=>{
  let returnedTrue = [];
  for(let i = 0;i<arr.length;i++){
    if(!validateCred(arr[i])){
      returnedTrue.push(arr[i]);
    }
  }
  return returnedTrue;
}
const invalidCards = findInvalidCards(batch);
const idInvalidCardCompanies=(arr)=>{
  let companiesArray = [];
  for(let i =0;i<arr.length;i++){
    if(arr[i][0]===3){
      companiesArray.push('Amex (American Express)');
    }else if(arr[i][0]===4){
    companiesArray.push('Visa');
    }else if(arr[i][0]===5){
    companiesArray.push('Mastercard');
    }else if(arr[i][0]===6){
    companiesArray.push('Discover');
    }
  }
  var uniq = companiesArray.reduce(function(a,b){
    if (a.indexOf(b) < 0 ) a.push(b);
    return a;
  },[]);
  return uniq;
}

This was definitely challenging for me but I felt victorious when I finished it.

Hi,

Credit Card Checker- Luhn algorithm;

I am wondering if anyone can help. I am struggling to understand the concept of this for loop and how it gets every other number from the array in reverse. The bit of code that i do not understand is ; " if ((numArr.length - 1 - i) % 2 === 1) {
currValue *= 2;"

The code works fine, but when i do the math myself, it does not work out. Here is how i am trying to calculate it in my head;

let randomArray = [1,2,3,4,5,6,7,8,9,]

1st loop 9(numArr.length)- 1 - 8(i) =0 then % 2 = 0
2nd loop 9(numArr.length)- 1 - 7(i) =1 then % 2 = 0
3rd loop 9(numArr.length)- 1 - 6(i) =2 then % 2 = 0 My calculations show this as 0, but the code is working which i do not understand? For the code to double this, it should be equal to 1.

Any help is much appreciated. The code is from the function below.

function validateCred(numArr) {

let total = 0;
for (let i = numArr.length - 1; i >= 0; i–) {
let currValue = numArr[i]
if ((numArr.length - 1 - i) % 2 === 1) {
currValue *= 2;
if (currValue > 9) {
currValue -= 9;
}
}
total += currValue;

}

return total % 10 === 0;

}

Hi @blog0488538318
I think there’s a misunderstanding of the modulo (%) operator:

% returns the rest value of a division:

console.log(0 % 2); // prints 0 --> 0 % 2 === 1 --> false
console.log(1 % 2); // prints 1 --> 1 % 2 === 1 --> true --> function executed
console.log(2 % 2); // prints 0 --> 2 % 2 === 1 --> false

I now understand this :slight_smile:
Thank you so much!

1 Like

My Solution: CreditCardChecker/main.js at master · ItsTheBravo/CreditCardChecker (github.com)