This question already has answers here:
Sum of the integers from 1 to n
(11 answers)
Closed 3 months ago.
I have the the sum from (i = 1) to N is 1 + 2 + 3 + 4 ... + N
I found this program to calculate the sum for i in range(1,100)
num1, num2 = 1, 100
sum = int((num2*(num2+1)/2) - (num1*(num1+1)/2) + num1)
print(sum)
This works, but what if I want to know N = 10, or N = 100?
Here is a better way to do that:
def sum(n):
return int(n * (n + 1) // 2)
print(sum(10))
print(sum(100))
This program works by pairing the numbers together from the end to the beginning. For example, to find the sum of the list 1, 2, 3, 4, 5, 6, you can pair 1 and 6 to make 7, 2 and 5 to make 7, and 3 and 4 to make 7. See a pattern? (hint: the pairs always add up to the sum of the first and the last).
This program also includes an adjustment for lists with an odd number of elements. For example, in the list 1, 2, 3, one needs to add the additional middle number that cannot be in a pair. 1 and 3 can pair to 4, but you'll need to add the unpaired 2 to the sum.
Now that you understand it, all you need to do is extract it into a function. Like this:
def consecutiveSum(num2):
num1 = 1
return int((num2*(num2+1)/2) - (num1*(num1+1)/2) + num1)
print(consecutiveSum(10)) # => 55
print(consecutiveSum(100)) # => 5050
Jiho Kim's answer also points out that this can be optimized a bit. See his answer too.
Do you know the formula for calculating the sum of an arithmetic progression? In the specific case of summing from 1 through N, it is N * (N + 1) / 2. Why does a different one work in your example? Because num1 * (num1 + 1) / 2 = 1 = num1 so your method reduces to num2 * (num2 + 1) / 2.
Related
I want to make a function where given a number like 7 I want to factorise the number by as many 3s and 2s. If left with a remainder then return -1.
Note: Through further examples it seems any number can be made up of the addition of multiples of 3s and 2s so -1 for remainder not needed. Goal is to get as many multiples of 3 before having to add multiples of 2 to factorise completely
For example given the number 11 I want the function to return 3:3 and 2:1 as 3 fits into 11 3 times and 2 once ie. 3+2+2=7, 3+3+3+2=11, 3+3+3+2+2=13. The preference should be being able to fit as many 3s first.
This is part of a wider problem:
from collections import Counter
#Choose two packages of the same weight
#Choose three packages of the same weight
#Minimum number of trips to complete all the deliveries else return -1
def getMinimumTrips(weights):
weights_counted = Counter(weights)
minimum_trips = 0
print(weights_counted)
for i in weights_counted:
if weights_counted[i]==1:
return -1
elif weights_counted[i]%3==0:
minimum_trips += (weights_counted[i]//3)
elif weights_counted[i]%2==0:
minimum_trips += (weights_counted[i]//2)
return minimum_trips
print(getMinimumTrips([2, 4, 6, 6, 4, 2, 4]))
Possible solution:
#Looking at inputs that are not a multiple of 3 or 2 eg, 5, 7, 11, 13
def get_components(n):
f3 = 0
f2 = 0
if n%3==1:
f3 = (n//3)-1
f2 = 2
elif n%3==2:
f3 = (n//3)
f2=1
return f"3:{f3}, 2:{f2}"
If we are given some integer value x we have 3 different cases:
x == 3 * n, solution: return 3 n times. The easiest case.
x == 3 * n + 1, solution: return 3 n - 1 times, then return 2 2 times, Note that we can put 3 * n + 1 == 3 * (n - 1) + 2 + 2
x == 3 * n + 2, solution: return 3 n times, then return 2.
As one can see in cases #1 and #3 solutions ever exist; in case #2 there's no solution for x = 1 (we can't return 3 -1 times). So far so good if x <= 1 we return -1 (no solutions), otherwise we perform integer division // and obtain n, then find remainder % and get the case (remainder 0 stands for case #1, 1 for case #2, 2 for case #3). Since the problem looks like a homework let me leave the rest (i.e. exact code) for you to implement.
This will return 0 if you can completely factorise the number, or -1 if 1 is remaining:
return -(i % 3 % 2)
If this helps?
Try this method using math.floor()
import math
def get_components(n: int) -> str:
q3 = math.floor(n / 3)
q2 = math.floor(q3 / 2)
if not (q3 and q2):
return '-1' # returning '-1' as a string here for consistency
return f'3:{q3}, 2:{q2}'
I know how to code a function for the factorial of a number but I am not sure why it works.
def factorial (num):
ans = 1
for i in range (1,num + 1):
ans *= i
return (ans)
In my mind ans remains one and is multiplied by every index on 1 through nums + 1. So it would look like: (1 * 1, 1 * 2, 1 * 3,...). How does this function lead to the factorial of the number in the parameter?
Why not introduce some print statements in your code to see what is going on?
def factorial(num):
ans = 1
for i in range(1, num + 1):
print(f" ans = {ans}, going to multiply by {i}")
ans *= i
return ans
print("Trying to find the factorial of 5")
final = factorial(5)
print(f"Final answer is: {final}")
This gives:
Trying to find the factorial of 5
ans = 1, going to multiply by 1
ans = 1, going to multiply by 2
ans = 2, going to multiply by 3
ans = 6, going to multiply by 4
ans = 24, going to multiply by 5
Final answer is: 120
So bottom line, you need to better understand what *= is doing in ans *= i (aka in-place operators), see here: https://docs.python.org/3/library/operator.html#in-place-operators
a *= b means :
take the content of a,
multiply it by b,
and store the result into a again.
(a in my example is ans for you)
So there is one variable, the same is used for every iteration. There is no list or such as you think it does, that takes the role of growing until the big final result.
ans starts at the value of 1, then will be multiplied by 2, and the result will replace it so it becomes 2, then will be multiply by 3, so it becomes 1 * 2 * 3 = 6, etc..
By the way, sometimes we call this kind of variable an "accumulator", in algorithmics.
Note the usage of the *= operator - in each iteration of the loop ans is multiplied by i, and the result saved back to ans.
Let's look at the first couple of iterations:
i=1 - ans * i is 1*1, or 1, which is saved back in ans.
i=2 - ans * i is 1*2, or 2, which is saved back in ans.
i=3 - ans * i is 2*3, or 6, which is saved back in ans.
... and so on.
I am trying to create a program that will find every number with a square root, cube root, quarter root, and quintuple root under 2^60. Every time I run the command I get only every square number, which is what I programmed variable Num1 to be.
code:
Num = 1
Num1 = 1
while Num1 < 1152921504606846976:
Num += 2
Num1 += Num
Num2 = Num1 ** 0.5
Num3 = Num1 ** 0.33333333333333333333
Num4 = Num1 ** 0.25
Num5 = Num1 ** 0.2
if Num1 > Num:
float(Num2).is_integer()and float(Num3).is_integer()and float(Num4).is_integer() and float(Num5).is_integer()
print Num1
else:
null
Sorry for bad code I am REALLY new to this.
Num2 - Num5 are the answers of the number Num1 being rooted, and if they are all integers my goal is to have a print command give the original number, Num1
As Julien pointed out using floats in this probem is problematic due to the precision issues. Furthermore, you are doing an iteration until 2 ^ 60, which may be pretty slow.
Simple but slow approach
A simple approach would be generate all the integers that have square roots, then all the integers that have cubic roots, and so on. After that, do an intersection of all the numbers we generated so far.
That process can be done easily, we need to iterate from 1 until n^(1/k) to generate numbers that have kth-roots, if i^k is less or equal than our max number, then we have found an kth-root. The code:
def kth_roots(n, k):
i = 1
ans = []
while i ** k <= n:
ans.append(i ** k)
i += 1
return ans
n = 2 ** 60
two = kth_roots(n, 2)
three = kth_roots(n, 3)
four = kth_roots(n, 4)
five = kth_roots(n, 5)
answer = set(two) & set(three) & set(four) & set(five)
print(answer)
An approach based on divisibility
I will propose an answer asuming that you will have your maximum number expressed as a power in the form x ^ y.
Note that, a number will have an integer square root if it can be expressed as b ^ e, such that e is divisible by two, it will have a integer cube root if e is divisible by three, and so on. So a better approach, is to check which exponents will satisfy your conditions (divisibility by 2, 3, 4, and 5). Finally we must determine the value of b, we can brute force, and stop whenever it is greater than x ^ y.
In this way we do not have to play with float numbers that may be a headache here. Some code:
max_exp = 60
max_base = 2
maxm = max_base ** max_exp
ans = 0
e = 1
print(1) # Trivial case
while True:
if e % 2 == 0 and e % 3 == 0 and e % 4 == 0 and e % 5 == 0:
b = 2
flag = False
while b ** e <= maxm:
flag = True
print(b ** e)
b += 1
if flag is False:
break
e += 1
EDIT: As Hugh Bothwel mentioned, the divisibility check on the powers can be reduced to compute the LCM of [2,3,4,5], that would be 60, so any number a^60 have the mentioned integer roots. All that remains is to brute force the values of a. The code:
from fractions import gcd
def _lcm(x, y):
return (x * y) // gcd(x, y)
maxm = 2 ** 60
lcm = reduce(_lcm, [2, 3, 4, 5], 1)
a = 1
while a ** lcm <= maxm:
print(a ** lcm)
a += 1
Given a number and a ratio, how do I create an exponentially growing list of numbers, whose sum equals the starting number?
>>> r = (1 + 5 ** 0.5) / 2
>>> l = makeSeq(42, r)
>>> l
[2.5725461188664465, 4.162467057952537, 6.735013176818984,
10.897480234771521, 17.63249341159051]
>>> sum(l)
42.0
>>> l[-1]/l[-2]
1.6180339887498953
>>> r
1.618033988749895
A discrete sequence of exponentially growing numbers is called a geometric progression. The sum is called a geometric series. The formula here can easily be solved to produce the sequence you need:
>>> n = 5
>>> r = (1 + 5 ** 0.5) / 2
>>> r
1.618033988749895
>>> total = 2.28
>>> a = total * (1 - r) / (1 - r ** n)
>>> a
0.13965250359560707
>>> sequence = [a * r ** i for i in range(n)]
>>> sequence
[0.13965250359560707, 0.22596249743170915, 0.36561500102731626, 0.5915774984590254, 0.9571924994863418]
>>> sum(sequence)
2.28
>>> sequence[1] / sequence[0]
1.618033988749895
>>> sequence[2] / sequence[1]
1.618033988749895
>>> sequence[2] / sequence[1] == r
True
It's also worth noting that both this problem and the original problem of the Fibonacci could be solved using a binary search / bisection method.
Pick any sequence of Fibonacci numbers you want. Add them up, and divide your target number by the sum to get a scaling factor. Multiply each number in your chosen sequence by the scaling factor, and you'll have a new sequence that sums to your target, and has the same ratio of adjacent terms as the original sequence of Fibonacci numbers.
To generate the example in your question, note that 1 + 2 + 3 + 5 + 8 = 19, and 2.28/19 = 0.12.
The Fibonacci sequence goes as follows: 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ... etc. As you may have already seen in the comments on your question, the Fibonacci sequence itself doesn't "scale" (i.e., fib_seq * 0.12 = 0, 0.12, 0.12, 0.24, 0.36, 0.60, 0.96 ... etc. isn't the Fibonacci sequence any longer), so you you can really only make a Fibonacci series in the order the values are presented above. If you would like to make the Fibonacci sequence dynamically scalable depending on some criteria, please specify further what purpose that would serve and what you are having trouble with so that the community can help you more.
Now, let's start with the basics. If you've had trouble with implementing a function to print the Fibonacci Sequence in the first place, refer to the answer #andrea-ambu gives here: https://stackoverflow.com/a/499245/5209610. He provides a very comprehensive explanation of how to not only implement the Fibonacci Sequence in a function in any given language, but even goes further to explore how to do so efficiently!
I presume that you are trying to figure out how to write a function that will take a user-provided integer and print out the Fibonacci series that sums up to that value (i.e., print_fib_series(33) would print 0 + 1 + 1 + 2 + 3 + 5 + 8 + 13). This is fairly easily achievable by just incrementally adding the next value in the Fibonacci series until you arrive to the user-provided value (and keeping track of which values you've summed together so far), assuming that the user-provided value is a sum of Fibonacci series values. Here's an easy implementation of what I just described:
# Recursive implementation of the Fibonacci sequence from the answer I linked
def fib_seq(ind):
if ind == 0:
return 0;
elif ind == 1:
return 1;
else:
return fib_seq(ind - 1) + fib_seq(ind - 2);
def list_fib_series(fib_sum, scaling_factor):
output_list = [];
current_sum = 0;
for current_val in fib_seq():
current_sum += current_val * scaling_factor;
output_list.append(current_val);
if current_sum == fib_sum:
return output_list;
elif current_sum > fib_sum:
return 0; # Or you could raise an exception...
fib_list = list_fib_series(2.4, 0.12):
print ' + '.join(map(str, fib_list));
So, considering the decimal value of 2.4 you could apply a linear scaling factor of 0.12 to the Fibonacci series and get the result you indicated in your question. I hope this helps you out!
Forget about the decimal numbers, like julienc mentioned program would never know where to start from if you bend the 'definition of Fibonacci series' like the way you wish to. You must be definitive about fibonacci series here.
For whole numbers and actual definition of fibonacci series, best you can do is make a program which takes number as input and tells whether the number sums up to some fibonacci series. And if it does then print the series. Assuming this is what you want.
a = 33
f_list = []
def recur_fibo(n):
if n <= 1:
return n
else:
return(recur_fibo(n-1) + recur_fibo(n-2))
i=0
total = 0
while True:
num = recur_fibo(i)
total += num
f_list.append(num)
if total > a:
print "Number can not generate fibonacci series"
break
elif total == a:
print "Series: %s" % f_list
break
i +=1
Output:
Series: [0, 1, 1, 2, 3, 5, 8, 13]
Based off of Alex Hall's answer, this is what I ended up using:
def geoProgress(n, r=(1 + 5 ** 0.5) / 2, size=5):
""" Creates a Geometric Progression with the Geometric sum of <n>
>>> l = geoProgress(42)
>>> l
[2.5725461188664465, 4.162467057952537, 6.735013176818984,
10.897480234771521, 17.63249341159051]
>>> sum(l)
42.0
>>> l[-1]/l[-2]
1.6180339887498953
"""
return [(n * (1 - r) / (1 - r ** size)) * r ** i for i in range(size)]
print "This program computes and prints the sum of all even values"
print "between 2 and a positive integer value entered by the user. \n"
integer = input("Enter a positive integer: ")
while integer <2:
if integer <2:
print "Integer must be greater than 2!"
integer = input("Enter a positive integer: ")
else:
integer2 = input("Now enter a second integer: ")
evens = (integer - integer2)/2 + 1
while True
I have to be able to ask the user for two numbers, and then my program should be able to add up all of the even numbers between the two numbers. I just started programming, so I haven't learned much. I tried looking around for answers, but the answers here didn't make any sense to me because they were using techniques that were too advanced for me. Thanks!
Here's a quick example using the interactive shell:
>>> x = 9
>>> y = 31
>>> sum([z for z in range(x, y + 1) if z % 2 == 0])
220
This uses something called list comprehension and the built-in method sum.
Now, for an explanation on how this all works together:
Range, as you already know, returns a list of numbers between its two arguments.
>>> range(x, y + 1)
[9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]
The modulo operator (%) is used to divide two numbers and then give you the remainder. This makes it very handy to find even numbers: any even number divided by 2 will have a remainder of 0.
>>> 5 % 2
1
>>> 4 % 2
0
The list comprehension uses this trick to build a list of values containing every even number in the given range.
>>> [z for z in range(x, y + 1) if z % 2 == 0]
[10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30]
Finally, sum() iterates and adds up all the values generated by that list for you.
>>> sum([z for z in range(x, y + 1) if z % 2 == 0])
220
This should do the trick:
start = 0
end = 0
while start < 2 or end <= start:
start = int(raw_input("Enter start -> "))
end = int(raw_input("Enter end ->"))
total = 0
for x in range(start, end+1):
if x % 2 == 0:
total += x
print total
You can make it even more succinct using list comprehensions:
start = 0
end = 0
while start < 2 or end <= start:
start = int(raw_input("Enter start -> "))
end = int(raw_input("Enter end -> "))
print sum([x for x in range(start, end+1) if x % 2 == 0])
Not that for both range functions, I have used end+1 because range will only go up to the number before the second parameter to the function.
Once you have the two numbers you need to find all even ones between them, right?
Well, to find all the numbers between them you use range(integer,integer2+1) (the +1 is there because I'm assuming you want it including the integer2).
To find all even numbers in that range you use filter(lambda x: x%2==0, range(integer, integer2+1)) and then to sum it all you use sum().. so in the end:
sum(filter(lambda x: x%2==0, range(integer, integer2+1)))
In order to generate a list of integers you can use the range function.
range(10, 20)
>> [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
Given a list of integers you can filter it by using a list comprehension.
[number for number in [1, 2, 3, 4, 5, 6] if not number % 2]
>> [10, 12, 14, 16, 18]
Given a list of integers, you can calculate the sum by using the built-in sum function.
sum([1, 2, 3])
>> 6
You can combine all this and obtain your answer in a simple statement.
sum([even for even in range(10, 20) if not even % 2])
>> 70
All the answers given address the problem, but in a different way than you are trying to (IE, using an equation instead of either language features or a basic loop... which will degrade in performance if passing in a very large range), so let me try and help you with your equation.
There are a couple things going wrong. Probably the most fundamental issue is the logic behind your expression.
For example, what do you expect the output of the following inputs to be vs what your expression should output...
Assuming absolute value and floor rounding...
(5, 7), expect 1, (5 - 7) / 2 + 1 = 2
(6, 8), expect 0, (6 - 8) / 2 + 1 = 2
(6, 7), expect 0, (6 - 7) / 2 + 1 = 1
It seems that you need to detect if one of the integers is in fact even... integer % 2 == 0
so for an exclusive range...
(6, 8), expect 0, (6 - 8) / 2 = 1, 6 is even so subtract 1 => 0
(5, 7), expect 1, (5 - 7) / 2 = 1, 5 is odd so do nothing => 1
(6, 7), expect 0, (6 - 7) / 2 = 0.5 (round up to 1), 6 is even, so subtract 1 => 0
(7, 8), expect 0, (7 - 8) / 2 = 0.5 (round up to 1), 8 is even, so subtract 1 => 0
(7, 10), expect 1, (7 - 10) / 2 = 1.5 (round up to 2), 10 is even, so subtract 1 => 1
Now, I think this should work for all input values. Lets modify the code.
import math
....
evens = math.ceil(math.fabs((integer - integer2) / 2.0))
if integer % 2 == 0 or integer2 % 2 == 0:
evens -= 1
And if you want to make it for an inclusive range, IE (6, 8) returns 2...
evensInclusive = evens + (integer + 1) % 2 + (integer2 + 1) % 2
First, your opening print statements mis-state what the program is supposed to do.
Second, be very specific. Do you wish to include the endpoints in the sum if they are even? The problem statement, as given, does NOT include them.
Third, use your head before you program anything. The sum of all even integers, starting from 2, and ending at 2N is N(N+1). If you start instead from another even number, 2L, where 2L>2, then you merely have to subtract out the part from 2 to 2L-2. But you know what that is: it's (L-1)L, where all I did was substitute L-1 for N in the "sum of all even integers starting from 2" equation. So, the sum of all even integers, starting from 2L and ending at 2N is
N(N+1)-(L-1)L, where 2L and 2N are included in the sum.
Fourth, set up code to make sure you are using the correct start/end points. Keep in mind that the user might use 2 evens, 2 odds, odd-even, or even-odd. You have to account for all cases.
Fifth, while you are testing any program, print out as many intermediate values as you can. That will make any bugs obvious. You can comment out those print statements later.
Sixth, test your program on easy cases.
def addEvenNumbers(num, num1):
total=0
for v in range(num,num1+1):
if v>=0 and v % 2 == 0:
total+=v
return total