Credit Card Checker Challenge Project (JavaScript)

Hi, below is my solution on Github:

Credit Card Checker

I made the function findInvalidCards use both of the other functions so they do not need to be called individually.

I realise compared to the solution I could have condensed the code a little. Any other feedback appreciated :slight_smile:

Thanks!

// 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) => { let arr = array.slice(); let sum = 0; let digit = arr[arr.length - 1]; for (let i = arr.length - 1; i >= 0; i--) { if (i % 2 === 0) { arr[i] = arr[i] * 2; if (arr[i] > 9) { arr[i] -= 9; } } else { } } for (let i = 0; i < arr.length; i++) { sum += arr[i]; } if (sum % digit === 0) { return true; } else { return false; } }; const findInvalidCards = (array) => { let invalidArray = []; let validArray = []; array.forEach((arr) => { if (validateCred(arr)) { validArray.push(arr); } else { invalidArray.push(arr); } }); console.log("valid:"); console.log(validArray); console.log("Invalid:"); console.log(invalidArray); return invalidArray; }; const idInvalidCardCompanies = (array) => { let cardCompanies = []; for (const card of array) { let firstDigit = card[0]; let companyName; switch (firstDigit) { case 3: companyName = "Amex (American Express)"; break; case 4: companyName = "Visa"; break; case 5: companyName = "Mastercard"; break; case 6: companyName = "Discover"; break; default: console.log('Company not found'); continue; } if (!cardCompanies.includes(companyName)) { cardCompanies.push(companyName); } } return cardCompanies; }; //console.log(validateCred(valid3)); //findInvalidCards(batch); console.log('Cards: ' + idInvalidCardCompanies(findInvalidCards(batch)));

Ktotz

Hello guys, I have spent quite a few hours on this project and finally came up with my solution. Please kindly check it out here and let me know how I can improve/refactor my code.

I found the first function most challenging to me. When I finally completed the first function, it’s already so long! I had to separate every step clearly. Therefore, I have added some comments to clarify my thought process and hope for better readability. Thank you!

Hi everyone, I’m a bit stuck on this project, and wonder if anyone can provide a bit of assistance, I’ve tried looking through some official documentation and everything and am still a bit confused.

Around the part of creating the validateCred() function of this assignment that uses the Luhn algorithm. My first instinct for this problem is to loop over the array backwards, using the length property

for (let i = arr.length - 1; i > 0; i--)

, however the constraint of doubling every other number is a bit confusing to me

Given that only every other is changed, what happens if we revise the increment to,

i -= 2

?

This will necessitate,

let i = arr.length - 2; i -= 2
1 Like

I had not thought about this, I guess if the increment is changed to - 2, it would go to every other index in the array instead.

1 Like

Note also where we start, arr.length - 2 so we skip the last element of the array.

1 Like

Good tips, thank you!

1 Like

Here is what I come up with for this project


Here is my project without the extra challenges

Please tell me what you guys think
Thanks

Did you validate your own credit card with this? If not, then did you validate a known active credit card? Sadly, that is the only way to be absolutely sure our code works. It is, after all, a credit card validity checking program.

// Web Development Foundations - Challenge Project: Credit Card Checker // 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 = (card) => { const len = card.length; let sum = 0; for (let i = len - 1, currentPos = 1; i >= 0; i--, currentPos++) { let digit = card[i]; // double every other number // from last(which is pos:1): double every even digit if (currentPos % 2 == 0) { digit *= 2; // subtract 9 if greater than 9 digit -= digit > 9 ? 9 : 0; } sum += digit; } return sum % 10 === 0; }; function findInvalidCards(arr) { return arr.filter((c) => !validateCred(c)); } function idInvalidCardCompanies(invalidCards) { const companies = { 3: "Amex (American Express)", 4: "Visa", 5: "Mastercard", 6: "Discover", }; const issuers = []; invalidCards.forEach((c) => { const firstDigit = c[0]; if (companies.hasOwnProperty(firstDigit)) { // add only once if (!issuers.includes(companies[firstDigit])) { issuers.push(companies[firstDigit]); } } else console.log("Company not found"); }); return issuers; } // TEST 1 const invalidCards = findInvalidCards(batch); const invalidCardIssuerCompanies = idInvalidCardCompanies(invalidCards); console.log('invalid card issuer companies:',invalidCardIssuerCompanies); // TEST 2 : 5 invalid + 3 invalid mystery card console.log('Total Invalid Cards: ',invalidCards.length) //8 // console.log([mystery1,mystery2,mystery3,mystery4,mystery5].map(validateCred)) //3 invalid card

