Project Euler #2 in Python - python

Background
I am stuck on this problem:
Each new term in the Fibonacci sequence is generated by adding the previous two terms. By starting with 1 and 2, the first 10 terms will be:
1, 2, 3, 5, 8, 13, 21, 34, 55, 89, ...
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
I tried to discover if the issue was my Fibonacci number generator, the code which gets the even numbers, or even the way that I add the numbers to no avail.
Code
I decided to store the numbers in lists. Here, I create them.
list_of_numbers = [] #Holds all the fibs
even_fibs = [] #Holds only even fibs
Then, I created my generator. This is a potential area of issues.
x,y = 0,1 #sets x to 0, y to 1
while x+y <= 4000000: #Gets numbers till 4 million
list_of_numbers.append(y)
x, y = y, x+y #updates the fib sequence
Then, I created some code to check if a number is even, and then add it to the even_fibs list. This is another weakpoint in the code.
coord = 0
for number in range(len(list_of_numbers)):
test_number = list_of_numbers [coord]
if (test_number % 2) == 0:
even_fibs.append(test_number)
coord+=1
Lastly, I display the information.
print "Normal: ", list_of_numbers #outputs full sequence
print "\nEven Numbers: ", even_fibs #outputs even numbers
print "\nSum of Even Numbers: ", sum(even_fibs) #outputs the sum of even numbers
Question
I know that this is a terrible way to ask a question, but what is wrong? Please don't give me the answer - just point out the problematic section.

You're stopping when the sum of the next two values in the sequence is greater than 4,000,000. You're meant to consider all values in the sequence up to 4,000,000.

Related

Project Euler 12 on Python

So I'm solving Problem 12 of Project Euler in Python. There's the task:
The sequence of triangle numbers is generated by adding the natural
numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 +
7 = 28. The first ten terms would be:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
Let us list the factors of the first seven triangle numbers:
1: 1 3: 1,3 6: 1,2,3,6
10: 1,2,5,10
15: 1,3,5,15
21: 1,3,7,21
28: 1,2,4,7,14,28 We can see that 28 is the first triangle number to have over five divisors.
What is the value of the first triangle number to have over five
hundred divisors?
I made 2 functions: first will generate triangle numbers infinitely:
def triangle_number(n_th_triangle, triangle_sum_number, triangle):
while True:
n_th_triangle += 1
while triangle_sum_number < n_th_triangle:
triangle_sum_number += 1
triangle += triangle_sum_number
print(triangle)
triangle_number(0, 0, 0)
second one will count, how many divisors has the given number:
def divisor_number(divisor, divisor_number, number):
while divisor < number:
divisor += 1
if number % divisor == 0:
divisor_number += 1
print(number)
print(divisor_number)
divisor_number(0, 0, *number*)
How to slap them together ? So that will be the solution of the 12 th problem on Project Euler.
Thanks!
First, you should return these values rather than print them.
As others have mentioned, using the yield keyword will allow you to return values to the caller without suspending function execution and deleting everything you already computed from the stack. Here is a pretty good tutorial on using generators in python.
Then, once you implement triangle_number() as a generator, you could have a simple loop such as the following:
tri_gen = triangle_number()
while(divisor_number(num)) <= 500:
num = next(tri_gen)
Some pointers:
you should yield the next triangle number instead of just printing it
you do not have to declare all internal variables as parameters
do not test all possible divisors, this will be much too slow
Instead, you can try the following:
calculate the first few thousand prime numbers using an efficient algorithm
use those to calculate the prime factorization of the number, e.g. [2, 5, 5] for 50; use divide an conquer and memoization to speed this up 1
finally, use the prime factorization to efficiently calculate the total number of divisors
Just for perspective, the result is a >> 10k-th triangle number and is somewhere around 75M.
1) As noted in comments you can use the fact that sum(1..n), and thus the n-th triangle number, is n(n+1)/2 and use that to find the prime factorization (and thus the divisors) much easier.

Euler Project problem #12 Python code gives weird results

