How could I compute the sum of the numbers in a range from 1 to 500 in which the summed numbers of this range must be odd and multiple of three ? >
I've only been able to do the break so far:
for c in range(3, 500, 3):
if c % 2 != 0:
How could I compute the sum of the numbers in a range from 1 to 500 in which the summed numbers of this range must be odd and multiple of three ? >
I've only been able to do the break so far:
for c in range(3, 500, 3):
if c % 2 != 0:
This question seems to be quite a common exercise in programming and I will respond as such. I have been a monitor of algorithm discipline at university and I have always noticed that students have a satiety in solving the problem without at least analyzing it.
Solution 1
The first solution I see, and certainly the simplest, is to analyze the problem mathematically, since it is ... a math problem. The sum of all numbers, within the range 1 to 500, odd and multiples of 3 are:
S = 3 + 9 + 15 + 21 + ... + 495
It's easy to see that a number is always the previous one summed in 6 (as sung in comments by Victor ). This clearly forms the sum of a progression arithmetic , from which it can be formulated:
S = (N/2)*(a_1 + a_N)
= (N/2)*(3 + 495)
Being N
the number of elements added. To calculate, we would simply analyze the expression of the general term of the progression:
a_n = a_1 + (n-1)*r
Knowing that 495 is the last element, a_N
, 3 is the first, a_1
, and the ratio is 6, r
, we have:
N = (a_N - a_1)/6 + 1
= (495 - 3)/6 + 1
= 83
So we know that there are 83 elements being added. Returning the sum formula:
S = (N/2)*(a_1 + a_N)
= (83/2)*(3 + 495)
= 20667
So the first solution would be to do:
a_1 = 3
a_N = 495
r = 6
N = (a_N - a_1)/r + 1
S = N/2 * (a_1 + a_N)
print(S)
See working at Ideone | Repl.it
Thecalculationtimeremainsconstant,regardlessoftheN
.
Solution2
Makealoopofrepetitionbetweenallvalues,checkwhichareoddandmultiplesof3and,whenadding,addinavariable:
S=0forxinrange(1,500):ifx%2!=0andx%3==0:S=S+xprint(S)
Seeworkingat Ideone | Repl.it
CalculationtimeincreaseslinearlybythevalueofN
.
Solution3
WecansimplifytheabovesolutionbyunderstandingPythonlists,alongwiththenativefunctionsum
:
S=sum(xforxinrange(1,500)ifx%2!=0andx%3==0)print(S)
Seeworkingat Ideone | Repl.it
CalculationtimeincreaseslinearlybythevalueofN
.
Solution4
Wecanfurthersimplifytheabovesolutionusingthe6-in-6intervalasappliedinthemathematicalsolution,andknowingthatthefirstvaluetobeconsideredwillbe3,wehave:
S=sum(range(3,500,6))print(S)
Seeworkingat Ideone | Repl.it
CalculationtimeincreaseslinearlybythevalueofN
.
Whymathematicalanalysiswouldbeimportantifloopingiseasier?
Performance.Witha small runtime test with the timeit
module, I took the time to run 1000 times each solution, printing the time spent :
Tempo gasto para calcular 1000x cada solução:
Solução 1: 0.0003348870013724081
Solução 2: 0.06511368200153811
Solução 3: 0.06661822800015216
Solução 4: 0.0016278160001093056
If we normalize to solution 1, which is the fastest, we have:
Solução 1: 1.0
Solução 2: 194.43478467272314
Solução 3: 198.927482186954
Solução 4: 4.8607918295971935
That is, solutions 2 and 3 take around 200x the execution time of solution 1, as solution 4 takes about 5x, because solution 1 has complexity O (1), that is, it will always do the (n), with the number of operations increasing linearly with the interval considered.
Wrong answer, fixed below in edit
Using the tips in the comment, you can do something like this:
for c in range(3, 500, 3):
soma = c + c
print(soma)
See the Ideone
Edit
Well noted by @Anderson Carlos Woss, the above answer is wrong and fixed as follows
cur = [] #declara a lista para receber os ímpares multiplos de 3
for c in range(0, 500,3): # o loop para percorrer a lista gerada pelo range
if (c % 2 != 0) and (c % 3 == 0): #checa se o valor corrente é primo e multiplo de 3
cur.append(c) #adiciona a lista
print(sum(cur)) #printa a soma dos itens da lista
See the Ideone