Recursive function to check if a given number is Fibonacci - python

I'm new to python and I'm am having problems building a recursive function that checks if a given number is a Fibonacci number.
This is my code.
def isFib(n):
if n <= 1:
return n
else:
return (n - 1) + (n - 2)
if isFib(n) == 1 or isFib(n) == isFib(n - 1) + isFib(n - 2):
return True
It should print True in both cases, but instead it print True and False, and I can't find what's wrong
print(all([isFib(i) for i in [1,2,3,5,8,13,21,34,55]]))
print(all([not isFib(2*i) for i in [1,2,3,5,8,13,21,34,55]]))

The first part of your function is an if statement. If True, it returns a value - if False, it also returns a value. So, the second part of your function cannot possible execute, and the function isn't recursive (since you don't call the function again in either return statement).
More generally, what you're doing will never work. The logic seems to be: "a Fibonacci number is the sum of the previous Fibonacci number and the number before that, so I can reverse that logic by computing n - 1 and n - 2 and if they are Fibonacci numbers, then so is n" - or something like that.
But that doesn't work: 5 is a Fibonacci number, but (5-1) is not, so the logic breaks right there. If you were thinking only the sum needed to be a Fibonacci number: 13 is a Fibonacci number, but (13-1) + (13-2) = 23 and that's not a Fibonacci number either.
An easy way to solve this would be to just generate a Fibonacci sequence and return True as soon as the number you're checking comes up:
def is_fib(n, seq=None):
if seq is None:
seq = [0, 1]
# n is Fibonacci if the last number in the sequence is
# or if the last number has not yet past n, then compute the next and try again
return n == seq[-1] or (seq[-1] < n and is_fib(n, seq + [seq[-2] + seq[-1]]))
print([is_fib(i) for i in [1,2,3,5,8,13,21,34,55]])
print(is_fib(23))

Related

Python mathematical sequence

I have to write code to manually input n number and code should find that n member of sequence.n should be natural number. Formula for that sequence is
f(n)=(f(n-1))²-1
First member is 2 second 3 third 8 and every next is one less than square of number before. The code should print that n member of sequence which is inputted.
For example
In:3
Out:8
In:4
Out:63
I wrote code but it don't work
n = int(input("'input n:"))
def f(n):
if n < 0:
print('Undefined')
else:
return (f(n - 1) ** 2) - 1
print(f(n))
In recursion, you need to return a definite value for the stop index.
Here you just have to write in your code that the first value of the sequence is 2:
def f(n):
if n < 0:
raise ValueError('Undefined') # better to raise to make sure to abort
elif n == 0:
return 2
else:
return (f(n - 1) ** 2) - 1
That is enough for f(1) to return 3 and f(2) to return 8...

Reducing by one recursion

I am currently working on a school assignment to generate the first 25 prime numbers using recursion. While the program I have written generates the prime numbers, an error occurs after the 23rd number.
RecursionError: maximum recursion depth exceeded in comparison
I have fixed this issue by extending the recursion depth on my own computer, however I realize that not everyone will have done the same. I have determined that I will instead shorten the amount of recursions running in the program. I am having trouble with this and would like to ask for help.
First.
def checkPrime(a, n, c):
Where a is the divisor, n is the possible prime, and c is the iteration.
if c <= 24:
if n % a <= 0:
if n == a:
print(n, end = ' ')
return checkPrime(2, n + 1, c + 1)
return checkPrime(2, n + 1, c)
return checkPrime(a + 1, n, c)
It basically checks the iteration, whether n is divisible by a, and if n is equal to the a. If n isn't divisible by a it recurs with a plus one. If n isn't equal to a it recurs with the next possible prime and resets the divisor to 2. If everything is True it prints the prime and recurs with the next possible prime, resets the divisor to 2, and add one to the counter.
I call the function like this:
checkPrime(2, 2, 0)
Two is the starting divisor and possible prime number and 0 is the iteration.
What I would like to do is be able to get rid of one of the recursions. I do not want to be told the exact line code I would need to use. If you would just point me in the right direction I would very much appreciate it. Thank you.
If you're allowed any and all, then your critical test is to see whether you have any valid divisor of the candidate number:
limit = ceil(sqrt(cand+1))
if not any([cand % divisor == 0 for divisor in range(2, limit)]):
# This is a prime
Can you take it from there?

How to avoid lists when analyzing order for palindromes?

