How to add the sum of cubes using a function in python? - python

I can get the answer of cubes but I don't really know where to go from here to get the function to return back the answer and keep adding it to a sum! What do I have to do to make it keep adding to get a total?
def sumNCubes(n):
for i in range(n)
return (n-1)**3
def main():
number = int(raw_input("What number do you want to find the sum of cubes for?"))
n = number + 1
for i in range(number):
n = n - 1
print "The result of the sums is:", sumNCubes(n)
main()

You could simply do something like this:
def sumNCubes(n):
return sum(i**3 for i in range(1,n+1))
which uses a list comprehension to cube number in a range from 1-n+1 (1-n will not include n) then uses python built in sum function to sum all of the cubes.
you could then just pass in your input and print it:
def main():
number = int(raw_input("What number do you want to find the sum of cubes for?"))
#this doesn't do anything but change n to 0
#for i in range(number):
# n = n - 1
print "The result of the sums is:", sumNCubes(number)
main()
with input of, for example, 5, this will return:
>>> sumNCubes(5)
225

The answer is very simple. This will be given by recursive approach.
Here is the function to find sum of N numbers and you were very close in getting this
def sumNcubes(n):
if (n == 1):
return 1
else:
return n**3 + sumNcubes(n-1)
>>>sumNcubes(6)
441