I was trying to solve problem number 12 of Project Euler. This is the problem:
The sequence of triangle numbers is generated by adding the natural
numbers. So the 7th triangle number would be 1 + 2 + 3 + 4 + 5 + 6 + 7
= 28. The first ten terms would be:
1, 3, 6, 10, 15, 21, 28, 36, 45, 55, ...
Let us list the factors of the first seven triangle numbers:
1: 1
3: 1,3
6: 1,2,3,6
10: 1,2,5,10
15: 1,3,5,15
21: 1,3,7,21
28: 1,2,4,7,14,28
We can see that 28 is the first triangle number to have over five
divisors.
What is the value of the first triangle number to have over five
hundred divisors?
I defined two functions to do the job:
1) allfactor(x): This gives us all the factors of a given number in a list form. Example: allfactor(10) gives us [1, 2, 5, 10]
2)TriangularNo(x): This gives us the nth Triangular number. Example TriangularNo(5) gives us 5
Here is the complete code which I wrote:
facs=[]
def allfacof(x):
for i in range(1,int(x/2)+1):
if x%i==0:
facs.append(i)
else:
pass
facs.append(x)
return(facs)
def TriangularNo(x):
no=0
for i in range(1,x+1):
no=no+i
return(no)
a=0 # a will tell us the number of iterations
while True:
a+=1
N=TriangularNo(a)
length=(len(allfacof(N)))
if int(length)>=500:
print(N)
break
else:
pass
When I run this code I get 1378 as the output which is clearly wrong because len(allfacof(1378)) turns out to be 8 and not 500 as demanded in the question.
Notice in the while loop, I use if int(length)>=500: So this means that when my code runs, length somehow gets the value = 500 but when I run the function separately it says that it's length is 8.
I am just not able to find out the error. Please help me
The problem is you are using facs as a global variable and you are only appending to the item. You should make it a member of allfacof() so that it clears out after each value.
If you look into facs then you will find it equals
1, 1, 3, 1, 2, 3, 6, 1, 2, 5, 10 ...
Although moving facs into all_factors_of() solves your immediate problem, the next problem with this code is performance. Let's consider triangle number generation first. The optimization that #Voo suggests:
def TriangularNo(n):
return n * (n + 1) / 2
is fine if we're looking for arbitrary triangle numbers -- but we're not. We're looking for sequential triangle numbers, so in this case the formula slows down our code! When going sequentially, you only need do a couple of additions to get the next triangle number -- but using the formula, you need to do an addition, a multiplication and a division! More expensive if you're going sequentially. Since we are going sequentially, this seems a perfect use of a Python generator:
def triangular_number_generator():
triangle = number = 1
while True:
yield triangle
number += 1
triangle += number
Which makes clear the two additions needed to get to the next triangle number. Now let's consider your factorization function:
Your factorization function loses performance in the way that it produces factors in order. But we're only concerned with the number of factors, order doesn't matter. So when we factor 28, we can add 1 and 28 to the factors list at the same time. Ditto 2 and 14 -- making 14 our new upper limit. Similarly 4 and 7 where 7 becomes the new upper limit. So we collect factors faster and quickly reduce the upper limit that we need to check. Here's the rest of the code:
def factors_of(number):
divisor = 1
limit = number
factors = []
while divisor <= limit:
if number % divisor == 0:
factors.append(divisor)
remainder = number // divisor
if remainder != divisor:
factors.append(remainder)
limit = remainder - 1
divisor += 1
return factors
triangular = triangular_number_generator()
number = next(triangular)
factors = factors_of(number)
while len(factors) <= 200:
number = next(triangular)
factors = factors_of(number)
print(number)
How does it compare? If we run your fixed code with a lower limit of > 200 factors, it takes about a minute to come up with the answer (2031120). The above code takes about 1/3 of a second. Now consider how long it'll take both to reach > 500 factors. Finally, to meet the stated goal:
What is the value of the first triangle number to have over five
hundred divisors?
this comparison in your original code:
if int(length)>=500:
would instead need to be:
if length > 500:
Though the way the count of factors jumps, it makes no difference for 500. But for smaller limits, for testing, it can make a difference.

How to further optimize calculating all the cross sums?

