How to calculate numbers in a given range?

-4

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:
    
asked by anonymous 23.10.2017 / 21:51

2 answers

7

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.

    
24.10.2017 / 03:53
2

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

    
23.10.2017 / 22:42