Without using n**3
def sum_cubes (n):
b, c, sum = 1, 0, 0
for a in range(0, 6*n, 6):
sum += (c := c + (b := b + a))
return sum
Without a loop
def sum_cubes (n):
return (n*(n+1)//2)**2

Related

How can I reduce my execution time for this code?

import math
class Solution:
def countSquares(self, N):
list = []
count = 0
for i in range(1,(int)(math.sqrt(N))):
square = i ** 2
list.append(square)
count = count + 1
return count
I am trying to count the number of perfect squares that are less than a given 'N'.
For example, if N = 9, the output is 2. Because only 1 & 4 are the perfect squares present.
list(map(lambda x:x*x, range(1,1+int(math.sqrt(n-1)))))
I think this should do it.
math.ceil(math.sqrt(n)) - 1
math.sqrt will output the square root of the current number.
math.ceil converts that number into the next whole number.
- 1 gives you the previous whole number, which is also the (inclusive) count of whole numbers which can be squared to a number less than n.
If you need to get the list of the square roots instead of the count the modifications are simple.
list(range(1, math.ceil(math.sqrt(n))))
In this case - 1 doesn't need to be performed so range ends with the correct number.
count = 0
for i in range(1, X):
#...
count = count + 1
ends with count == X - 1. Therefore, you don't really need a loop. You also never actually use the list, so storing it will slow down the program further.
sq = math.sqrt(N)
if math.floor(sq) < sq <= math.ceil(sq):
return int(sq)
return int(sq) - 1
Try this:
import math
class Solution:
def countSquares(self, N):
n = math.floor(math.sqrt(N))
if n * n == N:
return n - 1
else:
return n

Is there a way to make this reverse factorial code run more efficiently

I am just starting to learn python and made a program where it calculates the factorial number based on the factorial.
For example if I give the program the number 120 it will tell me it's factorial is 5
anyways my question is how can I make this code more efficient and faster.
Num = int(input())
i=0
for i in range(0,Num):
i = i + 1
x = Num/i
Num = x
if (x==1):
print(i)
Multiplications are much faster than divisions. You should try to reach the number with a factorial instead of dividing it iteratively:
def unfactorial(n):
f,i = 1,1
while f < n:
i += 1
f *= i
return i if f == n else None
unfactorial(120) # 5
A few things you can do:
Num = int(input())
i=0 # your for loop will initialize i, you don't need to do this here
for i in range(0,Num):
i = i + 1 # your for loop will increment i, no need to do this either
x = Num/i # you don't need the extra variable 'x' here
Num = x
if (x==1):
print(i)
You can rewrite this to look something like:
for index in range(1, number): # start range at 1
number /= index # this means; number = number / index
if number==1:
return index
Compute the factorials in ascending order until you reach (or exceed) the factorial you are looking for, using the previous factorial to efficiently compute the next.
def reverse_factorial(num):
i = 1
while num > 1:
i += 1
num /= i
return i
print(reverse_factorial(int(input())))

Sum of N numbers in Fibonacci

I am trying to implement the total sum of N whole numbers in Fibonacci
def fibo(n):
if n<2:
return 1
else:
res = fibo(n-1) + fibo(n-2)
sum = sum + res
return res, sum
n=7
sum = 0
for i in range(1, n):
print(fibo(i))
print("Suma", sum)
#example: if n=7 then print : 1,1,2,3,5,8,13 and sum is 32
The error I have is, when I put sum = sum + res
Doesnt print & run the program
Currently, how could you implement the total sum?
You simply need to calculate sum in the for loop, not in the fibo(n).
Here take a look:
def fibo(n):
if n<2:
return 1
else:
res = fibo(n-1) + fibo(n-2)
return res
n=7
sum = 0
for i in range(0, n):
r = fibo(i)
sum += r
print(r)
print("Suma", sum)
I used r in order to call fibo once in each loop.
Let me first point out that the sum of the first 7 terms of the Fibonacci sequence is not 32. That sum is 33. Now to the problem. Here is how I would solve the problem. I would first define the function that calculates the n th term of the Fibonacci sequence as follows:
def fibo(n):
if n in [1,2]:
return 1
else:
res = fibo(n-1) + fibo(n-2)
return res
Then I would define a function to calculate the sum of the first n terms of the Fibonacci sequence as follows.
def sum_fibo(n):
res = [fibo(i) for i in range(1, n+1)]
print(res)
return sum(res)
So if I do
[In] sum_fibo(7)
I get
[1, 1, 2, 3, 5, 8, 13]
out >>> 33
NOTE: In defining the functions above, I have assumed that the input of the function is always going to be a positive integer though the Fibonacci can be extended to cover all real and complex numbers as shown on this wiki page.
actually i don't think this needs to be that complicated the fibonacci sequence is very interesting in a maltitude of ways for example, if you want the sum up the 7th fibonacci number, then have checked what the 9th fibonacci number - 1 is? Now how do we find the n'th fibonacci number?
p = (1+5**.5)/2
q = (1-5**.5)/2
def fibo(n):
return 1/5**.5*(p**n-q**n)
and now we can can find the sum up to any number in one calculation! for example for 7
fibo(9)- 1
output
33
and what is the actual answer
1+1+2+3+5+8+13=33
summa summarum: the fibonachi number that is two places further down the sequence minus 1 is the sum of the fibonachi numbers up to the number
def sumOfNFibonacciNumbers(n):
# Write your code here
i = 1
sum = 2
fib_list = [0, 1, 1]
if n == 1:
return 0
if n == 2:
return 1
if n == 3:
return 2
for x in range(1,n-2):
m = fib_list[-1] + fib_list[-2]
fib_list.append(m)
sum = sum + m
return sum
result = sumOfNFibonacciNumbers(10)
print(result)
Made some modifications to your code:
def fibo(n):
print(1)
counter = 1
old_num = 0
new_num = 1
sum_fib = 1
while counter < n:
fib = old_num + new_num
print(fib)
if counter < n:
old_num = new_num
new_num = fib
sum_fib = sum_fib + fib
counter = counter + 1
print('sum:' + str(sum_fib))
#fibo(5)
First of all, the line sum = sum + res makes no sense because you never defined sum in the first place.
So, your function should look like
def fibo(n):
if n<2:
return 1
else:
return fibo(n-1) + fibo(n-2)
Second, you can get the sum by simply
sum_ = 0
for i in range(0, n):
sum_ += fibo(i)
Or maybe
sum_ = sum(fibo(i) for i in range(0, n))
Notice that the latter would only work if you have not overridden the built-in function named sum
You are referring the variable sum before assignment.
You may want to use the variable sum inside the for loop and assign the fibo to it.
def fibo(n):
if n<2:
return 1
else:
return fibo(n-1) + fibo(n-2)
n=7
sum = 0
for i in range(1, n):
sum += fibo(i)
print(fibo(i))
print("suma", sum)
Considering the start of the Fibonacci series with 1 rather than 0.
def fib(no_of_elements):
elements, start = [], 1
while start <= no_of_elements:
if start in [1, 2]:
elements.append(1)
elif start >= 3:
elements.append(elements[start-2]+elements[start-3])
start += 1
return elements, sum(elements)
print(fib(8))
Output:
([1, 1, 2, 3, 5, 8, 13, 21], 54)

Iterating level by level in python

For a section of my programming assignment I want to do the following.
In the level 1 I have an input number (N) which I'm dividing by another number(X).In the next level same input number (N) is divided by X*2. Likewise I want to go on calculating until the final result becomes less than or equal to 1.
For instance if X=8 and N=2 in first run I will divide 8/2=4
In the next run I will divide 8/4 which is 2
In the last run I will divide 8/8 which is 1
I'm trying to implement this in python. I have the basic idea of the code as follows:
def myFunc(n, x):
first_level=n/ x
next_level = n /x * 2
............
if result <=1:
break
myFunc(8, 2)
But I don't understand how to iterate calculating the possible next levels. Please help.
You can use a recursive function: Added the print to show that the result is equal to 1.
def myFunc(n, x):
result=n/ x
if result <=1:
print result
else:
myFunc(n,x*2)
myFunc(8, 2)
Or to get the levels you can use a global variable:
count = 1
def myFunc(n, x):
global count
count = count + 1
result=n/ x
if result <=1:
print result
else:
myFunc(n,x*2)
myFunc(8, 2)
print count
Here is a sample function that does this via iterating!
The key here is to set a temporary variable which keeps track of the current value of the loop, thus allowing you to make the division.
def myFunc(n, x):
i = 1
interim_result = n
while interim_result > 1:
interim_result = n / float(x**i) # I guess you're working with integers, but just in case
print "This is loop number: " + str(i) + " with result: " + str(interim_result)
i = i + 1
myFunc(8, 2)
Hope this is clear.

Calculating the first triangle number to have over 500 divisors in python

I'm trying to solve the 12th problem on Project Euler. I can calculate the number that has over 500 divisors in almost 4 minutes. How can i make it faster? Here's the attempt;
import time
def main():
memo={0:0,1:1}
i=2
n=200
while(1):
if len(getD(getT(i)))>n:
break
i+=1
print(getT(i))
#returns the nth triangle number
def getT(n):
if not n in memo:
memo[n]=n+getT(n-1)
return memo[n]
#returns the list of the divisors
def getD(n):
divisors=[n]
for i in xrange(1,int((n/2)+1)):
if (n/float(i))%1==0:
divisors.append(i)
return divisors
startTime=time.time()
main()
print(time.time()-startTime)
You don't need an array to store the triangle numbers. You can use a single int because you are checking only one value. Also, it might help to use the triangle number formula:n*(n+1)/2 where you find the nth triangle number.
getD also only needs to return a single number, as you are just looking for 500 divisors, not the values of the divisors.
However, your real problem lies in the n/2 in the for loop. By checking factor pairs, you can use sqrt(n). So only check values up to sqrt(n). If you check up to n/2, you get a very large number of wasted tests (in the millions).
So you want to do the following (n is the integer to find number of divisors of, d is possible divisor):
make sure n/d has no remainder.
determine whether to add 1 or 2 to your number of divisors.
Using a decorator (courtesy of activestate recipes) to save previously calculated values, and using a list comprehension to generate the devisors:
def memodict(f):
""" Memoization decorator for a function taking a single argument """
class memodict(dict):
def __missing__(self, key):
ret = self[key] = f(key)
return ret
return memodict().__getitem__
#memodict
def trinumdiv(n):
'''Return the number of divisors of the n-th triangle number'''
numbers = range(1,n+1)
total = sum(numbers)
return len([j for j in range(1,total+1) if total % j == 0])
def main():
nums = range(100000)
for n in nums:
if trinumdiv(n) > 200:
print n
break
Results:
In [1]: %cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
:def main():
: nums = range(10000)
: for n in nums:
: if trinumdiv(n) > 100:
: print 'Found:', n
: break
:
:startTime=time.time()
:main()
:print(time.time()-startTime)
:--
Found: 384
1.34229898453
and
In [2]: %cpaste
Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
:def main():
: nums = range(10000)
: for n in nums:
: if trinumdiv(n) > 200:
: print 'Found:', n
: break
:
:startTime=time.time()
:main()
:print(time.time()-startTime)
:--
Found: 2015
220.681169033
A few comments.
As Quincunx writes, you only need to check the integer range from 1..sqrt(n) which would translate into something like this for i in xrange(1, sqrt(n) + 1): .... This optimization alone vastly speeds up things.
You can use the triangle number formula (which I didn't know until just now, thank you Quincunx), or you can use another approach for finding the triangle numbers than recursion and dictionary lookups. You only need the next number in the sequence, so there is no point in saving it. Function calls involves significant overhead in Python, so recursion is usually not recommended for number crunching. Also, why the cast to float, I didn't quite get that ?
I see that you are already using xrange instead of range to build the int stream. I assume you know that xrange is faster because it is implemented as a generator function. You can do that too. This makes things a lot smoother as well.
I've tried to do just that, use generators, and the code below finds the 500th triangle number in ~16sec on my machine (YMMV). But I've also used a neat trick to find the divisors, which is the quadratic sieve.
Here is my code:
def triangle_num_generator():
""" return the next triangle number on each call
Nth triangle number is defined as SUM([1...N]) """
n = 1
s = 0
while 1:
s += n
n += 1
yield s
def triangle_num_naive(n):
""" return the nth triangle number using the triangle generator """
tgen = triangle_num_generator()
ret = 0
for i in range(n):
ret = tgen.next()
return ret
def divisor_gen(n):
""" finds divisors by using a quadrativ sieve """
divisors = []
# search from 1..sqrt(n)
for i in xrange(1, int(n**0.5) + 1):
if n % i is 0:
yield i
if i is not n / i:
divisors.insert(0, n / i)
for div in divisors:
yield div
def divisors(n):
return [d for d in divisor_gen(n)]
num_divs = 0
i = 1
while num_divs < 500:
i += 1
tnum = triangle_num_naive(i)
divs = divisors(tnum)
num_divs = len(divs)
print tnum # 76576500
Running it produces the following output on my humble machine:
morten#laptop:~/documents/project_euler$ time python pr012.py
76576500
real 0m16.584s
user 0m16.521s
sys 0m0.016s
Using the triangle formula instead of the naive approach:
real 0m3.437s
user 0m3.424s
sys 0m0.000s
I made a code for the same task. It is fairly fast. I used a very fast factor-finding algorithm to find the factors of the number. I also used (n^2 + n)/2 to find the triangle numbers. Here is the code:
from functools import reduce
import time
start = time.time()
n = 1
list_divs = []
while len(list_divs) < 500:
tri_n = (n*n+n)/2 # Generates the triangle number T(n)
list_divs = list(set(reduce(list.__add__,([i, int(tri_n//i)] for i in range(1, int(pow(tri_n, 0.5) + 1)) if tri_n % i == 0)))) # this is the factor generator for any number n
n+=1
print(tri_n, time.time() - start)
It completes the job in 15 seconds on an OK computer.
Here is my answer which solves in about 3 seconds. I think it could be made faster by keeping track of the divisors or generating a prime list to use as divisors... but 3 seconds was quick enough for me.
import time
def numdivisors(triangle):
factors = 0
for i in range(1, int((triangle ** 0.5)) + 1):
if triangle % i == 0:
factors += 1
return factors * 2
def maxtriangledivisors(max):
i = 1
triangle = 0
while i > 0:
triangle += i
if numdivisors(triangle) >= max:
print 'it was found number', triangle,'triangle', i, 'with total of ', numdivisors(triangle), 'factors'
return triangle
i += 1
startTime=time.time()
maxtriangledivisors(500)
print(time.time()-startTime)
Here is another solution to the problem.In this i use Sieve of Eratosthenes to find the primes then doing prime factorisation.
Applying the below formula to calculate number of factors of a number:
total number of factors=(n+1)*(m+1).....
where number=2^n*3^n.......
My best time is 1.9 seconds.
from time import time
t=time()
a=[0]*100
c=0
for i in range(2,100):
if a[i]==0:
for j in range(i*i,100,i):
continue
a[c]=i
c=c+1
print(a)
n=1
ctr=0
while(ctr<=1000):
ctr=1
triang=n*(n+1)/2
x=triang
i=0
n=n+1
while(a[i]<=x):
b=1
while(x%a[i]==0):
b=b+1
x=x//a[i];
i=i+1
ctr=ctr*b
print(triang)
print("took time",time()-t)

Categories