Just want to apologize in advance for the general coding and logic gore you might encounter while reading this. I recently discovered Project Euler and thought it was fun. I've made it a point to not only find the answer, but make a generic function that could find the answer for any similar case given the appropriate input. For instance, problem number 4, involving palindromes, which can be seen here: https://projecteuler.net/problem=4
Essentially what I did was found a way to multiply every possible combination of numbers given a number of digits, n, then found products that were palindromes. However, anything above 3 digits just takes way too long to process. I believe this is because I used the list() function to take advantage of indexing to determine whether the product was a palindrome. Is there another way to do something of this nature? I feel like this is shoving a square through a circular hole.
Here's the function in question.
def palindrome(n):
number = 0
for i in range(0,n):
number = number + 9 * pow(10, i)
a = pow(10, n - 1) - 1
b = pow(10, n - 1)
while a * b < number * number:
a = a + 1
b = a
while b <= number:
c = a * b
b = b + 1
digits = list(str(int(c)))
lastdigits = digits[::-1]
numdigits = len(digits)
middle = int((numdigits - (numdigits % 2)) / 2) - 1
if numdigits > 1 and digits[:middle + 1] == lastdigits[:middle + 1] and digits[0] == digits[-1] == '9' and numdigits == 2 * n:
print(c)
"Find the largest palindrome made from the product of two 3-digit numbers."
3-digit numbers would be anything from 100 - 999. One thing about the largest product is guaranteed: The two operands must be as large as possible.
Thus, it would make sense to step through a loop starting from the largest number (999) to the smallest (100). We can append palindromes to a list and then later return the largest one.
When you calculate a product, convert it to a string using str(...). Now, checking for palindromes is easy thanks to python's string splicing. A string is a palindrome if string == string[::-1], where string[::-1] does nothing but return a reversed copy of the original.
Implementing these strategies, we have:
def getBiggestPalindrome():
max_palindrome = -1
for i in range(999, 99, -1):
for j in range(999, i - 1, -1):
prod = i * j
str_prod = str(prod)
if str_prod == str_prod[::-1] and prod > max_palindrome:
print(prod)
max_palindrome = prod
return max_palindrome
getBiggestPalindrome()
And, this returns
>>> getBiggestPalindrome()
906609
Note that you can use the range function to generate values from start, to end, with step. The iteration stops just before end, meaning the last value would be 100.

a recursive function to calculate sum of a number digits

i have to write a recursive function which calculates sum of a number digits,here's the code i tried :
def sum_digit(n):
sum=0
a = n % 10
n //= 10
sum += a
while n > 0 :
sum = sum + sum_digit(n)
return sum
print(sum_digit(67154))
i don't know why i don't get the 23 as answer...my program doesn't come to an end
for example 23 number(please correct me if I'm wrong,I'm a newbie in python),the 3 goes to sum, and n become2,since its > 0 then it should go to while,so now it should calculate sum digit(2),the a become 2 and 2 goes to sum and n become 0 and sum digit(2) returns 2,then it sum with the 3 and i must get 5.
i appreciate your help.
You have an infinite loop because n never changes within the loop. Note that assigning a new value to n in the scope of the called function will not change n in the outer scope.
Also, it seems you are mixing an iterative solution with a recursive one. If you do the recursive call, you do not need the loop, and vice versa.
You can either do it recursively:
def sum_digit(n):
if n > 0:
return sum_digit(n // 10) + n % 10
else:
return 0
Or in an iterative way:
def sum_digit(n):
s = 0
while n > 0:
s += n % 10
n //= 10
return s
Or just using bultin functions (probably not what your teacher wants to see):
def sum_digit(n):
return sum(map(int, str(n)))
i must change the while with a if, and it works,thanks for your comments and sorry for posting such a question here.
This will do the trick:
def sum_digit(n, current_sum=0):
if n == 0:
return current_sum
else:
digit = n % 10
current_sum += digit
n //= 10
return sum_digit(n, current_sum)
The output:
print(sum_digit(67154))
> 23
You were mixing up an iterative method (the while loop) and the recursive method (the function call).
In a recursive function, must make sure you get these things right:
The end condition (in our case, we return the sum when the digit is 0)
and
The recursive call (in our case, going down one digit each time)
Change your code as following:
def sum_digit(n):
sum=0
a = n % 10
n //= 10
sum += a
if n > 0 :
sum = sum + sum_digit(n)
return sum
The reason is n is assigned new reference inside function, but it's invisible outside. so while part is loop died. In fact, while part is executed at most once, so code was changed as above.

Prime number checker function is faulty

I wrote a function to calculate whether or not a number is prime, but try as it might, it just seems unable to give the correct response. It also prints the n value that is being incremented. Here is the code for the function (in Python, by the way):
def isPrime(x):
for n in range(1, x):
print n
if x % n == 0:
return False
return True
If I input
isPrime(17)
the function returns
1
False
What is going wrong here?
Every number is divisible by 1 and itself. A prime number is a natural number that has no positive divisors other than 1 and itself. Therefore, if you start your for-loop with 1, every number x will pass the condition x % 1 == 0 in the first iteration, returning False.
To fix it, you need to start your loop with 2 instead of 1. Also, as a side-note, you just need to loop from 2 to sqrt(x), since if there exists a number q > sqrt(x) that divides x, then there must also be a number p = x / q which also divides x, and p < sqrt(x).

Categories

Resources