3

Hice una funcion que sustituye el * por todos los numeros del 0 al 9 y luego filtra todos los que son divisibles por 6 y los debe regresar como strings.. ver en: is divisible by 6 funcionaba bastante bien pero para numeros muy grandes el n%6==0 no me funciona... ejemplo n= 1234567890123456789012345678*0 que debia retornar ['123456789012345678901234567800', '123456789012345678901234567830', '123456789012345678901234567860', '123456789012345678901234567890'] en vez de eso regresa []

otra forma de buscar multiplos de 6 es si son divisibles por 2 y divisibles por 3... entonces hice esta funcion de abajo, como n%2 no funciona tampoco hice slice de su ultimo digito, y para n%3 hice reduce de sus digitos %3... Asi funciono para el modulo de 6 por esa variante del modulo de 3 y 2 aunque es algo engorroso paso todos los test.. asi que me gustaria saber como puedo trabajar con numeros muy grandes en Javascript pues no es la primera vez que me sucede algo similar...

function isDivisibleBy6(s) {    
    let nums=[];
    for(let i=0;i<=9;i++){
        nums.push(s.replace(/[*]/, `${i}`));
    }
    return nums.filter(d =>(d.slice(-1)%2==0)  && (d.split('').reduce((a,b)=>+a+~~(b))%3==0))
}

console.log('para 41*: '+isDivisibleBy6('41*'));
console.log('para 34234*2: '+isDivisibleBy6('34234*2'));
console.log('para 1234567890123456789012345678*0: '+isDivisibleBy6('1234567890123456789012345678*0'));
RazerJs
  • 2,253
  • 2
  • 10
  • 36
  • 2
    @PabloLozano (no puedo añadir a todos los que han marcado la pregunta). Me pregunto por qué esta pregunta ha sido marcada como duplicada de una pregunta que trata el tema del problema que tiene `JavaScript` (y otros lenguajes) para manejar números con coma flotante. Esta pregunta trata de números enteros y el problema es trabajar con números que sobrepasan `MAX_SAFE_INTEGER ` – ElChiniNet Oct 21 '19 at 14:00
  • 2
    Coincido con @ElChiniNet, la pregunta no versa sobre cálculos aritméticos directos con números, al contrario se trata de realizar operaciones con `strings`, y en dichas operaciones no intervienen nunca valores excesivamente grande (aunque el `string` sea enorme). La pregunta a la cual hace referencia el duplicado, sí que trabaja con operaciones aritméticas sobre números grandes, pero este no es el caso. Voto por reabrir la pregunta. – Mauricio Contreras Oct 22 '19 at 18:45

1 Answers1

2

Veo que tu lógica para intentar no comprobar directamente si el número es divisible por 6 está bien, estás comprobando si el último número es divisible entre 2 y si la suma de todos los dígitos es divisible entre 3 (quizás este es el propósito del ejercicio)

El problema que tienes intentando comprobar si los números son divisibles por 6 es que estás trabajando con números verdaderamente grandes que sobrepasan el número más grande con el que JavaScript puede trabajar de manera segura, por lo que el resultado de cualquier cálculo que hagas con esos números va a estar representado en notación exponencial aparte de que no tendrías la seguridad de que el resultado sea correcto:

const num = 123456789012345678901234567800;

console.log( num > Number.MAX_SAFE_INTEGER );

// Resultados
console.log(num);
console.log( num === num + 5 );
console.log( num % 6 === 0 );

Como bien te recomendó @ordago, lo mejor es trabajar con algún método que trabaje con números de este tamaño de manera segura. El estándar ya cuenta con bigInt, pero su compatibilidad es muy baja todavía. Lo mejor es usar alguna librería que trate los números como cadenas. Normalmente en HackerRank es posible incluir en el código la librería big-number para manejar números grandes en JavaScript (no sé si en CodeWars esté disponible, pero si no lo está, tu solución es la correcta siempre que la suma de los dígitos no sobrepase a Number.MAX_SAFE_INTEGER).

Aquí te dejo los mismos cálculos anteriores usando una librería similar (big-integer):

const num = bigInt('123456789012345678901234567800');

console.log( num.toString() );
console.log( num.compare(num.add(5)) === 0 );
console.log( num.mod(6).isZero() );
<script src="https://unpkg.com/big-integer@1.6.47/BigInteger.js"></script>

Y aquí el código chequeando si los números son divisibles por 6 usando la misma librería:

function isDivisibleBy6(s) {    
    const nums = [];
    for(let i = 0; i <= 9; i++){
        nums.push(s.replace(/\*/, `${i}`));
    }
    return nums.filter(n => bigInt(n).mod(6).isZero());
    
}

console.log('para 41*: '+isDivisibleBy6('41*'));
console.log('para 34234*2: '+isDivisibleBy6('34234*2'));
console.log('para 1234567890123456789012345678*0: '+isDivisibleBy6('1234567890123456789012345678*0'));
<script src="https://unpkg.com/big-integer@1.6.47/BigInteger.js"></script>

Y aquí tu mismo código chequeando si el último número es divisible por 2 y utilizando big-integer para la suma de los dígitos por si la suma resulta en un número muy grande (que es muy improbable que te den como input un número de este tamaño):

function isDivisibleBy6(s) {    
    const nums = [];
    for(let i = 0; i <= 9; i++){
        nums.push(s.replace(/\*/, `${i}`));
    }
    return nums.filter(b => +b.slice(-1) % 2 === 0 && b.split('').reduce((b, n) => b.add(+n), bigInt(0)).mod(3).isZero());
    
}

console.log('para 41*: '+isDivisibleBy6('41*'));
console.log('para 34234*2: '+isDivisibleBy6('34234*2'));
console.log('para 1234567890123456789012345678*0: '+isDivisibleBy6('1234567890123456789012345678*0'));
<script src="https://unpkg.com/big-integer@1.6.47/BigInteger.js"></script>
ElChiniNet
  • 3,215
  • 9
  • 25
  • Wow! esta es la funcion BigInt() https://unpkg.com/big-integer@1.6.47/BigInteger.js pensaba que era algo mas sencillo – RazerJs Oct 21 '19 at 12:29
  • @IsraelGonzález, en realidad esta librería actúa como polyfill si el objeto `bigInt` nativo no está presente. Pero sí, es una librería mucho más compleja que una simple función. – ElChiniNet Oct 21 '19 at 12:39
  • 1
    Gracias por tu respuesta amplia aun mas la solucion ElChiniNet – RazerJs Oct 21 '19 at 12:52
  • Entiendo la utilidad de BigInt, pero pienso que no es necesario su uso, igual esperaré a ver si la pregunta es reabierta. Saludos – Mauricio Contreras Oct 22 '19 at 18:52
  • @MauricioContreras, esperemos a ver, sería bueno escuchar otras opiniones y soluciones. – ElChiniNet Oct 22 '19 at 18:57