python project euler 6 with any number - python

I'm having trouble with Project Euler #6. The question is as follows:
Find the difference between the sum of the squares of the first one hundred natural numbers and the square of the sum.
I'm trying to write my code in such a way that what is being asked in Euler(all numbers up to and including 100) can be substituted for any number you like (all numbers up to and including x). I decided that in order to do this, you would need 3 functions. Code is:
#the sumSquare function squares every number from 0 to number called
#in the function and adds each term to a list. the function returns the sum
#of all numbers in this list
def sumSquare(num):
list1 = []
for i in range(num+1):
x = i^2
list1.append(x)
return sum(list1)
#the squareSum function adds every whole number from 0 up to and including
#the number called in the function to list2. It returns the sum squared of #every number in the list
def squareSum(num):
list2 = []
for i in range(1,num+1):
list2.append(i)
return (sum(list2) * sum(list2))
def ans(num):
return squareSum(num) - sumSquare(num)
print ans(100)
My output is 2549748 but I'm reading online that the correct solution is 25164150. Does anyone see where I am going wrong. I am just learning to code so I may be missing something that would be easy to spot by someone more experienced. But as far as I can tell, the lists are being filled with what would be the appropriate numbers before they are summed.

This
i^2
Is not a square in Python. Use i*i or i**2 for a square.

Your code is anylanguage code. But with sintax error.
Really power in Python is **
So.
Python-style code looks like that one:
print(sum(range(1, 101))**2 - sum([i**2 for i in range(1, 101)]))
Thats why they love the Python (R)

Thanks to everyone for the input. After thinking a bit more I realized just how overly convoluted this code was. I realized that if all three functions are taking the same variable to solve the problem, it can be simplified into one function that takes care of each step on its own. Came up with this solution which is obviously much more efficient:
import time
def ans(num):
numSq = []
for i in range(1, num+1):
numSq.append(i**2)
return ((sum(range(1, num+1))**2)-sum(numSq))
start_time = time.time()
print ans(100)
print "This program took {} seconds to execute.".\
format(time.time() - start_time)
Running the program you get:
25164150
This program took 0.00800013542175 seconds to execute.
Again, thanks for the input on my first post!

def diffSum():
sumSquares = 0
squareSum = 0
sumT = 0
for i in range(1,101):
sumSquares = sumSquares + (i * i)
for i in range(1,101):
sumT = sumT + i
squareSum = sumT * sumT
return squareSum - sumSquares
#sumsquares gets all the summation of the square numbers of the first 100 numbers
#sumT stores the summation of the first 100 numbers
#squareSum squares the summation of the first 100 numbers
#returns the difference between sumSquares and squareSum

Related

Calculate number of function calls for any size N

I'm trying to understand a way to write how many times the print statement for fun1 will be called for any size N. Written in summation form. This is more of an analysis question. I know I could just setup a count variable and print the result. S is an array of N items. N is the size.
def myAlg(S,n):
for i in range(1,n+1):
for j in range(1,i+1):
for k in range(1,j+1):
if j > k:
print('fun1 called, and count is now', count)
else:
print('fun2 called')
Im honestly a little lost on how to approach this. Any explanation would be greatly appreciated.
For two first loops we have sum of arithmetic progression 1+2+3+...+n, and result is
T(n) = n*(n+1)/2
known as trianglular numbers (1,3,6,10,15,21...)
So loop for k is executed T(n) times, and inner part is executed
Q(n) = sum(T(i),i=1..n) = n*(n+1)*(n+2)/6
times, sequence is known as tetrahedral numbers (1,4,10,20,35,56...)
But we have to subtract T(n) to exclude fun2 calls (one per loop)
Result = n*(n+1)*(n+2)/6 - n*(n+1)/2 = (n-1)*n*(n+1)/6
This is the same Q sequence without the last term, so
Result(n) = Q(n-1) = (n-1)*n*(n+1)/6

Finding the product of first Million natural numbers in Python