I had some spare time yesterday and somehow thought about calculating cross sums.
My goal is to calculate all the sums up to a given number n. Don't ask why - it's just for fun and to learn stuff.
So for n = 11 I want my result to look something like this: [1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2]
This is my code:
def dynamicCheckSumList(upperLimit):
dynamicChecksumList = []
for i in range(0, 10):
dynamicChecksumList.append(i)
for i in range(10, upperLimit+1):
length = getIntegerPlaces(i)
size = 10**(length-1)
firstNumber = i // size
ancestor = i-(firstNumber*size)
newChecksum = firstNumber + dynamicChecksumList[ancestor]
dynamicChecksumList.append(newChecksum)
return dynamicChecksumList
At first I create my empty list and then populate the numbers 0-9 with their respective trivial sums.
Then I look at all numbers above 9 until the upper limit. Get their length. I then continue with finding out the first digit of the number. After that I calculate the number without that leading digit. For example: If my i is 5432 I will get 432. Since I already saved the cross sum for 432 I can just add that cross sum to my leading digit and I'm basically done.
def getIntegerPlaces(theNumber):
if theNumber <= 999999999999997:
return int(math.log10(theNumber)) + 1
else:
counter = 15
while theNumber >= 10**counter:
counter += 1
return counter
The second function is something I found here at a question of something asking on how to calculate the number of digits in a given number.
Is there any way in here (I guess there will be) to speed up things?
Also appreciated would be tips on how to save on memory. Just for fun I tried to set n to 1 billion. And my memory (16GB) kind of exploded ;)
def digitSums2(n):
n = (n + 9) // 10 * 10 # round up to a multiple of 10
result = bytearray(range(10))
for decade in range(1, n//10):
r_decade = result[decade]
for digit in range(10):
result.append(r_decade + digit)
return result
There are two primary differences are:
bytearray uses a single byte per calculated value, which saves a lot of memory. It only allows numbers up to 255, but it is sufficient for numbers that have less than 26 digits.
Peeling of the last digit is much easier then peeling of the first one.
This should be about as fast as possible in python. Be careful with printing results, since it can take more time than calculation itself (especially if you do in-memory copies).

python - print the sum of items in list whose total is the largest and is odd

It's a simple problem I have been trying to solve. First of all I take input with a list of positive integers. I want to choose items from them in such a way that their total is maximum possible and their sum is odd. If no combination is possible I want to print -1. I have written the code and it is not working properly.
l = sorted(list(map(int, input().split())))
if sum(l)%2 == 1:
print(sum(l))
else:
m = 0
for x in range(len(l)):
a = l
a.pop(x)
if sum(a)%2 == 1 and sum(a) > m:
m = sum(a)
For example, for the input 2 3 4 5, it's printing 9 where it should print 11.
Any help would be appreciated.
So, from the list of numbers, you want to get the largest possible sum which is odd. This is actually rather simple and can be solved pretty easily. What you need to do is take the sum of all numbers as that is the maximum sum that you could possibly get from those numbers. Now, we have two options:
The sum is odd: In that case, we’re already done. The largest possible sum is also odd, so we have our result.
The sum is even: In that case, we have the largest possible sum but we are not odd. In order to fix that we need to remove the smallest odd number from the sum. So we look at the sorted list of numbers and pick the first odd number from it. By removing an odd number from an even sum, we get an odd number again, and since we picked the smallest possible number, we know our new sum is the largest odd sum. So that’s the result.
In code, this could look like this:
def largestOddSum(numbers):
s = sum(numbers)
if s % 2 == 1:
return s
for x in sorted(numbers):
if x % 2 == 1:
return s - x
return -1
Used like this:
>>> largestOddSum([2, 3, 4, 5])
11
In a easy way :
sum all and subtract the minimum odd number if first sum is even :
if sum(l)%2 == 1:
print(sum(l))
else:
print(sum(l) - [i for i in sorted(l) if i%2==1][0])
I think the best way to tackle this is by remembering that:
even + even = even
odd + even = odd
odd + odd = even
With this in mind, you can always include all even numbers. You can also always include all odd numbers, as long as the number of odd numbers is not even. If the number of odds IS even, just leave the smallest out.

Writing a Python program that finds the square of a number without using multiplication or exponents?

thank you for reading and hopefully responding to my question. I'm stuck trying to write this Python program that finds a number's square without using multiplication or exponents. Instead, I have to get the summation of the first odd n numbers starting from 1. This is what I have so far:
def square():
print("This program calculates the square of a given number")
print("WITHOUT using multiplication! ")
odd = 1
n = eval(input("Enter a number: "))
for odd in range(0, n + 1, 2):
odd = odd + 2
final_square = n + odd
print(n, "squared is", final_square, ".")
EDIT: Hi guys, I can't do 4 + 4 + 4 + 4. I have to do 1 + 3 + 5 + 7, and I'm not sure how. It gives me 4 squared is 11 or something.
Just some tips:
Try not to use eval(), it will evaluate any input given and so it can do something you don't want to do. Instead, use int().
Remember that, say 4*4, is just 4 + 4 + 4 + 4. You're on the right track with a for-loop, but now make the loop iterate n times adding n to itself.
new = 0
for _ in range(n):
new += n
Note that this won't work with negative numbers. If you're going to be dealing with those, perhaps get the absolute value of n at the beginning:
def square(n):
n = abs(n)
....
Since you have been told you have to get the answer by producing the first n odd numbers, then you need to think about how to do that - certainly your loop isn't doing that :
several issues :
you do odd =1, and then use odd in your for loop, the two can't co-exist, so the initial value of odd = 1 is overwritten.
Your loop doesn't produce the first n odd numbers that I can see.
My suggest would be to rework your loop : the first 'n' odd numbers are in the form :
1, 3, 5, ... n*2-1
(Counting from 1 not from zero)
so a loop like this :
final = 0
for c in range(1, n+1): #start counting from 1 to do 1 to n+1
odd = c*2 -1 #Use the series above to generate each odd number.
final += odd
should work
a much more 'pythonic' way to do this is :
final = sum(c*2-1 for c in range(1,n))
This uses a generator to create all of the odd numbers (the equivalent of the loop), and sum the values as they get created.
Go back to the original definition of multiplication.
Just add the number n to itself n times. What's so hard? It's inefficient has hell, but it'll work.
I'm sure there's a more Pythonic way:
def square(n):
sum = 0
for i in range(0,n):
sum = sum + n
return sum

Categories