- Moté,
Salut tout le monde,
En ce moment, j’apprends le python, et j’utilise pour ça exercism.io, qui propose des exercices pour apprendre le langage au fur et à mesure. Je suis en train de faire un side-exercise, ce qui veut dire que je n’ai pas de review dessus.
Cet exercice, c’est celui des nombres parfaits selon Nicomachus. Un nombre est parfait si la somme de ses facteurs (lui-même excepté) est égal à lui-même (6 = 1 + 2 + 3, et 6 est divisible par 1, 2 et 3). Si cette somme est supérieure, le nombre est alors abondant, si la somme est inférieure alors le nombre est déficient.
Je n’ai pas de problème avec la logique pour le faire, et j’ai très bien réussi. Mon code passe tous les tests, ce qui est plutôt bon signe. Maintenant, le problème c’est que les tests prennent plus de 2 secondes à s’exécuter, pour mon code qui fait 25 lignes. Faut dire que dans les tests, ça passe 2 fois par des valeurs à plus de 30 millions.
Actuellement, mon code passe par une boucle qui teste chaque entier inférieur à la moitié + 1 du nombre à classer pour vérifier le modulo. Si le modulo = 0, alors l’entier est ajouté dans la somme d’Aliquot. Ensuite, la somme est comparée avec le nombre à classer. Je me demandais s’il y avait moyen d’optimiser ce petit code ?
Sur exercism, je peux regarder les autres solutions de la communauté, qui sont parfois des trucs bizarres pour faire le moins de lignes possibles, mais parfois aussi des optimisations de code. C’est cool, mais je préfèrerais idéalement avoir des orientations sur lesquelles chercher, plutôt que les solutions déjà écrites du reste de la communauté
Pour voir la consigne complète et les tests, c’est dispo sur mon Github, parce que je ne suis pas sûr que ce soit accessible sur exercism.io sans inscription. Et pour mon code (aussi dispo sur Github, si jamais) :
def classify(number: int) -> str:
"""Classify the int following the Nicomachus' classification of perfect numbers.
"""
classification: str = ""
if number < 1 or int(number) != number:
raise ValueError("Can't classify this number or value")
elif number == 1:
classification = "deficient"
else:
aliquot = aliquot_sum(number)
if aliquot > number:
classification = "abundant"
elif aliquot < number:
classification = "deficient"
else:
classification = "perfect"
return classification
def aliquot_sum(number: int) -> int:
aliquot: int = 0
for i in range(1, number // 2 + 1): # Yup, no need to test more, and I needed someone to tell me that...
if number % i == 0:
aliquot += i
return aliquot