I have just started with Python programming language. I tried to write a function which takes input either a list or multiple integers to find their product. I am trying to find the product of first million natural numbers but its displaying an MemoryError.
def product(*arg):
answer=1
if type(arg) == tuple:
arg=str(arg)
arg=arg.lstrip('[(')
arg=arg.rstrip('],)')
arg=arg.split(',')
for i in arg:
answer*=int(i)
return answer
else:
for i in arg:
answer*=int(i)
return answer
j=range(1,1000000,1)
j=list(j)
print(product(j))
Steps:
I convert the range object into list object if i am to pass a list as
argument
Now, within the function, i try to split the tuple by converting it
string.
I convert the resultant string into a list and then loop over the
elements to find the product
Q1: How to avoid the memory error as i try to find the product of first Million natural numbers?
Q2 How to improve this code?
You can use a Generator in Python.
def generate_product():
r = 1
for i in range(1,1000000):
r *= i + 1
yield r
list(generate_product())[0]
It is more memory efficient and better in terms of performance.
To calculate the product of all numbers from 1 to 1 million use a simple loop:
r = 1
for l in range(1,1000000):
r*=(i+1)
print(res)
But keep in mind that the result will be a pretty big number.
That means that your calculation might take long and the resulting number will need a lot memory.
EDIT Then i missread your question a little. This is a function that multiplies the elements in a list:
def multiply_list_elements(_list):
result = 1
for element in _list:
result*=element
return result
multiply_list_elements([1,2,3,4])
>>> 24
The memory error probably came from the huge number as #ZabirAlNazi calculated so nicely.
All of the solution is fine, but one point to make - your question is equivalent to find the factorial of 1 million.
The number of digits of n! = log10(1) + log10(2) + ... log10(n)
import math
num_dig = 1
for i in range(1,1000000):
num_dig += math.log10(i)
print(num_dig)
So, the number of digits in your answer is 5565703 (approx.).
That's only the final n, if you also want the intermediate results it will require squared memory O(m^2).
import math
ans = 1
for i in range(2,1000001):
ans *= i
print(ans)
N.B: You can approximate with logarithms and Stirling numbers with faster run-time.
A very simple solution would be:
def prod_of():
p=1
for i in range(1,1000000):
p* = i
print(p)

Project Euler 92

My code for solving problem 92 was correct but too slow and hence I tried to modify it by considering only one number for each possible permutation of that number, effectively reducing the size of the problem to 11439 from the original 10 million. Here's my code
import time
from Euler import multCoeff
start = time.time()
def newNum(n):
return sum([int(dig)**2 for dig in str(n)])
def chain(n, l):
if n in l:
return n, l
else:
l.append(n)
return chain(newNum(n), l)
nums = []
for i in range(1,10000000):
if all(str(i)[j] <= str(i)[j+1] for j in range(len(str(i))-1)):
nums.append(i)
count = 0
for i in nums:
if 89 in chain(i,[])[1]:
perms = multCoeff(i)
count += perms
end = time.time() - start
print count, end
multCoeff is a method that I created which is basically equivalent to len(set(permutations([int(j) for j in str(i)])))
and works just fine. Anyway, the problem is that the result I get is not the correct one, and it looks like I'm ignoring some of the cases but I can't really see which ones. I'd be really grateful if someone could point me in the right direction. Thanks.
We're missing the code for multCoeff, so I'm guessing here.
You're trying to filter from 1 to 999,999,999 by excluding numbers that do not have digits in ascending order and then re-calculating their permutations after.
Your problem is 0.
According to your filter 2, 20, 200, 2000, 20000, 200000, 2000000 are all represented by 2, however you're probably not adding back this many permutations.
General observations about your code:
item in list has O(n) time complexity; try to avoid doing this for large lists.
You are throwing away the results of many computations; any number in a chain that results in 89 or 1 will always have that end result.
Every function call has a time cost; try to keep the number of functions in looping calls low.
Casting str to int is somewhat expensive; try to keep the number of casts to a minimum.

optimization help to find max number of divisors

