Credit card checker luhn algorithm javascript - javascript

I'm currently making a credit card checker(Luhn algorithm) from the Codecademy project but my function does not seem to work, because it gives me back "false" with an array that has to return "true"(valid3). Can anyone helps me?
// 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];
// An array of all the arrays above
const batch = [valid1, valid2, valid3, valid4, valid5, invalid1, invalid2, invalid3, invalid4, invalid5];
// Add your functions below:
function validateCred(arr) {
let reverseArr = arr.reverse()
let sum = 0;
for (let i = 0; i < reverseArr.length; i += 2) {
sum += reverseArr[i];
sum += reverseArr[i + 1] * 2;
if (reverseArr[i + 1] * 2 > 9) {
sum -= 9;
}
}
if (sum % 10 === 0) {
return true
} else {
return false
}
}
function findInvalidCards(arr000) {
let invalidArr = []
for (let j = 0; j < arr000.length; j++) {
if (validateCred(arr000[j]) === false) {
invalidArr.push(arr000[j])
}
}
return invalidArr;
}
let arr = [4, 5, 5, 6, 7, 3, 7, 5, 8, 6, 8, 9, 9, 8, 5]
let arr1 = 6
console.log(validateCred(valid3))
console.log(findInvalidCards(batch))

valid3 has an odd number of elements so reverseArr[i + 1] becomes undefined in validateCred. Perhaps you can check that reverseArr[i + 1] has a value before adding it to the sum:
// 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];
// An array of all the arrays above
const batch = [valid1, valid2, valid3, valid4, valid5, invalid1, invalid2, invalid3, invalid4, invalid5];
// Add your functions below:
function validateCred(arr) {
let reverseArr = [...arr].reverse()
let sum = 0;
for (let i = 0; i < reverseArr.length; i += 2) {
sum += reverseArr[i];
if(reverseArr[i + 1]) { // Check reverseArr[i + 1] has a value
sum += reverseArr[i + 1] * 2;
if (reverseArr[i + 1] * 2 > 9) {
sum -= 9;
}
}
}
return sum % 10 === 0;
}
console.log(batch.map(validateCred))

Here is my JavaScript port of our server side algorithm:
function luhnCheck(s) {
// Strip the dashses and other garbage
let ccNumber = s.replace(/[^0-9]/g, '');
// We need at least 14 digits for a valid card number
// Check for a blank string because it would return true
if (!ccNumber || ccNumber.length < 14) return false;
if (ccNumber.length == 14 && !ccNumber.matches(/^3(?:0[0-59]{1}|[689])[0-9]{0,}$/)) return false;
let sum = 0;
let alternate = false;
for (let i = ccNumber.length - 1; i >= 0; i--) {
let n = parseInt(ccNumber.substring(i, i + 1));
if (alternate) {
n *= 2;
if (n > 9) {
n = (n % 10) + 1;
}
}
sum += n;
alternate = !alternate;
}
return (sum % 10 == 0);
}

Related

Trying to find the correct syntax for an when I need to take an if statement and check if the results are > 9 then add another if statement

I am doing a project for codecademy and am a little stuck on the syntax among other things ;). I am trying to reverse iterate an array and as I iterate to the left I need to double every other digit THEN check to see whether those numbers are greater than 9 after doubling them. THEN subtract the doubled number by 9. Any help would be much appreciated! This is my code so far
// 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(arr) {
for (let i = arr.length - 2; i >= 0; i--)
if(i % 2 === 0) {
arr[i] = arr[i] * 2;
} else if (i % 2 === 1) {
arr[i]
}
}
arr[i] by itself doesn't do anything, so you can just leave out the else statemennt.
After doubling the number, use an if statement to check if it's higher than 9.
function validateCred(arr) {
for (let i = arr.length - 2; i >= 0; i--) {
if (i % 2 === 0) {
arr[i] *= 2;
if (arr[i] > 9) {
arr[i] -= 9;
}
}
}
}

Credit Card validator - issue making function that checks if credit card arrays are valid

https://pastebin.com/cxjqS1TZ
[Hello fellow engineers. I have been on the codecademy credit card challenge (code on pastebin link) and I have been unable to figure out why the findInvalidCard function does not work. I have tried everything up to the scope of what I have learned so far, which is all we are supposed to use for this challenge, and I fail to find the error.
PS: sorry if I formatted this post incorrectly, I am brand new to programming and this is my first Stacks Overflow question. ]
Here is the link to the instructions
https://pastebin.com/EjW2S2BQ
[Thanks a lot, and please leave feedback as to how I can improve my question posts on the platform.]
"use strict";
// 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:
// let [index, ...batchEle] = batch;
///Step 3
// console.log(batchEle);
let sumNewArr = 0;
const validateCred = (arr) => {
let newArr = [];
for (let i = arr.length - 1; i >= 0; i--) {
if (i % 2 === 0) {
arr[i] *= 2;
if (arr[i] > 9) arr[i] -= 9;
newArr.push(arr[i]);
} else if (i % 2 === 1) {
newArr.push(arr[i]);
}
}
newArr.forEach((sum) => {
sumNewArr += sum;
//console.log(sumNewArr);
});
if (sumNewArr % 10 === 0) {
return true;
} else {
return false;
}
};
// console.log(validateCred(valid4));
let invalidCards = [];
const findInvalidCards = (badArr) => {
for (let i = 0; i < badArr.length; i++) {
if (validateCred(badArr[i]) === false) {
invalidCards.push(badArr[i]);
}
}
// console.log(badArr);
return invalidCards;
};
console.log(findInvalidCards(batch));
// console.log(validateCred(invalid1));
//valid 4
//mystery 3

