Credit Card Checker Challenge Project (JavaScript)

It took around 3 hours for me to complete the task… Everything seems to work well. Here is my code. I only didn’t accomplish the last optional task (Making valid cards out of invalid ones) as I couldn’t figure out what exactly should be done…

Hi, here´s my solution:

I took notes on my process in the README file. It works, but I can still make some improvements.

One thing I’m puzzling about is the return value of findInvalidCards() returns undefined in the console.

I’m wondering if this matters, and if I could either make it not print to the console, or actualy use returned values for the idInvalidCardCompanies function.

Hi, I share my code, for all everyone who want to see it, thanks

Hi ! Here is my solution until point 6.
Your comments are welcomed ! :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: function validateCred(array) { let sum = 0; for (let i=array.length-1; i>=0; i--) { if (i%2===1) { sum += array[i]; } else { let count = array[i]*2; if (count>9) count-=9; sum += count; } } return (sum%10 === 0) ;//? true : false; } console.log(validateCred(mystery5)); function findInvalidCards(array) { return array.filter(p=>!validateCred(p)); } const invalidcards=findInvalidCards(batch); console.log(invalidcards); const findCompany = array => { switch (array[0]) { case 3 : return "Amex (American Express)"; break; case 4: return "Visa"; break; case 5: return "Mastercard"; break; case 6: return "Discover"; break; default: return "Company not found"; break; } } function idInvalidCardCompanies(array) { const result = array.map(findCompany); return result.reduce((a,b) => { if (!a.includes(b)) return a + ', ' + b; return a; }).split(', '); } console.log(idInvalidCardCompanies(invalidcards));

// 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 validateCard(array) {
let num = 0;
let total = 0;
let doubledNum;
for (let i = array.length -1; i>=0; i–) {
if (num % 2 === 0) {
total = total +array[i];
} else if (num % 2 != 0) {
doubledNum = array[i] * 2;
if (doubledNum > 9) {
doubledNum -= 9;
};
total += doubledNum;
}
num += 1;
}

if (total % 10 === 0 ) {
return true;
} else {
return false;
};
}

console.log(validateCard(valid1));

function findInvalidCards(arr) {
let invalidCards = ;
arr.forEach(cardNum => {
if (validateCard(cardNum)) {
} else {
invalidCards.push(cardNum);
};
});
return invalidCards;
};

findInvalidCards(batch);

function idInvalidCardCompanies(array) {
let companiesNcards = ;
let cardObject;
array.forEach(cardNmbr =>{
if (cardNmbr[0] === 3) {
cardObject = [“Amex”, cardNmbr];
companiesNcards.push(cardObject);
} else if (cardNmbr[0] === 4) {
cardObject = [“Visa”, cardNmbr];
companiesNcards.push(cardObject);
} else if (cardNmbr[0] === 5) {
cardObject = [“MasterCard”, cardNmbr];
companiesNcards.push(cardObject);
} else if (cardNmbr[0] === 6) {
cardObject = [“Discover”, cardNmbr];
companiesNcards.push(cardObject);
};
});
return companiesNcards;
}

console.log(idInvalidCardCompanies(findInvalidCards(batch)));

1 Like

That was tough. Here is my solution.

Hello all!
Here’s my solution to the challenge :metal:t3:

Hello friends!
It was fun!) I know nothing Luhn algorithm before.
Check this out!

I need an advise with easy question. There is one thing i can’t understand.

const arr = [1, 2, 3, 4, 5]
const testFunc = num => {
  let test = num
  for(let i = 0; i < test.length; i++) {
    test[i] = test[i] + 2
  }
  return test
} 
console.log(arr) //[1, 2, 3, 4, 5]
console.log(testFunc(arr)) //[ 3, 4, 5, 6, 7 ]
console.log(arr)   //[ 3, 4, 5, 6, 7 ]

why my ‘arr’ was changed? I thought that function will change the variable only when we call this function. And in function i don’t change varriable, I create a new one (test) with the same meaning and change it.
Sorry for this newbee question i think i miss something in explonation.

Hi everyone,

Honestly ChatGPT helped me a lot to solve this challenge.

Hi folks. Linking to my solution below:
https://github.com/DominicBennett/credit-card-checker-challenge.git

