2013-12-08 4 views
2

Мне нужно написать программу, которая суммирует все целые числа, которые могут быть разделены на 3 в диапазоне от 100 до 2000. Я даже не уверен, с чего начать. У меня есть этот крошечный фрагмент кода, который неверен.Подсчитайте все целые числа в диапазоне()

for x in range(100, 2001, 3): 
     print(x+x) 

Любая помощь очень ценится!

+2

В случае, если это больше похоже на домашнее задание «изобретать алгоритм», может быть достаточно намека: число делится на три в случае, если отдельные компоненты компонентов суммируются до числа, делящегося на три (например, 948 делится на три, потому что 9 + 4 + 8 = 21, которое делится на три и т. Д. И т. Д.). –

ответ

6

выражение Использование генератора и функции сумма здесь:

res = sum(x for x in range(100, 2001) if x % 3 == 0) 

Это довольно очевидно код: вы «суммируя все числа от 100 до 2000 включительно, которые делятся на три.

+2

Вы можете удалить '[]' - не нужно материализовывать список, просто чтобы рассчитать сумму. – ThiefMaster

+0

@ThiefMaster, чтобы он стал генератором списков, не так ли? – aga

+0

@ThiefMaster, если это не материализует список, какое значение оно передает сумме? –

0

Существует sum function

>>> sum(filter(lambda x: x % 3 == 0, range(100, 2000))) 
664650 

Но это лучше:

>>> sum(x for x in range(100, 2000) if x % 3 == 0) 
664650 
+3

Неверно, потому что вы суммируете числа, не делящиеся на 3. –

+1

100 не делится на 3, так что это неверно – Max

+0

На самом деле это не так, потому что есть такая функция. но я отредактирую сообщение, спасибо, мой плохой – Deck

11

Поскольку вы знаете, что первое число в этом диапазоне, который делится на 3, 102, вы можете сделать следующее:

Решение:

>>> sum(range(102, 2001, 3)) 
664650 

Чтобы сделать это в прочную функцию :

def sum_range_divisible(start, end, divisor): 
    while start % divisor != 0: 
     start += 1 
    return sum(range(start, end, divisor)) 

С его помощью:

>>> sum_range_divisible(100, 2001, 3) 
664650 

Примечание:

Преимущества здесь в том, что вы не должны проверять каждое число во всем диапазоне, так как вы прыгаете на 3 каждый раз.


Хронометраж:

Я рассчитали различные решения, шахтные и aga's:

>>> import timeit 
>>> timeit.Timer('sum(range(102, 2001, 3))').repeat() 
[9.516391893850312, 9.49330620765817, 9.508695564438462] 
>>> timeit.Timer('sum(x for x in range(100, 2001) if x % 3 == 0)').repeat() 
[134.757627812011, 134.46399066622394, 138.34528734198346] 

Вывод:

Мой ответ быстрее фактор

+0

Не важно, что это имеет значение '3', но' while start% divisor! = 0: start + = 1' не подходит для большого 'divisor'. Может быть, 'start + = (-start% abs (divisor))'. –

+0

@InbarRose не нужно тратить время на мое решение и ваше - очевидно, что простое суммирование чисел намного быстрее, чем пересечение диапазона, который в три раза длиннее вашего, фильтруя только те числа, которые можно разделить на три без учета остаток и суммирование. :) Вы придумали элегантное решение, +1 для этого. – aga

+0

@InbarRose Мне нравится ваше решение, но решение aga включает в себя цикл, который я должен использовать. – maku

0
sum(filter(lambda l : l%3 ==0, range(100,2001))) 
+1

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

+0

Я не думаю, что мы должны обсудить новую главу лямбда здесь, по некоторым причинам я их использую, есть уже отличное обсуждение лямбда. Короче говоря, перейдите по этой ссылке https://mail.python.org/pipermail/python-dev/2006-February/060415.html – devil00

1

Для этого есть закрытая формула.

Если (u_i) представляет собой последовательность определяется его первым членом u_0 и его общая разность г, то сумма п первых членов (U_i) является:

\frac{n(u_0 + u_{n-1})}{2}

EDIT: Я есть сделал это немного video, чтобы объяснить это визуально.

A popular anecdote приписывает эту формулу молодому Иоганну Карлу Фридриху Гаусу.

В вашем случае:

  • u_0 = 102
  • u_ {п-1} = 1998
  • п = (1998 - 102)/3 + 1 = 633

Таким образом, сумма равна (633 * (102 + 1998))/2 = 664650.

В качестве общей функции Python с обычными аргументами rangestart, stop, step:

def arithmetic_series(start, stop, step): 
    number_of_terms = (stop - start) // step 
    sum_of_extrema = start + (stop - step) 
    return number_of_terms * sum_of_extrema // 2 

В вашем случае вызов будет:

arithmetic_series(102, 2001, 3) 

Сложность O (1) вместо O (п), так что неудивительно:

%timeit sum(range(102, 2001, 3)) 
100000 loops, best of 3: 17.7 µs per loop 

%timeit arithmetic_series(102, 2001, 3) 
1000000 loops, best of 3: 548 ns per loop 
Смежные вопросы