How can I keep the return value of a function as a nested array?

I'm coding a program using the Luhn Algorithm to check for valid and invalid credit card numbers. These numbers are single arrays but you can batch them inside a nested array. What I'm trying to do is reverse their order, then save them inside an array called reversedNumbers (this is a nested array as well), after that I've tried to do the following but the result is not what I wanted since the return value is a single array not arrays nested inside an array.
CODE BELOW:
// 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 = arry => {
let reversedNumbers = [];
let newArray = [];
for (let i = 0; i < arry.length; i++) {
reversedNumbers.push(arry[i].slice().reverse());
}
//return console.log(reversedNumbers);
for (let j = 0; j < reversedNumbers.length; j++) {
for (let k = 0; k < reversedNumbers[j].length; k++) {
if (k % 2 !== 0) {
if ((reversedNumbers[j][k] * 2) > 9) {
newArray.push((reversedNumbers[j][k] * 2) - 9);
} else {
newArray.push(reversedNumbers[j][k]);
}
} else {
newArray.push(reversedNumbers[j][k]);
}
}
}
return console.log(newArray);
}
validateCred(batch);
RESULT:
You're just pushing everything onto newArray, you're not creating any nested arrays. You need to create an array each time through the outer loop, and push that onto newArray.
// 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 = arry => {
let reversedNumbers = [];
let newArray = [];
for (let i = 0; i < arry.length; i++) {
reversedNumbers.push(arry[i].slice().reverse());
}
//return console.log(reversedNumbers);
for (let j = 0; j < reversedNumbers.length; j++) {
let newSubArray = [];
for (let k = 0; k < reversedNumbers[j].length; k++) {
if (k % 2 !== 0) {
if ((reversedNumbers[j][k] * 2) > 9) {
newSubArray.push((reversedNumbers[j][k] * 2) - 9);
} else {
newSubArray.push(reversedNumbers[j][k]);
}
} else {
newSubArray.push(reversedNumbers[j][k]);
}
}
newArray.push(newSubArray);
}
return newArray;
}
console.log(validateCred(batch));
You can also do it using map().
// 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 = arry => {
let reversedNumbers = arry.map(a => a.slice().reverse());
let newArray = reversedNumbers.map(numbers => numbers.map((num, k) => {
if (k % 2 !== 0) {
if ((num * 2) > 9) {
return (num * 2) - 9;
} else {
return num;
}
} else {
return num;
}
}))
return newArray;
}
console.log(validateCred(batch));

array doesn't push expected element

