Trabajando en un problema de JavaScript relacionado con los números de Fibonacci de un desafío de codewars aquí
Aquí está mi código hasta ahora:
function productFib(prod){ let firstFib = 0; let secondFib = 1; while (prod > firstFib * secondFib){ firstFib = firstFib + secondFib secondFib = firstFib + secondFib } if (prod === firstFib*secondFib){ return [firstFib, secondFib, true] } else { firstFib = secondFib - firstFib; secondFib = secondFib - firstFib; return [firstFib, secondFib, false] } }He pasado todas las pruebas excepto dos: productFib(193864606) y productFib(602070). Mis resultados son [10946, 17711, falso] y [610, 987, falso] respectivamente, y deberían decir verdadero en lugar de falso. Pero si multiplica esos números de Fibonacci, son iguales a prod param, por lo que no entiendo por qué mi declaración condicional no capta esos dos específicamente.
Tu lógica necesita pequeños cambios. La forma en que obtienes tus pares es:
function productFib(prod){ let firstFib = 0; let secondFib = 1; while (prod > firstFib * secondFib){ firstFib = firstFib + secondFib secondFib = firstFib + secondFib console.log(firstFib,secondFib); } if (prod === firstFib*secondFib){ return [firstFib, secondFib, true] } else { firstFib = secondFib - firstFib; secondFib = secondFib - firstFib; return [firstFib, secondFib, false] } } productFib(602070);Tus parejas son:
0,1 1,2 3,5 Pero te estás perdiendo los casos en los que 2,3 o 1,1 deberían estar juntos. Esto se debe a que está actualizando firstFib como firstFib + secondFib . En lugar de eso, debería tomar el valor de secondFib directamente
function productFib(prod){ let firstFib = 0; let secondFib = 1; while (prod > firstFib * secondFib){ let prevFirstFib = firstFib; firstFib = secondFib; secondFib = prevFirstFib + secondFib; console.log(firstFib, secondFib); } if (prod === firstFib*secondFib){ return [firstFib, secondFib, true] } else { firstFib = secondFib - firstFib; secondFib = secondFib - firstFib; return [firstFib, secondFib, false] } } console.log(productFib(602070)); console.log(productFib(193864606));Hay dos problemas:
El primer bucle salta 2 pasos de Fibonacci en cada iteración. Pero cuál fue el mayor número de Fibonacci de los dos debe permanecer y usarse como el menor de los dos.
La parte else no debe retroceder a un par anterior. El par actual es lo que necesita devolver. Así que puedes hacer esto sin if... if..else even, y pasar como argumento booleano la comprobación de igualdad.
Corrección:
function productFib(prod){ let firstFib = 0; let secondFib = 1; while (prod > firstFib * secondFib){ [firstFib, secondFib] = [secondFib, firstFib + secondFib] } return [firstFib, secondFib, prod === firstFib*secondFib] } const assertSimilar = (a, b) => console.assert(JSON.stringify(a) === JSON.stringify(b)); assertSimilar(productFib(4895), [55, 89, true]) assertSimilar(productFib(5895), [89, 144, false]) assertSimilar(productFib(74049690), [6765, 10946, true]) assertSimilar(productFib(84049690), [10946, 17711, false]) assertSimilar(productFib(193864606), [10946, 17711, true]) assertSimilar(productFib(447577), [610, 987, false]) assertSimilar(productFib(602070), [610, 987, true]) console.log("tests passed");Si agrega algunas declaraciones de registro, será mucho más fácil ver lo que está sucediendo. Su función en realidad falla con un número mucho más pequeño: 40. Al iniciar un poco de registro, veamos qué sucede:
function productFib(prod){ let firstFib = 0; let secondFib = 1; while (prod > firstFib * secondFib){ console.log("before", firstFib, secondFib); firstFib = firstFib + secondFib secondFib = firstFib + secondFib console.log("after", firstFib, secondFib); } console.log(prod, firstFib, secondFib) if (prod === firstFib*secondFib){ return [firstFib, secondFib, true] } else { firstFib = secondFib - firstFib; secondFib = secondFib - firstFib; return [firstFib, secondFib, false] } } console.log(productFib(40)) Como puede ver, se está saltando un número. En lugar de usar el secondFib anterior como el nuevo firstFib , lo omite por completo, es por eso que su función está fallando. Una forma sencilla de solucionar esto es guardar el valor anterior de firstFib , establecer firstFib = secondFib y luego establecer secondFib = prevFirst + secondFib , así:
function productFib(prod){ let firstFib = 0; let secondFib = 1; while (prod > firstFib * secondFib){ console.log("before", firstFib, secondFib); let prevFirst = firstFib; firstFib = secondFib secondFib = prevFirst + secondFib console.log("after", firstFib, secondFib); } console.log(prod, firstFib, secondFib) if (prod === firstFib*secondFib){ return [firstFib, secondFib, true] } else { firstFib = secondFib - firstFib; secondFib = secondFib - firstFib; return [firstFib, secondFib, false] } } console.log(productFib(40))¡Ahora verá que está recorriendo los números correctamente y generando lo que espera!