I sat for ages staring at a reference error which I just couldn’t see in the switch block. Eventually gave in and asked Chat GPT. It hadn’t a clue the first time I asked. So I started a new chat and asked it again and it caught it first time. ( I’d used the assignment ‘=’ instead of comparator ‘===’ in an ‘if’ statement.

As far as I can see, my code works. I’ve left my various debug lines commented out for posterity or something.

Hi there. I am also a newbie, but it appears the line let test = num does not create a new array, but creates a new reference to the same array.

I tried using map() on your code to create a new array, not just a reference to the first array, and it seems to behave as you had intended.

const arr = [1, 2, 3, 4, 5]
const testFunc = num => {
  //create a new array identical to the array passed, and return it
  let test = num.map(x => x);
  for(let i = 0; i < test.length; i++) {
    test[i] = test[i] + 2
  }
  return test
} 
console.log(arr) //[1, 2, 3, 4, 5]
console.log(testFunc(arr)) //[ 3, 4, 5, 6, 7 ]
console.log(arr)   //[ 1, 2, 3, 4, 5 ]

1 Like

Thanks for support. I also use map(). But everytime I thought that when I create new variable it doesn’t used to be a reference. Now I know.

For a flat array we can generate a copy using, Array.slice(). A multi-dimension array might not be offered the full extent of support by the method. That will take some testing.

As far as Array.map() is concerned, if we want a corresponding AND mutated copy of the array, we can do that in a single step. That for loop is not needed.

test = num.map(x => x + 2)

The only real reason to have a copy of an array is so it can be consumed without affecting the array it was copied from. This would imply some sort of repeated use of the array.

Ultimately our travels through code land are going to expose us to many and varied solutions to the same problem. We will have, in time, to know which one to choose in a given scenario, or at least know the effect that each one has when compared to the other. This is what is really in store for the learner.

Let’s take one last example for a test ride.

a = '4535116024681001'
b = a.split('')
n = b.length % 2
b.forEach(function (x, i, a) {
  if (i % 2 === n) {
    x *= 2
    if (x > 9) {
      x -= 9
    }
  }
  a[i] = +x
})

When we run this, b gets mutated in place, and has the string digits converted to integers, AND we do the doubling and tweaking as well, all in that one pass. We do not mutate the last element of the array (the last digit of the sequence).

console.log(b)
[8, 5, 6, 5, 2, 1, 3, 0, 4, 4, 3, 8, 2, 0, 0, 1]

Now let’s make a one character shorter:

a = '535116024681001'
b = a.split('')
n = b.length % 2
b.forEach(function (x, i, a) {
  if (i % 2 === n) {
    x *= 2
    if (x > 9) {
      x -= 9
    }
  }
  a[i] = +x
})

Let’s see if the last digit is affected:

console.log(b)
[5, 6, 5, 2, 1, 3, 0, 4, 4, 3, 8, 2, 0, 0, 1]

Bottom line, there are a lot of ways to cook an egg.

1 Like

Thank you for examples and explanation

2 Likes

Hey guys! This task was not easy, but I liked it. The most difficult part for me was the last one - getting rid of duplications. Guess my solution is not the best and most beautiful, but it works and I feel really happy about it now. Here’s the link, so please, check it out:)

// 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 findInvalidCards(invalidCardsearch) {
    let invalidCardNum = [];
    for (let i = 0; i < invalidCardsearch.length; i++) {
        if (invalidCardsearch[i] === false) {
            invalidCardNum.push(batch[i]);
        }
    }
    return invalidCardNum;
}

function idInvalidCardCompanies(invalidCards) {
    //console.log(invalidCards)
    //console.log(invalidCards.length
    let firstElement;
    let firstIndex = 0;
    let companyList = [];
    let companyName = ' ';
    let search;
    /*First Digit 	Company
    3 	3-Amex (American Express)
    4 	4-Visa
    5 	5-Mastercard
    6 	6-Discover*/
    for (let z = 0; z < invalidCards.length; z++) {
        firstElement = invalidCards[z][firstIndex];
        //console.log(firstElement);
        switch (firstElement) {
            case 3:
                companyName = 'Amex';
                break;
            case 4:
                companyName = 'Visa';
                break;
            case 5:
                companyName = 'Mastercard';
                break;
            case 6:
                companyName = 'Discover';
                break;
            default:
                companyName = 'Company not Found';
        }
        search = companyList.find(element => element === companyName)
            //console.log(search);
        if (companyName === 'Company not Found') {
            companyList.push(companyName)
        } else if ((companyName !== 'Company not Found') && (search !== companyName)) {
            //console.log(companyName);
            companyList.push(companyName);
        }

    }
    //console.log(companyList);
    return companyList;
}

function validateCred(creditCardNum) {
    //console.log(`A ${creditCardNum.length} digit credit card: `)
    let process = []
    for (let i = creditCardNum.length - 1; i >= 0; i--) {
        //console.log(`element number ${i+1} ${creditCardNum[i]}`);
        if ((creditCardNum.length % 2 === 0) && ((i + 1) % 2 === 0)) { // for even number of digit cards 
            //console.log(`even element: ${i + 1} : ${creditCardNum[i]}`);
            process.unshift(creditCardNum[i]);
        } else if ((creditCardNum.length % 2 !== 0) && ((i + 1) % 2 !== 0)) {
            //console.log(`even element: ${i + 1} : ${creditCardNum[i]}`);
            process.unshift(creditCardNum[i]);
        } else {
            //console.log(`odd element: ${i+1}: ${creditCardNum[i]}`)
            if (((creditCardNum[i] * 2) > 9)) {
                process.unshift((creditCardNum[i] * 2) - 9);

            } else {
                process.unshift(creditCardNum[i] * 2);

            }

        }

    }
    //console.log(process2);
    let sum = process.reduce((accumulator, currentValue) => accumulator + currentValue);
    //console.log(`The sum ${sum}`);
    let result;
    if (sum % 10 === 0) {
        result = true;
    } else {
        result = false;
    }
    return result;
}
let findings = [];
let invalidCardList;
let companyNames;
for (x = 0; x < batch.length; x++) {
    findings.push(validateCred(batch[x]));
}
//console.log(findings);
invalidCardList = findInvalidCards(findings);
companyNames = idInvalidCardCompanies(invalidCardList);
console.log(companyNames);

my solution looks awful hehehehehe