2010-10-26 4 views
5

Я написал программу для проверки правильности моей мысли о решении на бумаге (и это так).Упростите этот код python

Задача: сколько нулей в спину умножения всех чисел от 10 до 200.

Это 48, и это просто вычислить вручную.

Я никогда не пишу на питоне серьезно и это то, что я получаю:

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 

Я держал пари, что можно написать то же самое более элегантно на таком языке, как питон.

пс: да, это домашнее задание, но не мой - я просто помог парню ;-)

ответ

11

Прямая вперед реализация, которая не включает в себя вычисление факториала (так, что он работает с большими числами, то есть 2000000) (отредактированный):

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

Было бы неплохо, если бы я мог понять, как это работает. –

+3

Он подсчитывает количество пятерок и двойников в простой факторизации факториала итеративно (так что 10! Будет иметь 2 пятых и 8 двоек). Так как 5 * 2 = 10, и никакие другие простые числа не могут быть умножены на 10, число 10 в факторизации (которое является числом конечных нулей) является минимумом числа fives и числа двойников в прайме факторизации. Количество пятерок и двойников намного меньше расчетного факториала. – irrelephant

+3

Хотя вопрос действительно требует 10-200, это, безусловно, лучший подход для гораздо большего числа. Для меньших чисел, фактически выполнение умножения делает ауты быстрее (по крайней мере, когда я запускал тесты времени). – 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)) 

Вторая строка вычисляет продукт, третий получает итератор всех замыкающие нулей в том, что number, последний печатает число этих нулей.

+2

Может заменить 'лямбда х, у: х * y' с' operator.mul' –

+0

И '' range' с xrange' (хотя в этом случае это было бы незначительно) –

+0

@Brendan Long: поскольку мы alwa ys итерации от начала до конца диапазона - вообще не «xrange» накладные расходы? – zerkms

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

Это какой-то уродливый Python ... –

+1

, но красивый, если вы в функциональный программирование, взгляд смотрителя и все! –

+3

Я бы не сказал, что это очень функционально. Вы не видите много регулярных выражений в функциональном программировании. –

6
import math 

answer = str(math.factorial(200)/math.factorial(9)) 
count = len(answer) - len(answer.rstrip('0')) 
  1. Импорт математическая библиотека
  2. Вычислить factorial 200 и заберите первые 9 число
  3. стирают нули справа и выяснить разницу в длине
+0

Самая лаконичная в данный момент – zerkms

+0

Не будет 'сокращение (operator.mul, xrange (10, 200 + 1))' более эффективным, чем факториалы + деление? –

+0

@Brendan Long: все ответы оценены, но я проверю самый элегантный: -P – zerkms

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

Вы имеете в виду zeroes? Что такое null в противном случае?

Не могла бы ли какая-нибудь математика упростить?

Сколько 5s в 200 Len ([х для й в диапазоне (5, 201, 5)]) = 40

Сколько 25s в 200 LEN ([х для й в диапазоне (25, 201, 5), если x% 25 == 0]) = 8

Сколько 125 секунд в 200 является len ([x для x в диапазоне (120, 201, 5), если x% 125 == 0]) = 1

Всего 5с = 49

200! = 5^49 * 2^49 * (другие числа не делится на 2 или 5)

Так Есть 49 нулей

+0

Чтобы быть ясным - это 48, а не 49 ;-) И я решил это вручную таким же образом. Текущий вопрос - это просто любопытство о том, как написать алгоритм «bruteforce» в python. – zerkms

+0

@zerkms: Я предполагал, что вы, должно быть, уже это сделали. Дурак я! – pyfunc

4
print sum(1 + (not i%25) + (not i%125) for i in xrange(10,201,5)) 
Смежные вопросы