Estoy trabajando en una lección sobre programación dinámica, y mientras trabajaba en uno de los ejemplos me encontré con un error interesante que no he podido resolver. Se supone que el código se ejecuta recursivamente a través de una matriz de números para determinar si los miembros de la matriz se pueden usar para sumar a un targetNumber en particular. Lo hace restando recursivamente los números en la matriz de targetNumber para ver si disminuirá a 0.
Paso los parámetros a la función canSum así:
console.log(canSum(8, [2, 3, 5]));
Y luego aquí está la función:
const canSum = (targetNumber, numbers) => { // if targetnumber is 0, can return true if (targetNumber === 0) return true; //if targetNumber is less than 0, can return false if (targetNumber < 0) return false; //loop over array of numbers and evaluate each to see if subtracting it from targetNumber reaches 0 for (let num of numbers) { const remainder = targetNumber - num; if (canSum(remainder, numbers) === true) { //if (remainder === 0) { return true; } } return false; }Y el código terminado funciona perfectamente, volviendo verdadero para el conjunto de entradas anterior.
PERO, mientras escribía el código en el camino, antes de poner la llamada recursiva a canSum, estaba tratando de probarlo simplemente verificando si el resto era igual a 0 y, de ser así, devolver verdadero. Esa es la línea de código comentada
if (remainder === 0) {Sin embargo, cuando uso esa línea en lugar de la llamada recursiva, la función NUNCA devuelve verdadero. Incluso cuando uso console.log para imprimir el valor restante para poder confirmar que, de hecho, es 0, nunca se devuelve ni se muestra verdadero. siempre devuelve falso. Claramente me estoy perdiendo algo fundamental aquí y simplemente no puedo resolverlo. Gracias por cualquier ayuda que me puedan dar.
Su targetNumber es una constante y se declara dentro del ciclo, por lo que nunca se puede actualizar. Para que su declaración if funcione y también para que funcione su recursividad, querrá inicializar el resto con targetNumber antes del ciclo, y también restar del resto en lugar de targetNumber dentro del ciclo.
Aquí hay un ejemplo de esos cambios:
const canSum = (targetNumber, numbers) => { // if targetnumber is 0, can return true if (targetNumber === 0) return true; //if targetNumber is less than 0, can return false if (targetNumber < 0) return false; let remainder = targetNumber; //loop over array of numbers and evaluate each to see if subtracting it from targetNumber reaches 0 for (let num of numbers) { remainder = remainder - num; if (remainder === 0) return true; //if (canSum(remainder, numbers) === true) { // return true; //} } return false; }Como dijo "si los miembros de la matriz se pueden usar para sumar a un número objetivo en particular", entonces 2 + 3 + 5 = 10. No son iguales a 8, por lo que la condición debería ser falsa. En su código, la "recursión" pasará el resto en cada iteración como:
Entonces te queda 0 que devolverá verdadero de acuerdo con la lógica de tu código.
Necesita modificar ligeramente el código como:
const canSum = (targetNumber, numbers) => { // if targetnumber is 0, can return true if (targetNumber === 0) return true; //if targetNumber is less than 0, can return false if (targetNumber < 0) return false; var remainder = targetNumber; //loop over array of numbers and evaluate each to see if subtracting it from targetNumber reaches 0 for (let num of numbers) { remainder = remainder - num; if (remainder === 0) { //if (canSum(remainder, numbers) === true) { // return true; } } return false; }