Si vous essayez simplement de compter combien de fois il est réduit et que vous ne vous souciez pas spécifiquement de la récursivité ... vous pouvez simplement supprimer la récursivité. Le code ci-dessous reste fidèle à la poste d'origine car il ne compte pas num <= 9comme nécessitant une réduction. Par conséquent, singleDigit(8)aura count = 0, et singleDigit(39)aura count = 3, tout comme le PO et la réponse acceptée démontrent:
const singleDigit = (num) => {
let count = 0, ret, x;
while (num > 9) {
ret = 1;
while (num > 9) {
x = num % 10;
num = (num - x) / 10;
ret *= x;
}
num *= ret;
count++;
console.log(num);
}
console.log("Answer = " + num + ", count = " + count);
return num;
}
Il n'est pas nécessaire de traiter les nombres 9 ou moins (c.-à-d. num <= 9). Malheureusement, le code OP sera traité num <= 9même s'il ne le compte pas. Le code ci-dessus ne traitera ni ne comptera pas num <= 9du tout. Il passe juste à travers.
J'ai choisi de ne pas l'utiliser, .reducecar l'exécution des calculs réels était beaucoup plus rapide à exécuter. Et, pour moi, plus facile à comprendre.
Réflexion sur la vitesse
Je pense que le bon code est également rapide. Si vous utilisez ce type de réduction (qui est beaucoup utilisé en numérologie), vous devrez peut-être l'utiliser sur une énorme quantité de données. Dans ce cas, la vitesse deviendra de la plus haute importance.
L'utilisation des deux .map(Number)et console.log(à chaque étape de réduction) est à la fois très très longue à exécuter et inutile. La simple suppression .map(Number)de l'OP l'a accéléré d'environ 4,38x. La suppression console.loga tellement accéléré qu'il était presque impossible de tester correctement (je ne voulais pas l'attendre).
Donc, comme pour la réponse de customcommander , ne pas utiliser .map(Number)ni console.loget pousser les résultats dans un tableau et utiliser .lengthfor countest beaucoup plus rapide. Malheureusement pour la réponse de customcommander , l'utilisation d'une fonction de générateur est vraiment très lente (cette réponse est environ 2.68x plus lente que l'OP sans .map(Number)et console.log)
En outre, au lieu d'utiliser, .reduceje viens d'utiliser les mathématiques réelles. Ce seul changement a accéléré à lui seul ma version de la fonction par un facteur de 3,59x.
Enfin, la récursivité est plus lente, elle prend de la place dans la pile, utilise plus de mémoire et a une limite au nombre de fois qu'elle peut "se reproduire". Ou, dans ce cas, combien d'étapes de réduction il peut utiliser pour terminer la réduction complète. Déployer votre récursivité en boucles itératives le maintient au même endroit sur la pile et n'a aucune limite théorique sur le nombre d'étapes de réduction qu'il peut utiliser pour terminer. Ainsi, ces fonctions peuvent ici "réduire" presque n'importe quel entier de taille, uniquement limité par le temps d'exécution et la longueur d'un tableau.
Tout cela à l'esprit ...
const singleDigit2 = (num) => {
let red, x, arr = [];
do {
red = 1;
while (num > 9) {
x = num % 10;
num = (num - x) / 10;
red *= x;
}
num *= red;
arr.push(num);
} while (num > 9);
return arr;
}
let ans = singleDigit2(39);
console.log("singleDigit2(39) = [" + ans + "], count = " + ans.length );
// Output: singleDigit2(39) = [27,14,4], count = 3
La fonction ci-dessus est extrêmement rapide. Il est environ 3,13 fois plus rapide que l'OP (sans .map(Number)et console.log) et environ 8,4 fois plus rapide que la réponse de customcommander . Gardez à l'esprit que la suppression console.logde l'OP l'empêche de produire un nombre à chaque étape de réduction. D'où la nécessité ici de pousser ces résultats dans un tableau.
PT
.map(Number)est redondant puisque l'*opérateur contraint les valeurs à numéroter de toute façon. ;-)