E376 − Les forts et les faibles [*** à la main]
Un entier n est par convention appelé "fort" si son nombre de diviseurs (y compris 1 et lui-même) est
strictement supérieur aux nombres de diviseurs de tous les entiers qui lui sont inférieurs. A l'inverse cet entier est dit "faible".
Par exemple, 4 est fort car il a trois diviseurs (1,2,4) et chacun des entiers 1,2,3 a au plus deux diviseurs.
15 est faible car il a 4 diviseurs (1,3,5,15) alors que 12 qui est inférieur à 15 en a 6 (1,2,3,4,6,12).
Q₁ Le plus petit entier qui a exactement 28 diviseurs est-il fort ou faible?
Q₂Trouver le plus petit entier fort qui a au moins 112 diviseurs
Q₃ Déterminer le nombre d'entiers faibles strictement positifs ≤ 2019.
Q₄ Déterminer l'entier fort n < 100 000 qui a le plus grand nombre possible de diviseurs.
Q₅ Pour quelles valeurs de n, l'entier n! (factorielle de n) est-il fort?
Solution proposée par Michel Dominique
Remarque : ce problème a trait aux nombres hautement composés.
Pour les questions Q1 à Q4, un script Python permet de trouver les solutions (script fourni à la fin du document) :
Q1: 960 est faible
Q2: 55440 est le plus petit entier fort qui a 112 diviseurs
Q3: 2002: nombre d'entiers faibles <= 2019
Q4: 83160 (fort) a 128 diviseurs
Pour la question Q5, Python n’est pas notre ami. En effet, si on regarde les factorielles des douze premiers entiers de 1 à 12, on voit avec le script suivant que ce sont tous des entiers forts sauf 8 puisque 27720 < 8!=
40320 a 96 diviseurs comme 8!
def getDivisors(n, strict=False):
"""
Retourne la liste des diviseurs propres de n.
"""
liste = [1]
for i in range(2, n//2+1):
if n % i == 0:
liste.append(i)
if not strict and n != 1: liste.append(n) return liste
# Q5-Pour quelles valeurs de n, l'entier n! (factorielle de n) est-il fort?
def Q5(seuil):
# mémoisation du nombre de diviseurs des entiers liste_nbdivisors = [1] # 0! est exclus par hypothèse n = 1
fact = 1
liste_fact_fort = [1]
while n <= seuil:
divisors = getDivisors(fact) nb_divisors = len(divisors)
#print(n, fact, nb_divisors, divisors, liste_nbdivisors, "...") if max(liste_nbdivisors) < nb_divisors:
liste_fact_fort.append(n)
print(n, "! =", fact, "a", nb_divisors, "diviseurs: ", divisors, " - Liste des nombres de diviseurs des n!:", liste_nbdivisors)
liste_nbdivisors.append(nb_divisors) n += 1
fact = fact*n return liste_fact_fort seuil = 12
print("Q5> liste des n! forts:", Q5(seuil))
dont le résultat pour seuil=12 donne :
Q5> liste des n! forts: [1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 12]
Le résultat ci-dessus suggère que n! est fort pour n sauf n=8.
Mais cela reste à démontrer !
Script Python pour trouver les réponses aux questions Q1 à Q4
""" A376. Les forts et les faibles
Un entier n est par convention appelé "fort" si son nombre de diviseurs (y compris 1 et lui-même) est strictement supérieur aux nombres de diviseurs de tous les entiers qui lui sont inférieurs.
Si ce n'est pas le cas, cet entier est dit "faible".
Par exemple, 4 est fort car il a trois diviseurs (1,2,4) et chacun des entiers 1,2,3 a au plus deux diviseurs.
15 est faible car il a 4 diviseurs (1,3,5,15) alors que 12 qui lui est inférieur en a 6 (1,2,3,4,6,12).
Q1-Le plus petit entier qui a exactement 28 diviseurs est-il fort ou faible?
Q2-Trouver le plus petit entier fort qui a au moins 112 diviseurs.
Q3-Déterminer le nombre d'entiers faibles strictement positifs ≤ 2019.
Q4-Déterminer l'entier fort n < 100 000 qui a le plus grand nombre possible de diviseurs.
Q5-Pour quelles valeurs de n, l'entier n! (factorielle de n) est-il fort?
Réponses: HYPOTHESES:
- n > 0
- 1 est fort et a 1 diviseur (sinon 0 le serait mais il est exclus par hypothèse) Q1: 960 est faible
Q2: 55440 est le plus petit entier fort qui a 112 diviseurs Q3: 2002: nombre d'entiers faibles <= 2019
Q4: 83160 (fort) a 128 diviseurs
"""
def getDivisors(n, strict=False):
"""
Retourne la liste des diviseurs propres de n.
"""
liste = [1]
for i in range(2, n//2+1):
if n % i == 0:
liste.append(i)
if not strict and n != 1: liste.append(n) return liste
# Q1-Le plus petit entier qui a exactement 28 diviseurs est-il fort ou faible?
def Q1(seuil):
# mémoisation du nombre de diviseurs des entiers
liste_nbdivisors = [0, 1] # Astuce: 0 occupe l'indice 0 donc les entiers n sont récupérables par leur indice n = 2
while True:
nb_divisors = len(getDivisors(n)) if nb_divisors == seuil:
#print(n, nb_divisors, max(liste_nbdivisors), "...", end='\r') if max(liste_nbdivisors) < nb_divisors:
ret = "{} est fort !".format(n) else:
ret = "{} est faible...".format(n) return ret
liste_nbdivisors.append(nb_divisors) n += 1
# Q2-Trouver le plus petit entier fort qui a au moins 112 diviseurs.
def Q2(seuil):
# mémoisation du nombre de diviseurs des entiers
liste_nbdivisors = [0, 1] # Astuce: 0 occupe l'indice 0 donc les entiers n sont récupérables par leur indice n = 2
found = False while not found:
nb_divisors = len(getDivisors(n)) if nb_divisors >= seuil:
#print(n, nb_divisors, max(liste_nbdivisors), "...") if max(liste_nbdivisors) < nb_divisors:
found = True break
liste_nbdivisors.append(nb_divisors) n += 1
return n
# Q3-Déterminer le nombre d'entiers faibles strictement positifs ≤ 2019.
def Q3(seuil):
# mémoisation du nombre de diviseurs des entiers
liste_nbdivisors = [0, 1] # Astuce: 0 occupe l'indice 0 donc les entiers n sont récupérables par leur indice n = 2
nb_faibles = 0 while n <= seuil:
nb_divisors = len(getDivisors(n))
#print(n, nb_divisors, max(liste_nbdivisors), "...", end='\r') if max(liste_nbdivisors) >= nb_divisors:
nb_faibles += 1
liste_nbdivisors.append(nb_divisors) n += 1
return nb_faibles
# Q4-Déterminer l'entier fort n < 100 000 qui a le plus grand nombre possible de diviseurs.
def Q4(seuil):
# mémoisation du nombre de diviseurs des entiers
liste_nbdivisors = [0, 1] # Astuce: 0 occupe l'indice 0 donc les entiers n sont récupérables par leur indice n = 2
max_diviseurs = 0 n_max = 0
while n < seuil:
nb_divisors = len(getDivisors(n))
#print(n, nb_divisors, max(liste_nbdivisors), "...", end='\r') if max(liste_nbdivisors) < nb_divisors:
if nb_divisors > max_diviseurs:
max_diviseurs = nb_divisors n_max = n
liste_nbdivisors.append(nb_divisors) n += 1
return n_max, max_diviseurs seuil = 28
print("Q1> plus petit nombre avec", seuil, "diviseurs:", Q1(seuil)) seuil = 112
print("Q2> plus petit entier fort avec", seuil, "diviseurs:", Q2(seuil)) seuil = 2019
print("Q3> nb d'entiers faibles <=", seuil, ":", Q3(seuil)) seuil = 100000
n_max, max_diviseurs = Q4(seuil)
print("Q4> entier fort <", seuil, "ayant le plus grand nombre de diviseurs:", n_max, "a", max_diviseurs,
"diviseurs")