I'm trying to solve problem 12 of Euler project. What is the value of the first triangle number to have over five hundred divisors? ( the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7 = 28). This is my code, but it is not fast enough..
Do you have any optimization tips?
n=0
a=0
list=[]
maxcount=0
while True:
n+=1
a+=n
count=0
for x in range(1,int(a+1)):
if a%x==0:
count+=1
if count>maxcount:
maxcount=count
print a, "has", maxcount, "dividors"
Thank you!
Start with reducing the search space, no need to look at numbers that are not triangle numbers. Also try looking at divisors in range(1, sqrt(n)) instead of range(1, n)
Grab the code from this question which implements very fast prime factorization:
Fast prime factorization module
Then use the answer to this question to convert your prime factors into a list of all divisors (the length is what you want):
What is the best way to get all the divisors of a number?
For example, you can add the following function (adapted from the second link) to the bottom of the module from the first link:
def alldivisors(n):
factors = list(factorization(n).items())
nfactors = len(factors)
f = [0] * nfactors
while True:
yield reduce(lambda x, y: x*y, [factors[x][0]**f[x] for x in range(nfactors)], 1)
i = 0
while True:
if i >= nfactors:
return
f[i] += 1
if f[i] <= factors[i][1]:
break
f[i] = 0
i += 1
Then in your code to count divisors you would use len(list(alldivisors(a))) which will calculate the number of divisors significantly more quickly than the brute force method you are currently using.
Apart from number theory: try caching, and doing things the other way around. For example: When you already know that 300 has 18 divisors (and what they are), what does that mean for a number which is dividable by 300? Can you cache such information? (sure you can.)
Pure python speedup hacks won't help you, you need a better algorithm.

Python multiplication table syntax differences

So I'm learning python as a beginner and have been using How to Think Like a Computer Scientist for python 3. I'm on the chapter about iteration, doing the coding from my own brain instead of copy/pasting so I remember it easier.
When doing the last part of the multiplication table section, I got the same output as the lesson showed, but it seems like mine is cleaner (fewer arguments). I'm still trying to get the hang of tracing programs, so I'm having a hard time wrapping my head around the differences. I was hoping someone could let me know if my code is less efficient or more error prone somehow than the text's version and help end this headache ;).
def print_multiples(n, high): #This is the e-book version
for i in range(1, high+1):
print(n * i, end=' ')
print()
def print_mult_table(high):
for i in range(1, high+1):
print_multiples(i, i+1) #They changed high+1 to i+1 to halve output
Source
It seems like their result would have too many +1's, since i+1 would become 'high' in print_multiples and then end up adding +1 again in print_multiples' loop. (I also noticed they kept the end=' ' instead of a end='\t' which threw off alignment.
def print_multiples(n): #n is the number of columns that will be made
'''Prints a line of multiples of factor 'n'.'''
for x in range(1, n+1): #prints n 2n 3n ... until x = n+1
print(n * x, end='\t') #(since x starts counting at 0,
print() #n*n will be the final entry)
def print_mult_table(n): #n is the final factor
'''Makes a table from a factor 'n' via print_multiples().
'''
for i in range(1, n+1): #call function to print rows with i
print_multiples(i) #as the multiplier.
This is mine. The elementary comments were for my benefit trying to keep the tracing straight in my head. My functions make a lot more sense to me, but there could be some difference. I don't really understand why the book decided to make two arguments for print_multiples() since 1 seems sufficient to me...I also changed most of the variables since they were using 'i' and 'high' multiple times to demonstrate local vs global. I re-used n, though, since it would be the same final number in both cases.
There might be more efficient ways to do this type of thing, but I'm still on iteration. Just hoping to try to get a feel for what works and what doesn't and this one is bugging me.
(Note: right, you're running Python 3.x)
Your code is simpler and makes more sense to me, too.
Theirs is correct, but its intention is not quite the same, so its output is different.
Carefully compare the outputs of both and see if you can notice the pattern of difference.
Your code is slightly more "efficient", but printing stuff to the screen takes a (relatively) long time, and your program prints slightly less than theirs.
To measure efficiency, you can "profile" code in Python to see how long things take.
Below is the code I ran to
a) inspect the difference in source text and output
b) profile the code to see which was faster.
You might try running it. Good luck!
import cProfile
def print_multiples0(n, high): #This is the e-book version
for i in range(1, high+1):
print(n * i, end=' ')
print()
def print_mult_table0(high):
for i in range(1, high+1):
print_multiples0(i, i+1) #They changed high+1 to i+1 to halve output
def print_multiples1(n): #n is the number of columns that will be made
'''Prints a line of multiples of factor 'n'.'''
for x in range(1, n+1): #prints n 2n 3n ... until x = n+1
print(n * x, end='\t') #(since x starts counting at 0,
print() #n*n will be the final entry)
def print_mult_table1(n): #n is the final factor
'''Makes a table from a factor 'n' via print_multiples().
'''
for i in range(1, n+1): #call function to print rows with i
print_multiples1(i) #as the multiplier.
def test( ) :
print_mult_table0( 10)
print_mult_table1( 10)
cProfile.run( 'test()')

Categories

Resources