I'm learning JavaScript and having this problem. Basically I have to check for invalid credit cards number
// 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]
The validity of a credit card is accessed by this algorithm (Luhn algorithm):
function validateCred(card_number){
let sum = card_number[card_number.length-1];
let flag = 1;
for (i = card_number.length-2; i >= 0; i--){
if (flag % 2 !== 0){
card_number[i] *= 2;
if (card_number[i] > 9){
card_number[i] -= 9;
}
}
sum += card_number[i];
flag++;
}
if (sum % 10 === 0){
return true;
} else {
return false;
}
}
And I have to create an array with all the invalid cards:
function findInvalidCards(numbers){
let invalid_array = [];
for (i = 0; i < numbers.length; i++){
if (!validateCred(numbers[i])){
invalid_array.push(numbers[i]);
}
}
return invalid_array;
}
When I call the findInValidCards function, it raises the heap out of memory error, I tried to follow the solution from this link and raise the usage memory to 8gb but the problem persists. After debugging, I found out that this line invalid_array.push(numbers[i]) actually appends a undefined variable to the array, not the element that I wanted. What could possibly cause this problem?
As Nina had said in the comments, you should be defining i with let each time you're writing the for loop or else you're going to have unpredictable behavior
However, you also had an issue in your validateCred function where you were mutating the original Array while checking it - you can simply clone the input Array with let clone = card_number.slice(0);, and then reference clone for your checks
Also, you can simplify findInvalidCards by using .filter(), like:
function findInvalidCards(numbers) {
return numbers.filter(x => !validateCred(x));
}
// 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];
function validateCred(card_number) {
let clone = card_number.slice(0);
let sum = clone[clone.length - 1];
let flag = 1;
for (i = clone.length - 2; i >= 0; i--) {
if (flag % 2 !== 0) {
clone[i] *= 2;
if (clone[i] > 9) {
clone[i] -= 9;
}
}
sum += clone[i];
flag++;
}
if (sum % 10 === 0) {
return true;
} else {
return false;
}
};
// And I have to create an array with all the invalid cards:
function findInvalidCards(numbers) {
let invalid_array = [];
for (let i = 0; i < numbers.length; i++) {
if (!validateCred(numbers[i])) {
invalid_array.push(numbers[i]);
}
}
return invalid_array;
}
let invalidCardArray = findInvalidCards(batch);
// Prettier console.log()
invalidCardArray.forEach(x => console.log(validateCred(x) + ':', ...x));
The i variable is defined as global if you don't define it with var or let. So when it starts from findInvalidCards function the i value is zero but when it access the validateCred function, the i value changes.So when it will finish from validateCred function, i value will be -1 and it will try to increment it in findInvalidCards for loop and i value will be zero.That will happen over and over again,it will go in infinite loop causing the memory exception and everything crashes.
I have debug your code, so i know how it goes. :)
function findInvalidCards(numbers){
let invalid_array = [];
//make i local variable by defining it let or var, otherwise it will be global
for (var i = 0; i < numbers.length; i++){
if (!validateCred(numbers[i])){
invalid_array.push(numbers[i]);
}
}
return invalid_array;
}
function validateCred(card_number){
let sum = card_number[card_number.length-1];
let flag = 1;
//make i local variable by defining it let or var, otherwise it will be global
for (var i = card_number.length-2; i >= 0; i--){
if (flag % 2 !== 0){
card_number[i] *= 2;
if (card_number[i] > 9){
card_number[i] -= 9;
}
}
sum += card_number[i];
flag++;
}
if (sum % 10 === 0){
return true;
} else {
return false;
}
}

Returning Array names in array of arrays

Is there a way to call the names of the arrays in an array of arrays? I am applying a Luhn algorithm to a set of credit card numbers in an array of arrays I would like output that says, 'Array xxx is true/false.' I have created a workaround below by creating an array of "names" but can the batch array names be accessed directly?
// 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]
const arrNames = ['valid1', 'valid2', 'valid3', 'valid4', 'valid5', 'invalid1', 'invalid2', 'invalid3', 'invalid4', 'invalid5', 'mystery1', 'mystery2', 'mystery3', 'mystery4', 'mystery5']
const batchL = batch.length;
function ValidateCred(CC) {
if (CC.length > 19) return (false);
sum = 0;
mul = 1;
l = CC.length-1;
for (i = 0; i < l+1; i++) {
digit = CC[l - i];
tproduct = digit * mul;
if (tproduct >= 10) sum += (tproduct % 10) + 1;
else sum += tproduct;
if (mul == 1) mul++;
else mul--;
};
if ((sum % 10) == 0) return (true);
else return (false);
};
for (b = 0; b < batchL; b++) {
console.log('Card', arrNames[b],'is: ', ValidateCred(batch[b]));
};
Probably the best approach to this problem is to use an object instead of an array:
const validCCNumbers = {
valid1: [4, 5, 3, 9, 6, 7, 7, 9, 0, 8, 0, 1, 6, 8, 0, 8],
valid2: [5, 5, 3, 5, 7, 6, 6, 7, 6, 8, 7, 5, 1, 4, 3, 9],
valid3: [3, 7, 1, 6, 1, 2, 0, 1, 9, 9, 8, 5, 2, 3, 6],
valid4: [6, 0, 1, 1, 1, 4, 4, 3, 4, 0, 6, 8, 2, 9, 0, 5],
valid5: [4, 5, 3, 9, 4, 0, 4, 9, 6, 7, 8, 6, 9, 6, 6, 6]
}
If you need to access the names of each array you can do it with Object.keys(validCCNumbers)
You can shorten the whole operation considerably:
const all= {valid1:["4539677908016808", "5535766768751439", "371612019985236", "6011144340682905", "4539404967869666"],
invalid1:["4532778771091795", "5795593392134643", "375796084459914", "6011127961777935", "5382019772883854"],
mystery1:["344801968305414", "5466100861620239", "6011377020962656203", "4929877169217093", "4913540463072523"]};
Object.entries(all).forEach(([grname,arr])=>{
console.log(grname);
console.log(arr.map(cc=>cc+": "+ValidateCred(cc)));
});
function ValidateCred(ccstr) {
if (ccstr.length > 19) return (false);
let CC=ccstr.split(""), digit, tproduct,
sum = 0, mul = 1, l = CC.length-1;
for (i = 0; i < l+1; i++) {
digit = CC[l - i];
tproduct = digit * mul;
if (tproduct >= 10) sum += (tproduct % 10) + 1;
else sum += tproduct;
if (mul == 1) mul++;
else mul--;
};
return sum % 10 == 0
};

Categories