I'm trying to calculate the numbers of the fibonacci Sequence under 100, but the code I made doesn't work. What I have is:
def fib(n):
if n == 0:
return 0
elif n == 1:
return 1
else:
return fib(n-1) + fib(n-2)
num=0
while(num<100):
print (fib(num))
num+=1
I think this should work, but it doesn't, so it's definitely my issue with my coding. Could anyone resolve this?
So what about this code is not working? It looks like the implementation is correct, but it's of course, slow. You can try to store the numbers you compute in some kind of data structure as you go along to reduce your stack trace and prevent having to recalculate fib of 23 when you're trying to calculate fib of 24.
Related
I have the following exercise:
"Write a recursive function that prints the n-th number of the fibonacci sequence. The function parameters are 'n','current_number' [F(0)] and 'next_number' [F(1)]. [F(0)] and [F(1)] are the initial seeds of the sequence. Write the main program that ask user for the input parameters. Your code must output the result as follows.
fibon({n},{current_number},{next_number}) = {result}
fibon(5,4,5) = 37
fibon(5,0,1) = 5
fibon(10,0,1) = 55
The following solution seems to work
def fibon(n, current_number, next_number):
#print(f'n is {n} from the outset')
if n == 0:
#print('n == 0 is true')
return current_number
elif n == 1:
#print('n == 1 is true')
return next_number
else:
n = n-1
#print(f'this is n-1 {fibon(n-1, current_number, next_number)}')
#print(f'this is n {fibon(n, current_number, next_number)}')
fib= fibon(n-1, current_number, next_number) + fibon(n, current_number, next_number)
#print(fib)
return(fib)
However, I don't understand how 'fibon' is returning the value of nth number in fibonacci series. It is a recursive function and I don't understand how every time it loops, it gets the fibonacci number for the nth position. If you look at the code, " fibon(n-1, current_number, next_number) + fibon(n, current_number, next_number)" can only return a number when n== 1 or n==0. If so, how it can reutrn other numbers in the position when they are not in the 1th or 0 position?
I am not sure if I made a lot of sense but I tried to express my confusin. Thanks in advance!
The code is working but I do not seem to understand why it is working. You can also propose a better solution if there is one. Thank you very much!
So I watched this video: https://www.youtube.com/watch?v=OnXlnd3JB-8
He is giving a 16 year a brief lesson in coding and asks him to make a fibonacci function. At about 10:37 he shows the 16 year old the correct code that tells you the nth number in the fibonacci sequence. Before he revealed this code, I thought that this might be interesting to try myself, considering that I am very much a beginner at coding. I wrote this:
def fibonacci(n):
a = []
while len(a) == 0:
a.append(0)
while len(a) == 1:
a.append(1)
while n > len(a):
a.append(a[len(a) - 1] + a[len(a) - 2])
return a[n-1]
And in the video he writes this:
def fib(n):
if n == 0:
return 1
if n == 1:
return 1
else:
return fib(n-1) + fib(n - 2)
What I don't understand is why the code that I wrote seems to be so much faster than his in the video. It is my understanding that they do essentially the same thing? But if you go to decently big fibonacci numbers (like the 35th in the sequence) there is a very apparent speed difference. I even went up to 150th number in the sequence for the one I wrote and it still seems to be working in less than a second. So as a newbie, I don't understand exactly how these processes differ and what is making mine faster, so my question is why is it so fast? Thanks
The second method uses Recursion - Calling the same function within the function.
Why it is slower ?
Recursion (in your code) involves a lot of function calls, which takes time. Ofcourse, you could cache the results and avoid them.
It's Time Complexity is O(2^n)
It calculates everything that is already calculated before. Say n = 5
fib(5) = fib(4) + fib(3)
fib(4) = fib(3) + fib(2)
fib(3) = fib(2) + fib(1)
fib(2) = fib(1) + fib(0)
You can see f(3), f(2) and f(1) are calculated again and again.
You don't see the above issues in the first ccode.
Forn = 5,
You are just adding the previous two values (a[4] and a[3]) and storing that in a[5].
It's Time Complexity is O(n).
You can see there are no function calls, no recalculation and That's why it's faster.
Recursion can be elegant, but it's not the most efficient solution. There's overhead in making function calls and passing parameters. Also, your code is not producing the right answers. You'd need something like this to match their code:
def fibonacci(n):
a = [1,1]
while n >= len(a):
a.append(a[-1] + a[-2])
return a[-1]
In the end, there's really no point in keeping the whole list. All you need are the two most recent entries.
I'm new to both Python and StackOverflow so I apologise if this question has been repeated too much or if it's not a good question. I'm doing a beginner's Python course and one of the tasks I have to do is to make a function that finds the next prime number after a given input. This is what I have so far:
def nextPrime(n):
num = n + 1
for i in range(1, 500):
for j in range(2, num):
if num%j == 0:
num = num + 1
return num
When I run it on the site's IDE, it's fine and everything works well but then when I submit the task, it says the runtime was too long and that I should optimise my code. But I'm not really sure how to do this, so would it be possible to get some feedback or any suggestions on how to make it run faster?
When your function finds the answer, it will continue checking the same number hundreds of times. This is why it is taking so long. Also, when you increase num, you should break out of the nested loop to that the new number is checked against the small factors first (which is more likely to eliminate it and would accelerate progress).
To make this simpler and more efficient, you should break down your problem in areas of concern. Checking if a number is prime or not should be implemented in its own separate function. This will make the code of your nextPrime() function much simpler:
def nextPrime(n):
n += 1
while not isPrime(n): n += 1
return n
Now you only need to implement an efficient isPrime() function:
def isPrime(x):
p,inc = 2,1
while p*p <= x:
if x % p == 0: return False
p,inc = p+inc,2
return x > 1
Looping from 1 to 500, especially because another loop runs through it, is not only inefficient, but also confines the range of the possible "next prime number" that you're trying to find. Therefore, you should make use of while loop and break which can be used to break out of the loop whenever you have found the prime number (of course, if it's stated that the number is less than 501 in the prompt, your approach totally makes sense).
Furthermore, you can make use of the fact that you only need check the integers less than or equal to the square root of the designated integer (which in python, is represented as num**0.5) to determine if that integer is prime, as the divisors of the integers always come in pair and the largest of the smaller divisor is always a square root, if it exists.
We just started learning python this year in school, and so far we are only doing basic stuff with tkinter canvas (drawing houses, flowers etc.) and our teacher kinda sucks so I had to learn everything I know by now myself.
I've been thinking about this idea of writing a function to find the digital sum of a number (without recursion preferably) so I came up with this:
def sum(n):
total=0
for letter in str(n):
total+=int(letter)
return total
But then, I had an idea about using recursion to find the "absolute dig. sum of a number", for instance 99=9+9=18 =>1+8=9
and I came up with this
total=0
def suma(n):
global total
def part_sum(n):
global total
total_part=0
for letter in str(n):
total_part+=int(letter)
total=total_part
if total<10:
print(total)
else:
part_sum(total)
part_sum(n)
which basically makes a sum of n, checks if it is lower than n, if it is not it runs it again (basic recursion), but it uses a bunch of variables and global variables (which are for some reason bad as I've heard) and I am well aware it could be done much more efficiently using classes and objects, but I've only watched couple of vidoes on that so I'm not very good at it.
Could someone please edit my code and paste it here with some notes to help me understand it?
Recursion is often overused. I believe you can write suma() much more clearly without it. Build on what you have already created.
def sum(n):
total=0
for letter in str(n):
total+=int(letter)
return total
def suma(n):
while n >= 10:
n = sum(n)
return n
Here's my solution
def rec_dig_sum(n):
total = str(sum(map(int, str(n))))
while len(total)>1:
total = str(sum(map(int, total)))
return int(total)
You can think of map as taking map(function, [input1, input2, input3]) and returning [function(input1), function(input2), function(input3)]
Instead of saving a variable and updating it with each iteration of a loop (the normal way to do this):
def iterative_sum(num):
while num >= 10:
num = int(sum(map(int, str(num))))
return num
Send it as an argument to a new function call:
def recursive_sum(num):
if num >= 10:
return recursive_sum(sum(map(int, str(num))))
return num
You can also make a recursive function to do the initial summation, and use that in the function that keeps doing so until it's only one digit:
def rc(n, c=0):
if n:
return rc(n//10, c+n%10)
return c
def rs(n):
if n >= 10:
return rs(rc(n))
return n
I'm solving Euler problem set #2, and I have found the function relevant to what I want I want to do, well partially at least since I'll need to make modifications for even numbers in the fibonacci sequence. I'm trying to print out fibonacci numbers, up to a certain point, n.
def fib(n):
if n == 1:
return 1
elif n == 0:
return 0
else:
return fib(n-1) + fib(n-2)
Giving
>>> fib(13)
233
However
>>> fib(200)
returns nothing. I'm not sure if it is taking long to compute, or whatnot. I might try this in C++, but would like some knowledge from here first.
It's just taking a long time to compute, because you're recursively calling fib() many, many times. If you add a line as follows you can get status update on it as it runs. It'll take a very long time because of the amount of recursion (if it even finishes).
def fib(n):
print("Fibonacci: {0}".format(n))
if n == 1:
return 1
elif n == 0:
return 0
else:
return fib(n-1) + fib(n-2)