I am attempting to do Project Euler problem #2. Which is:
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.
However the terminal window hangs when I use the following code with 4000000. Smaller numbers run ok. Is there something about this code that is really inefficient, hence the lagginess?
n = int(raw_input("Enter the start number: "))
def fib_generator():
a, b = 0, 1
yield 0
while True:
a, b = b, a + b
yield a
def even_sum(fib_seq):
seq = []
seq = [next(fib_seq) for number in range(n)]
seq = [number for number in seq if number % 2 == 0]
return sum(seq)
def start():
fib = fib_generator()
even_sum = even_sum(fib)
print even_sum
start()
You have a bug. You're generating the first 4,000,000 Fibonacci numbers, but the problem statement only asks for those Fibonacci numbers whose values are not more than 4,000,000.
Since the Fibonacci numbers grow exponentially (Fn ~ 1.618n), you're generating some numbers with a very large number of digits (log10 Fn ~ n / 5) and that will take an immense amount of time.
Fix the bug, and you'll be okay.
You just need to add logic to stop when the next fibonacci number exceeds 4000000.
Also, I spy a potential problem with this line:
def start():
fib = fib_generator()
even_sum = even_sum(fib) #<--- right here
print even_sum
It isn't good to have a variable name the same as the function name.
Yes, there is something inefficient in your code, you load a very long list into memory twice, with your two seq = ... statements. Why not try one generator expression rather than two list comprehensions? Also, you could alter your Fibonacci generator to stop at a certain number:
def fib_generator(n):
a, b = 0, 1
while a < n:
yield a
a, b = b, a + b
def even_sum(fib_seq):
seq = (number for number in fib_seq if not number % 2)
return sum(seq)
def start():
n = int(raw_input('Enter max constraint: '))
fib_seq = fib_generator(n)
even_sum1 = even_sum(fib_seq)
print even_sum1
start()
This ran pretty fast for me
lst = []
num1 = 1
num2 = 2
sum = 0
jump = 0
next = 0
while next<4000000:
next = num1 + num2
if next<4000000:
if jump ==0:
num1 = next
jump = 1
else:
num2 = next
jump = 0
if next%2 == 0:
lst.append(next)
for item in lst:
sum+=item
print ''
print "Sum: ",
print sum
Related
Please help, I cannot figure out why this code does not work. I think the first loop runs forever but I don't know why!
def NTN():
list1 = []
count = 0
number = 0
Start = input('Type Start Number')
while number != Start:
count = count + 1
number = number + count
Stop = input('Type Stop Number')
while number != Stop:
count = count + 1
number = number + count
if number != Stop:
(list1).append(number)
return (list1)
print(NTN())
You are increasing number by increasing amounts in every iteration. Here's an idea of how it is increasing. Assume Start = 4
After 1 loop, count = 1 and number = 1, increase of 1
After 2 loops, count = 2 and number = 3, increase of 2
After 3 loops, count = 3 and number = 6, increase of 3
Since number is never really equal to 4, the loop never ends. What you need probably is while number <= Start. That would terminate the loop after 3 iterations when number is past 4.
change "number != Start" and "number != Stop" to "number < Start" and "number < Stop" in all places, and it should work.
What went wrong: if Start is 2, then in the first iteration of the while loop, count becomes 0+1=1 and number becomes 0+1=1; in the second iteration, count becomes 1+1=2 and number becomes 1+2=3, which bypasses 2. Since your while loop only ends when number is equal to Start, it never ends.
A couple of side-points:
By convention Python variable and function names are lower-case.
input() returns a string; if you want a number you have to convert it ie with int() or float(). (Note: if you are using Python 2.x input() calls eval() which is really awful design - you should be using int(raw_input()) instead.)
so,
# This code assumes Python 3.x
from math import ceil, sqrt
def get_int(prompt):
"""
Prompt until an integer value is entered
"""
while True:
try:
return int(input(prompt))
except ValueError:
print("Please enter an integer!")
def tri(n):
"""
Return triangular number n,
ie the sum of (1 + 2 + ... + n)
"""
# using Gaussian sum
return n * (n + 1) // 2
def reverse_tri(t):
"""
For positive integer t,
return the least positive integer n
such that t <= tri(n)
"""
# derived by quadratic formula from
# n * (n + 1) // 2 >= t
return int(ceil(((sqrt(8 * t + 1) - 1) / 2)))
def ntn(start, stop):
"""
Return a list of triangular numbers
such that start <= tri < stop
"""
a = reverse_tri(start)
b = reverse_tri(stop)
return [tri(n) for n in range(a, b)]
def main():
start = get_int('Enter a start number: ')
stop = get_int('Enter a stop number: ')
lst = ntn(start, stop + 1) # include stop number in output
print(lst)
if __name__ == "__main__":
main()
I'm working on this one and I seem to have a working solution but I have difficulty understanding its behaviour.
Here is what I have.
#!/usr/bin/python
def even_fib_sums(limit):
number = 1
last = 0
before_last = 0
total = 0
for counter in range (0,limit):
before_last = last
last = number
number = before_last + last
if not number % 2:
total += number
yield total
print sum(even_fib_sums(4000000))
I'm new to programming but it makes sense to me that this is not very effective considering I need to cycle through all 4000000 numbers in the range.
If I use the same approach in generating the Fibonacci sequence up to 5 as follows, you will see the results below.
def generate_fib(limit):
number = 1
last = 0
before_last = 0
total = 0
for counter in range (0,limit):
before_last = last
last = number
number = before_last + last
print number
generate_fib(5)
Result: 1,2,3,5,8
Of these numbers in the result, only 2 and 8 % 2 == 0.
The sum should be 10 but I am returning 12 if I am to use the first snippet above. Why so?
By considering the terms in the Fibonacci sequence whose values do not exceed four million, find the sum of the even-valued terms.
You only need to loop until you hit a fib that is > 400000 not the 4 millionth fibonacci number which your code is trying to do, you can simplify to a using generator function with sum, only yielding even numbers and breaking the loop when you hit a fibonacci number > 4000000:
def fib(n):
a, b = 0, 1
while a <= n:
a, b = b, a + b
if not b & 1:
yield b
print(sum(fib(4000000)))
It takes a fraction of a second to compute:
In [5]: timeit sum(fib(4000000))
100000 loops, best of 3: 6 µs per loop
trying to timeit even_fib_sums(4000000) is still running after a few minutes.
by using for counter in range(0, limit) you are having 'limit' iteration in your function. for example, if your 'limit' variable is 10, you won't have the sum of even fibonachi numbers that are less than 10, but you will have the sum of the first 10 fibonachi numbers that are even.
To make your code works properly, you need to remplace for counter in range(0, limit) by while last < limit, and each time you find that last is even, you add it to total.
You can probably clean up that generating function a bit. Here is how I would write it.
def fib(x):
a = 1
b = 1
yield a
yield b
a,b = b,a+b
while b<=x:
yield b
a,b = b,a+b
This will give you a generating function which will give you all Fibonacci numbers less than or equal to x (we should be a little more careful here, as we will return the first two numbers no matter what).
Then we can just do
sum(x for x in fib(4000000) if x%2==0)
You should change your code to just yield the number, not the sum or just change yield to return, and remove the sum() keyworkd like this:
def even_fib_sums(limit):
number = 1
last = 0
before_last = 0
total = 0
for counter in range (0,limit):
before_last = last
last = number
number = before_last + last
if not number % 2:
total += number
return total
print even_fib_sums(5)
In the first code snippet, you sum the total of round numbers, instead of just yielding the number. If you expect to get 10 in your first snippet for an input of 5, you should amend the code in either of the following ways (not trying to be efficient here, just to fix the problem):
...
number = before_last + last
if not number % 2:
yield number
print sum(even_fib_sums(4000000))
or
...
number = before_last + last
if not number % 2:
total += number
return total
print even_fib_sums(4000000)
I am trying to solve the following using Python:
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.
So far, I have been able to generate the Fibonacci elements but in trying to sum the even elements, my code seems to stall. Here is the code below:
def fib(n):
if n==0:
return 0
elif n==1:
return 1
if n>1:
return fib(n-1)+fib(n-2)
n=0
total=0
while fib(n)<=4000000:
if fib(n)%2==0:
total+=fib(n)
print(total)
Any suggestions would be welcome.
You have an infinite loop as n isn't ever incremented up from zero in your while loop. Additionally, why not sum your Fibonacci total as well as find the next Fibonacci value in the same while loop, like this:
x= 1
y=1
total = 0
while x <= 4000000:
if x % 2 == 0:
total += x
x, y = y, x + y
print (total)
Outputs:
4613732
since this looks like a homework assignment, I threw in some interesting Python
from math import sqrt
# Using Binet's formula
def fib(n):
return int(((1+sqrt(5))**n-(1-sqrt(5))**n)/(2**n*sqrt(5)))
def sum_even_terms(limit = 4000000):
n = total = 0
while True:
term = fib(n)
n += 1
if term > limit: break
if term % 2 == 0:
total += term
return total
print sum_even_terms()
def is_nth_term_even(n):
return (fib(n) % 2 == 0)
print is_nth_term_even(30)
Just for fun, here's a really short solution:
def fib_even_sum(limit=4*10**6):
"""Sum of the even Fibonacci numbers up to the given limit."""
b, c = 1, 2
while c <= limit:
a = b + c; b = c + a; c = a + b
return b // 2
print fib_even_sum() # outputs 4613732
It's based on the following facts:
Every third Fibonacci number is even.
If Fib(n) is even, then the sum of the even Fibonacci numbers up to Fib(n) is equal to the sum of the odd Fibonacci numbers up to Fib(n) (because each even Fibonacci number is the sum of the two preceding odd Fibonacci numbers).
The sum of all Fibonacci numbers (even and odd) up to and including Fib(n) is Fib(n+2) - 1 (via an easy proof by induction).
So if Fib(n) is the last even number to be included in the sum, then
the total you want is just (Fib(n+2) - 1) / 2.
You can also use a generator and add the numbers
def fib():
a, b = 0, 1
while 1:
yield a
a, b = b, a + b
f = fib()
total = 0
while total <= 4000000:
current = f.next()
if current % 2 == 0:
total += current
print total
My objective was to use the index of a list to do addition/subtraction with. Where by I turned the even index positive, and the odd index negative.
EX1: 1234508 Should be answered by a 0: 1-2+3-4+5-0+8 = 11, then the while loops it again and I get 1-2+1 = 0
Ex2: 12345 Should be answered by a 3: 1-2+3-5 = 3, so it shouldn't go through the loop again.
Ex3: 121 Should be answered by a 0: 1-2+1 = 0, so it shouldn't go throught he loop again.
def main():
print()
print("Program to determine if a number is evenly\ndivisible by 11")
print()
indexed = input("Enter a number: ",)
total = 0
num = 0
while num >= 10:
for item in indexed:
if num %2 == 0:
total = total + int(item)
else:
total = total - int(item)
num = num + 1
print(total)
main()
Note that this print statement above is a place holder for a if statement which is inactive on my code, but was printing as large bold print here.
Let's say you have a string st whose characters are all digits, and that you want to have the sum of these digits. You then define the following function
def sd(st):
return sum(int(d) for d in st)
that we can test in the interpreter
In [30]: sd('10101010101010101010')
Out[30]: 10
In [31]: sd('101010101010101010101')
Out[31]: 11
What you really want is to sum the odd digits and subtract the even ones, but this is equivalent to sum the odds, sum separately the evens and then take the difference, isn't it? so what you want is
step_1 = sd(odds(st)) - sd(evens(st))
How can you separate the odd digits from the even ones? Ah! no need for a function, we can use slices
step_2 = sd(st[::2]) - sd(st[1::2])
Now we want to test the slices in the interpreter
In [32]: '101010101010101010101'[::2]
Out[32]: '11111111111'
In [33]: '101010101010101010101'[1::2]
Out[33]: '0000000000'
But step_2 could be a negative number, that I don't want to manage... I'd rather use the abs builtin
step_3 = abs(sd(st[::2]) - sd(st[1::2]))
and this is exactly what you were looking for.
Eventually we can put all the above together, but we may need to iterate until the difference is less than 11 --- we'll use an infinite loop and a break statement to exit the loop when we'll have found the answer
def sd(st):
return sum(int(d) for d in st)
number = input('Give me a number: ')
trial = number
while True:
n = abs(sd(trial[::2]) - sd(trial[1::2]))
if n < 11: break
trial = str(n)
if n > 0:
...
else:
...
what exactly do you want to do with this?
evenindex = evenindex int(item)
"list" is a type, means the list type in python, so it cannot be the name of a variable. Furthermore, you have not defined this variable in your code.
I have figured out the answer to the question I asked above. As such, my answer here is in the event anyone stumbles upon my above question.
def main():
indexed = input("Enter a number: ",)
total = 0
num = 0
while num <= 10:
for item in indexed:
if num %2 == 0:
total = abs(total + int(item))
else:
total = abs(total - int(item))
num = num + 1
if total == 0:
print(indexed, "is evenly divisible by 11 \ncheck since", indexed, "modulus 11 is", int(indexed) % 11)
else:
print(indexed, "is not evenly divisible by 11 \ncheck since", indexed, "modulus 11 is", int(indexed) % 11)
input()
main()
I'm having trouble with my code. The question is:
"By listing the first six prime numbers: 2, 3, 5, 7, 11, and 13, we can see that the 6th prime is 13. What is the 10 001st prime number?"
This is what it looks like:
div = 10001
i = 2
count = 0
prime = 0
now = []
while count < div:
for x in range (2,i+1):
if len(now) ==2:
break
elif i%x == 0:
now.append(x)
if len(now)==1:
prime = i
count += 1
now = []
i+=1
print(prime)
I have tried div up to 1000 and it seems to work fine(for div 1000 I receive 7919). However, when I try div = 10001 I get nothing, not even errors. If someone would help me out I would really appreciate it.
Thank you.
# 7 10001st prime
import itertools
def is_prime(n):
for i in range(2, n//2 + 1):
if n % i == 0:
return False
else:
continue
return True
p = 0
for x in itertools.count(1):
if is_prime(x):
if p == 10001:
print(x)
break
p += 1
Try this code:
prime_list = lambda x:[i for i in xrange(2, x+1) if all([i%x for x in xrange(2, int(i**0.5+1))])][10000]
print prime_list(120000)
Lambda in Python defines an anonymous function and xrange is similar to range, defining a range of integer numbers. The code uses list comprehension and goes through the numbers twice up to the square root of the final number (thus i**0.5). Each number gets eliminated if it is a multiple of the number that's in the range count. You are left with a list of prime numbers in order. So, you just have to print out the number with the right index.
With just some simple modifications (and simplifications) to your code, you can compute the number you're looking for in 1/3 of a second. First, we only check up to the square root as #Hashman suggests. Next, we only test and divide by odd numbers, dealing with 2 as a special case up front. Finally, we toss the whole now array length logic and simply take advantage of Python's break logic:
limit = 10001
i = 3
count = 1
prime = 2
while count < limit:
for x in range(3, int(i ** 0.5) + 1, 2):
if i % x == 0:
break
else: # no break
prime = i
count += 1
i += 2
print(prime)
As before, this gives us 7919 for a limit of 1000 and it gives us 104743 for a limit of 10001. But this still is not as fast as a sieve.
m=0
n=None
s=1
while s<=10001:
for i in range(1,m):
if m%i==0:n=i
if n==1:print(m,'is prime',s);s+=1
m+=1