Estaba creando una función para el algoritmo de Luhn en Javascript. Aquí está mi código:
// 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){ let newArr = []; newArr.push(arr[arr.length - 1]); for(let i = arr.length - 2; i >= 0; i--){ let x = arr[i]; // console.log(x); x *= 2; if(x > 9){ x -= 9; } // console.log(x); newArr.push(x); // console.log(newArr); } // console.log(newArr); let sum = 0; newArr.forEach(num => sum += num); console.log(sum); // if(sum % 10 === 0){ // return true; // } else { // return false; // } return newArr; } console.log(validateCred(valid1)); Este no es mi código original, pero como puede ver, validateCred es mi función. Se supone que la declaración if en realidad da un resultado verdadero, pero está dando falso, así que me preguntaba dónde me equivoqué. Los console.log aquí me ayudaron a descubrir qué salió mal, así que aquí está el resultado de ellos. Corté el código para ver qué estaba haciendo la función con la matriz, verifiqué y todo estaba bien. Incluso la suma estaba funcionando. Así que me quedé preguntándome si la matriz está mal, pero cuando ingresé la misma matriz en la implementación de GeeksForGeeks, ¡se cumplió! Entonces, ¿qué salió mal?
No quiero tomar los créditos de Niet, así que si publica sus comentarios como respuesta, debes aceptar los suyos. Estoy publicando esto solo dos muestran dos alternativas más cortas usando Array.prototype.reduce
El principal problema con su algoritmo es (como ya dijo Niet) que está duplicando cada dígito, en lugar de solo cada dos dígitos.
Variante 1 con inversión del número de tarjeta
function checkCard(arr) { return arr.slice().reverse() .reduce((a, c, i) => a + (i % 2 == 0 ? c : (c < 5 ? 2 * c : 2 * c - 9)), 0) % 10 == 0; } arr.slice().reverse() porque reverse funciona en su lugar. Entonces, para mantener arr en el orden original, cópielo primero. reduce luego sumará los dígitos. Para cada índice par (0,2,4,...) en la matriz invertida , simplemente agregará el dígito actual c . Para cada índice impar (1,3,5,...), agregará 2*c o 2*c-9 , dependiendo de si 2*c > 9 .
Variante 2 sin invertir el número de tarjeta
function checkCard2(arr) { const p = arr.length % 2 return arr.reduce((a,c,i) => a + (i % 2 != p ? c : (c < 5 ? 2 * c : 2 * c - 9)), 0) % 10 == 0; } Debido a que el algoritmo original de Luhn comienza a contar desde el dígito más a la derecha, si comenzamos desde el dígito más a la izquierda (es decir, sin invertir el número), tenemos que actuar de manera diferente en números de longitud par o impar. Para números de longitud impar, debemos duplicar los dígitos en índices impares (1,3,5,...), para longitudes pares debemos duplicar los dígitos en índices pares (0,2,4,...). Para eso está la p . Será 0 para longitud par y 1 para longitud impar. Entonces si i % 2 == p debemos duplicar el dígito actual, de lo contrario no.