I guess every companies issued invalid cards

Here’s my solution to this challenge project:

I checked it against a real credit card and it correctly validated
it

1 Like

Hi everyone! Hope you all are ok and improving in your code journey.

I have reached to finish this exercise some minutes ago and here is my answer. If anyone could give me some feedback it would be really appreciated :slight_smile:

// 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 => {
    const finalNumber = array.reduceRight((accumulator, checkNumber, index) => {
        let value = checkNumber;
        //console.log('Este es el checkNumber: ' + checkNumber);
        //console.log('Este es el accumulator: ' + accumulator);
        //console.log(array.length - 1 - index)
        if ((array.length - 1 - index) % 2 !== 0) {
            value *= 2;
            //console.log('Este es valor de los números impares: ' + value);

            if (value > 9) {
                value = value - 9;
            }
        }
        //console.log('Esta es la suma: ' + (accumulator + value));
        const newAccumulator = accumulator + value;
        return newAccumulator;
    });
    //console.log(finalNumber)
    //console.log(finalNumber % 10 === 0);
    return finalNumber % 10 === 0;
};


validateCred(valid1);

const findInvalidCards = nestedArray => {
    const invalidCards = nestedArray.filter(array => {
       const finalNumber = array.reduceRight((accumulator, checkNumber, index) => {
            let value = checkNumber;
            //console.log('Este es el checkNumber: ' + checkNumber);
            //console.log('Este es el accumulator: ' + accumulator);
            //console.log(array.length - 1 - index)
            if ((array.length - 1 - index) % 2 !== 0) {
                value *= 2;
                //console.log('Este es valor de los números impares: ' + value);

                if (value > 9) {
                    value = value - 9;
                }
            }
            //console.log('Esta es la suma: ' + (accumulator + value));
            const newAccumulator = accumulator + value;
            return newAccumulator;
        });
        //console.log(finalNumber)
        //console.log(finalNumber % 10 === 0);
        return finalNumber % 10 === 0;
    })
      //console.log(invalidCards);

        return invalidCards;
};

const invalidCardsChecked = findInvalidCards(batch);
//console.log(invalidCardsChecked)

const idInvalidCardCompanies = (nestedArray) => {
  const companiesWithInvalidCards = [];
  
  const findFirstElement = nestedArray.forEach(array => {
    const copiedArray = [... array];
    const firstElement = copiedArray.shift();

    if (firstElement === 4 && companiesWithInvalidCards.some(element => element === 'Visa') !== true) {
      companiesWithInvalidCards.push('Visa');
    } else if (firstElement === 3 && companiesWithInvalidCards.some(element => element === 'Amex (American Express)') !== true) {
      companiesWithInvalidCards.push('Amex (American Express)');
    } else if (firstElement === 5 && companiesWithInvalidCards.some(element => element === 'Mastercard') !== true) {
        companiesWithInvalidCards.push('Mastercard');
    } else if (firstElement === 6 && companiesWithInvalidCards.some(element => element === 'Discover') !== true) {
       companiesWithInvalidCards.push('Discover');
    }

  });
  console.log(`This are the companies with invalid credit cards: ${companiesWithInvalidCards}`)
  return companiesWithInvalidCards;
};

//idInvalidCardCompanies(invalidCardsChecked);

//Convertion of a credit card number string into an array
const convertStringToArray = string => {
  const stringToArray = Array.from(string).map(number => parseInt(number));
 
  return stringToArray;
};

//convertStringToArray('456326532623232');

Cheers and keep pushing,
Sergio

I mean a win is a win