2010-10-26 6 views
5

J'ai écrit un programme pour vérifier si ma pensée sur la solution sur papier est correcte (et c'est le cas).Simplifier ce code python

La tâche: combien de zéros est dans le dos de la multiplication de tous les numéros de 10 à 200.

Il est 48 et il est simple de calculer manuellement.

Je n'écrire sur python sérieux et voici ce que je reçois:

mul = 1 
for i in range(10, 200 + 1): 
    mul *= i 

string = str(mul) 
string = string[::-1] 
count = 0; 
for c in str(string): 
    if c == '0': 
     count += 1 
    else: 
     break 

print count 
print mul 

Je parie qu'il est possible d'écrire le même plus élégant dans un langage comme un python.

ps: oui, il est un devoir, mais pas le mien - je viens d'aider un gars ;-)

Répondre

11

Une implémentation straight-forward qui ne comporte pas le calcul de la factoriel (pour que cela fonctionne avec de grands nombres, soit 2000000) (édité):

fives = 0 
twos = 0 
for i in range(10, 201): 
    while i % 5 == 0: 
     fives = fives + 1 
     i /= 5 
    while i % 2 == 0: 
     twos = twos + 1 
     i /= 2 
print(min(fives, twos)) 
+0

Serait bien si je pouvais comprendre comment cela fonctionne. –

+3

Il compte le nombre de cinq et deux dans la factorisation en nombres premiers de la factorielle itérative (donc 10! Aurait 2 et 8). Puisque 5 * 2 = 10, et qu'aucun autre nombre premier ne peut être multiplié par 10, le nombre de 10 dans la factorisation (qui est le nombre de zéros) est le minimum du nombre de cinq et le nombre de deux dans le premier factorisation Le nombre de cinq et cinq est beaucoup plus petit que le factorial calculé. – irrelephant

+3

Bien que la question appelle 10-200, c'est certainement une meilleure approche pour des nombres beaucoup plus importants. Pour les plus petits nombres, faire la multiplication s'avère être plus rapide (au moins quand j'ai fait des tests de temps). – snapshoe

3
import itertools 
mul = reduce(lambda x,y: x*y, range(10, 200+1)) 
zeros = itertools.takewhile(lambda s: s == "0", reversed(str(mul))) 
print len(list(zeros)) 

La deuxième ligne calcule le produit, le troisième obtient un itérateur de tous les zéros dans cette nombre, le dernier imprime le nombre de ces zéros.

+2

pourrait remplacer 'lambda x, y: x * y' avec' 'operator.mul' –

+0

Et range' avec' xrange' (bien que ce serait mineur dans ce cas) –

+0

@Brendan Long: depuis nous alwa ys itère du début à la fin de la plage - n'est-ce pas «xrange» un overhead du tout? – zerkms

3
len(re.search('0*$', str(reduce(lambda x, y: x*y, range(10, 200 + 1),1))).group(0)) 
+4

C'est un peu python moche ... –

+1

mais beau si vous êtes en fonction programmation, oeil du spectateur et tout! –

+3

Je ne dirais pas que c'est très fonctionnel. Vous ne voyez pas beaucoup d'expressions régulières dans la programmation fonctionnelle. –

6
import math 

answer = str(math.factorial(200)/math.factorial(9)) 
count = len(answer) - len(answer.rstrip('0')) 
  1. importer la bibliothèque de mathématiques
  2. Calculer la factorial de 200 et enlever les 9 premiers numéros
  3. Dénudez zéros de droite et trouver la différence dans les longueurs
+0

Le plus laconique en ce moment – zerkms

+0

'reduce (operator.mul, xrange (10, 200 + 1)) 'ne serait-il pas plus efficace que la division factorielle +? –

+0

@Brendan Long: toutes les réponses sont appréciées, mais je vais vérifier le plus élégant ;-P – zerkms

0
mul = str(reduce(lambda x,y: x*y, xrange(10, 201))) 
count = len(mul) - len(mul.rstrip("0")) 
2

Voulez-vous dire zéros? Qu'est-ce que null sinon?

Est-ce que certaines mathématiques ne le rendraient pas plus simple?

Combien de 5 s à 200 est len ​​([x pour x dans la plage (5, 201, 5)]) = 40

Combien de 25s à 200 est len ​​([x pour x dans la plage (25, 201, 5) si x% 25 == 0]) = 8

Combien de 125 dans 200 est len ​​([x pour x dans la plage (120, 201, 5) si x% 125 == 0]) = 1

au total 5 s = 49

200! = 5^49 * 2^49 * (autres numéros non divisible par 2 ou 5)

Donc il y a 49 zéros

+0

Pour être clair - c'est 48, pas 49 ;-) Et je l'ai résolu manuellement de la même manière. La question actuelle est juste une curiosité sur la façon d'écrire l'algorythme "bruteforce" en python. – zerkms

+0

@zerkms: Je devinais que vous avez déjà fait ça. Que je suis bête! – pyfunc

4
print sum(1 + (not i%25) + (not i%125) for i in xrange(10,201,5)) 
Questions connexes