Septième exercice en Python, JavaScript et APL 

Résumé en français : Ecrire une fonction qui admet en paramètre un nombre entier positif et qui retourne le nombre de fois où vous devez multiplier ses chiffres pour obtenir un seul chiffre.

Version classique

On doit compter (variable compteur) combien de fois il faut multiplier les chiffres entre eux jusqu’à obtenir un seul chiffre. Ce nombre d’itérations étant inconnu, nous allons naturellement utiliser une boucle Tant Que (while). Maintenant, comment faire la multiplication des chiffres d’un nombre ? On peut par exemple transformer ce nombre en chaine puis en liste et multiplier les éléments de cette liste grâce à une boucle.

Python

def mul(n):
  chaine = str(n)            # Transformation nombre en chaine
  liste = list(chaine)       # puis en liste
  produit = 1                # Initialisation du résultat du produit
  for c in liste:
    produit *= int(c)        # int = convertir chaine en entier
  return produit  

>> mul(999)
729

On peut également utiliser une librairie comme operator ou numpy :

import numpy as np

def mul(n):
  liste = list(str(n))                      # Nombre en liste
  return np.prod([int(v) for v in liste])   # "prod" pour produit

>> mul(999)
729

javascript

const mul = n => 
{
     liste = [...''+n] ;    // Conversion nombre > chaine > liste
     produit = 1 ;
     for (c of liste) produit *= +c ;
     return produit
}

>> mul(999)
729

APL

Pour transformer un nombre en chaine on utilise et inversement transforme une chaine en nombre :

      '2',⍕3     ⍝ Concaténation de la chaine '2' et de '3'
23
      ⍎ '2+3'    ⍝ Transformation de la chaine en nombre
5

Ainsi, en écrivant :

      ⍎¨⍕ 987
9 8 7

On transforme le nombre 987 en un vecteur composé de ses chiffres, le ¨ signifiant pour chaque (for each). Il suffit ensuite de faire le produit des termes, c’est-à-dire une réduction :

      ×/ ⍎¨⍕ 999
729

Programme finaL version classique en javascript

A tester ici :

const persistence = n =>
{
   var compteur = 0;                  // Notre compteur de tours
   while (n > 9) {
     compteur ++;
     produit = 1;                     // Calcul du produit des chiffres
     liste = [...''+n];               // Conversion du nombre en liste
     for (c of liste) produit *= +c;  // +c --> entier
     n = produit  
   }
   
   return compteur;
}

>> persistence(999)
4

Programme finaL version classique en python

import numpy as np

def persistence(n):
  compteur = 0
  while n > 9:
    compteur += 1
    n = np.prod([int(v) for v in list(str(n))])
  return compteur 

>> persistence(999)
4

Version récursive

Si un nombre est plus petit que 10, sa persistence est 0. Sinon, sa persistence est 1 + la persistence du produit de ses chiffres. Par exemple :

persistence(39) = 1 + persistence(3 * 9)
                = 1 + persistence(27)
                = 1 + (1 + persistence(2 * 7)) 
                = 1 + 1 + persistence(14)
                = 1 + 1 + (1 + persistence(1 * 4))
                = 1 + 1 + 1 + persistence(4)              
                = 1 + 1 + 1 + 0
                = 3

version finale récursive en python

import numpy as np

def persistence(n):
    if n < 10: return 0
    p = np.prod([int(v) for v in list(str(n))])
    return 1 + persistence(p) 

version finale récursive en javascript

La multiplication des chiffres peut se faire par reduce plutôt que par une boucle for classique :

>> [...'999'].reduce((a,c) => a * (+c), 1)   // avec parenthèses
729

>> [...'999'].reduce((a,c) => a * +c, 1)    // ou sans parenthèse !
729

>> [...'999'].reduce((a,c) => a * +c)      // ou sans initialisation !!
729

On obtient finalement :

persistence = num => 
    num < 10 ? 
    0 :
    1 + persistence([...'' + num].reduce((a, c) => a * +c))

Version finale récursive en apl

La récurvisité en APL existe en utilisant le symbole . Exemple classique de la factorielle :

      {⍵ = 1 : 1 ⋄ ⍵ × ∇ ⍵ - 1} 10
3628800
      !10
3628800

La forme est test : valeurSiVrai ⋄ valeurSiFaux où ⋄ (diamant) est le séparateur.

Voici une proposition pour notre problème :

      persistence ← {⍵ < 10 : 0 ⋄ 1 + ∇ ×/ ⍎¨ ⍕ ⍵}

      persistence 999
4

Qui est la traduction de : Si le nombre ⍵ est inférieur à 10, renvoyer 0 sinon, faire 1 plus la persistence du produit des chiffres de ⍵.