Find if there is an exponent recursively - python

I need to write a function that takes 2 parameters base and number.
The function returns True if there is an exponent that gives me the number base ** exp == number or False otherwise.
Examples:
check_is_power(2, 16) -> True # because you have a valid exp here (4)
check_is_power(3, 17) -> False # because there is not a whole positive number as an exp
important:
I can use only these functions to solve this:
def add(x: float, y: float) -> float:
return x + y
def subtract_1(x: int) -> int:
return x - 1
def is_odd(n: int) -> bool:
return n % 2 == 1
def divide_by_2(n: int) -> int:
return n // 2
This is what I tried:
def check_is_power(base: int, number: int) -> bool:
if number == base:
return True
return check_is_power(base, divide_by_2(number))
Now, I know I have problems with this code but That's my start position and I would like help to finish this. Thanks!

Something like this?
Work only with integers and positives number
def add(a, b) :
return a + b
def subtract_1(x):
return x - 1
def mul(a, b) :
if b == 1:
return a
if(b == 0):
return 0
return add(mul(a, subtract_1(b)), a)
def exp(a, b) :
if a == 0 and b == 0:
return -1 #should be NaN
if b == 1:
return a
if(b == 0):
return 1
return mul(exp(a, subtract_1(b)), a)
def check_is_power(base, number):
e = 0
if base == 0 and number == 0:
return True
if base <= 0 or number <= 0:
return False
while True:
r = exp(base, e)
if r == number:
return True
if r > number:
break
e = add(e, 1)
return False
print(check_is_power(15, 170859375))

Since I did not see a restriction on allowing one to change the sign of a value from positive to negative, following is a very simple block of code that appears to provide the necessary results.
def add(x: float, y: float) -> float:
return x + y
def is_exponent(x,y):
a = 0
b = y
c = -x # No mention of not allowing changing the sign of the base to effectively allow subtraction
while b > 0:
b = add(b,c)
a = a + 1
if b < 0:
return False
elif b == 0 and a == x:
return True
elif b == 0 and a < x:
return False
else:
return is_exponent(x,a)
while True:
base = int(input("Enter base "))
value = int(input("Enter value to check "))
if (is_exponent(base, value)):
print(value, "is an exponent of", base)
else:
print(value, "is not an exponent of", base)
choice = input("Do you want to check another pair (y/n)? ")
if choice != 'y':
break
All that is needed is the addition function along with recursively calling the "is_exponent" function.
Testing this out with a few different base numbers seemed to hold together.
#Una:~/Python_Programs/Exponent$ python3 Exponent.py
Enter base 6
Enter value to check 36
36 is an exponent of 6
Do you want to check another pair (y/n)? y
Enter base 25
Enter value to check 625
625 is an exponent of 25
Do you want to check another pair (y/n)? y
Enter base 25
Enter value to check 125
125 is not an exponent of 25
Do you want to check another pair (y/n)? y
Enter base 17
Enter value to check 4913
4913 is an exponent of 17
Do you want to check another pair (y/n)?
Give that a try and see if it meets the spirit of the exercise.

Related

Compute the greatest common divisor and least common multiple of two integers

I need to write a Python program in which the user enters two numbers and receives the LCM and HCF of those numbers. I tried it, and my LCM was correct, but my HCF was not, so could anyone assist me in locating the HCF? Thank you!
num1 = int(input('Enter your first number: '))
num2 = int(input('Enter your second number: '))
def compute_lcm(x, y):
# choose the greater number
if x > y:
greater = x
else:
greater = y
while(True):
if((greater % x == 0) and (greater % y == 0)):
lcm = greater
break
greater += 1
return lcm
print("The L.C.M. is", compute_lcm(num1, num2))
You can use Euclidian algorithm if you want to find greatest common divisor or in your terms highest common factor (HCF): here is the link to the article in FreeCodeCamp.org
Here is the code you can use for python for your case:
"""
finding HCF
"""
def hcfLoop(x : int, y : int) -> int:
"""
finding hinghest common factor using loop
returns int
"""
while (x % y) > 0:
remainder = x % y
x = y
y = remainder
return y
def hcfRecurs(x : int, y : int) -> int:
"""
find highest common factor using recursion
"""
if y == 0 :
return x
else:
return hcfRecurs(y, x % y)
x = 1220
y = 516
print(f"the HCF for {x} and {y} using loop: {hcfLoop(x,y)}")
print(f"the HCF for {x} and {y} using recursion: {hcfRecurs(x,y)}")
The answer:
the HCF for 1220 and 516 using loop: 4
the HCF for 1220 and 516 using recursion: 4
num1 = 36
num2 = 60
hcf = 1
for i in range(1, min(num1, num2)):
if num1 % i == 0 and num2 % i == 0:
hcf = i
print("Hcf of", num1, "and", num2, "is", hcf)
# HCF of 36 and 60 is 12

python how many moves to get to zero

I have tried to do this task in a lot of ways but none of it works.
The user enters a natural number n. In one move, its largest digit is subtracted from the number. In the next move, its highest digit is subtracted from the result, etc. The program needs to determine and print how many moves it takes to get to zero. For example, number 24 requires five moves (24 → 20 → 18 → 10 → 9 → 0).
Here is what I've done so far. I know how to find the largest digit but how can I put this into a loop to substract largest digit from result ?
num = int(input("Enter natural number "))
if num <= 0:
print("That is not a natural number")
else:
max = 0
while num > 0:
digit = num % 10
if max < digit:
max = digit
num = num // 10
print("Largest Digit is : ", max)
You could try with a string and max:
num = int(input("Enter natural number "))
if num <= 0:
print("That is not a natural number")
else:
ntimes = 0
while num > 0:
num -= int(max(str(num)))
ntimes += 1
print(ntimes)
Output:
5
In case you have the requirement of not casting the number into a string to obtain its digits you can use divmod:
def get_natural_num_input(prompt: str) -> int:
num = -1
while True:
try:
num = int(input(prompt))
if num <= 0:
print("Error: Not a natural number, try again...")
else:
break
except ValueError:
print("Error: Enter a integer, try again...")
return num
def get_digits(num: int) -> list[int]:
digits = []
while num > 0:
num, digit = divmod(num, 10)
digits.append(digit)
return digits
def moves_to_get_zero(num: int) -> int:
moves = 0
while num != 0:
num -= max(get_digits(num))
moves += 1
return moves
num = get_natural_num_input("Enter a natural number: ")
print(f'moves_to_get_zero({num}) = {moves_to_get_zero(num)}')
Example Usage:
Enter a natural number: 24
moves_to_get_zero(24) = 5

How to detect if the middle digit of an integer is "0" without converting it into a string?

Trying to make a function which detects the the middle digit of an odd number is 0 and returns True if it is, otherwise False. I really want to get this function to work without converting the integer to a string first.
This is what I have so far:
def test(n):
n = str(n)
if len(n) % 2 == 0:
return False
else:
left_side = n[:len(n)//2]
right_side = n[(len(n)//2):]
if right_side[:1] == "0" and ((not "0" in left_side)and (not "0" in right_side[2:])):
return True
else:
return False
print (test(0)) # True
print (test(101)) # True
print (test(123)) # False
print (test(21031)) # True
n = 12345
digits = []
while n:
digit = n % 10
digits.append(digit)
n //= 10
digit_count = len(digits)
if digit_count % 2:
middle = digit_count // 2
print(digits[middle])
Output:
3
Alternatively, using math.log10:
from math import log10
n = 12345
digit_count = int(log10(n)) + 1
middle = digit_count // 2
print(n // 10 ** middle % 10)
See these two answers:
Length of an integer in Python
How to take the nth digit of a number in python
this should do it. it does convert it to a string, but honestly it's faster, easier, and just more efficient.
num = int(input("number too test: "))
def test(number):
num_len = len(str(number))
print(num_len)
if num_len % 2 == 0:
return False
else:
number = str(number)
half = int((num_len-1)/2)
print(number[half])
if int(number[half]) is 0:
return True
else:
return False
test(num)
Not that it will make much difference in terms of performance, but you can use the log function to compute the number of zeros in a number and remove the rightmost half by dividing to the correct power of 10. For example:
import math
def test(n):
if n == 0:
return True
digits = math.ceil(math.log(n + 1, 10)) - 1
return digits % 2 == 0 and not (n // 10**(digits / 2) % 10)

manipulate list in python

I'm doing a python challenge and I cannot go further...
I need to verify if the numbers in the vetor are primes.
Like:
vetor = [2,5,12]
2 is prime(TRUE)
5 is prime(TRUE)
12 not prime(FALSE)
This is my code until now:
vetor = [ ]
def is_prime():
x = vetor
if x == 1:
return False
elif x == 2:
return True
for i in range(x):
if (x % i) != 0:
return True
else:
return False
def number():
value = int(input('Write an integer number bigger than 1: '))
if value >= 1:
vetor.append(value)
return number()
elif value < 0:
return number()
elif value == 0:
return is_prime()
print(number())
But doing this, Python returns me:
TypeError: 'list' object cannot be interpreted as an integer
What could I do to manipulate that data inside my list?
Try this:
vetor = [ ]
def is_prime(x):
if x == 1:
return False
elif x == 2:
return True
for i in range(1, x):
if (x % i) != 0:
return True
else:
return False
def number():
value = int(input('Write an integer number bigger than 1: '))
if value >= 1:
vetor.append(value)
return number()
elif value < 0:
return number()
elif value == 0:
for x in vetor:
if is_prime(x):
print(x, 'is prime')
else:
print(x, 'is not prime')
print(number())
You're trying to evaluate the value of a 'whole' list (datatype) against an integer (datatype) value (1 or 2), and then you're using the whole list as it were a single integer value again. You should address every single value in the list and check it separately.
You can do it, per example, with a for-each loop:
for value in vetor:
#do wahtever you want with 'value'
I would recommend making is_prime accept an integer as an argument. Then it's just a pure function that takes in an integer and outputs a boolean value.
I also notice a problem in your is_prime implementation. In your if-else statement, the function returns no matter what during that statement, so the for loop will always stop after only one iteration. You should only return False if all of the divisors you check do note divide the number:
import math
def is_prime(n):
if n <= 1:
return False
for d in range(2, int(math.sqrt(n))+1):
if n % d == 0:
return False
return True
# >>> is_prime(7)
# True
# >>> is_prime(8)
# False
I also think it would be clearer to write your program iteratively, rather than recursively (your number function currently calls itself). This might look like
vector = []
while True:
value = int(input('Write an integer bigger than 1: '))
if value == 0:
break
elif value > 0:
vector.append(value)
for n in vector:
print(n, is_prime(n))
# prints something like:
#
# 1 False
# 2 True
# 11 True

Function to check whether a number is a Fibonacci number or not?

I've made a program which takes number of test cases as input and for each test case, it needs a number as input. Finally it checks whether the numbers you have entered are fibonacci numbers or not and prints accordingly. I've had no problems running it on my PC.But when i upload it to CodeChef.com(where i saw this quesion), it shows runtime error.
Any help is appreciated and as i'm a noob my code might look lengthy ., any modifications are welcome.Thanks!
Here's my code:
def isperfect(n):
import math
if n < 0:
print("No Solution")
return False
else:
test = int(math.sqrt(n))
return test*test == n
test_cases = int(input())
count = 0
store = []
while count < test_cases:
x = int(input())
store.append(x)
count += 1
for each_item in store:
assert isinstance(each_item, int)
s1 = 5*each_item*each_item-4
s2 = 5*each_item*each_item+4
if(isperfect(s1) == True or isperfect(s2) == True):
print("YES")
else:
print("NO")
This is the most elegant solution i've encountered:
def is_fibonacci(n):
phi = 0.5 + 0.5 * math.sqrt(5.0)
a = phi * n
return n == 0 or abs(round(a) - a) < 1.0 / n
The code is not mine, was posted by #sven-marnach.
The original post:
check-input-that-belong-to-fibonacci-numbers-in-python
The runtime error is apparently due to an exception, but Codechef does not provide any more information. It could be various things including divide by zero, memory exhaustion, assertion failure, ...
Although your program works for many common numbers, it doesn't handle all the inputs that the Codechef constraints allow. In particular, the number to be tested can have up to 1000 digits in it. If you try a large input like a 1000-digit number, you'll find it fails. First it fails because of your assert isinstance(each_item, int); a number of 12 digits or more is not of type int. You can just remove the assertion. The next failure occurs because you are using the floating point sqrt routine, and that requires the integer to be converted into floating point. Python can handle very long integers, but the floating point representation is more limited in its precision, and cannot handle 1000 digit integer conversions. That's harder to fix, but can be done. See this ActiveState recipe for an all-integer solution for square root.
I've figured that this can be done by using Newton- Raphson method, i have replaced the code in the function isperfect() with Newton-Raphson formula code, removed assertion and it worked. Thanks for all your help.
Here's the final code:
def isperfect(n):
x = n
y = (x + n // x) // 2
while y < x:
x = y
y = (x + n // x) // 2
return x*x == n
test_cases = int(input())
count = 0
store = []
while count < test_cases:
x = int(input())
store.append(x)
count += 1
for each_item in store:
s1 = 5*each_item*each_item-4
s2 = 5*each_item*each_item+4
if(isperfect(s1) == True or isperfect(s2) == True):
print("YES")
else:
print("NO")
This is going to be a very efficient way of doing it.
In [65]:
import scipy.optimize as so
from numpy import *
In [66]:
def fib(n):
s5=sqrt(5.)
return sqrt(0.2)*(((1+s5)/2.)**n-((1-s5)/2.)**n)
def apx_fib(n):
s5=sqrt(5.)
return sqrt(0.2)*(0.5*(1+s5))**n
def solve_fib(f):
_f=lambda x, y: (apx_fib(x)-y)**2
return so.fmin_slsqp(_f,0., args=(f,),iprint=0)
def test_fib(fibn):
if fibn<1:
print 'No, it is not'
else:
n=int(round(solve_fib(fibn)))
if int(round(fib(n)))==int(fibn):
print 'Yes, it is. (%d)'%n
else:
print 'No, it is not'
In [67]:
asarray(fib(arange(1,20)), dtype='int64')
Out[67]:
array([ 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89,
144, 233, 377, 610, 987, 1597, 2584, 4181])
In [68]:
test_fib(34)
Yes, it is. (9)
In [69]:
test_fib(4181)
Yes, it is. (19)
In [70]:
test_fib(4444)
No, it is not
Fairly simple and efficient way of doing it
def isInFib(n):
if n == 0: return False
elif n == 1: return True
else:
A = 1
B = 1
FLIP = True
while(True):
new = A + B
if new > n: return False
elif new == n: return True
else:
if(FLIP):
A = new
FLIP = not FLIP
else:
B = new
FLIP = not FLIP
Explanation of Algorithm
I first check if my input is equal to 0 or 1, and return appropriate.
If my input is greater than 1, we go into the else, infinite loop.
A and B represent the last two previous numbers in the sequence. We add A and B to get new, the current Fibonacci number.
We check if new is equal to our input number, if that's true we return true, we are done and complete the function.
If it's greater, that means our number is not in the Fibonacci sequence, since we have surpassed it.
if it's less, we need to keep going! and this is where I think it get's confusing to explain. I want to set up A or B as my current fibonacci sequence number (new), but I have make sure that I keep switching between them, since I don't want one to get left behind. Fibonacci sequence takes the previous 2 numbers and adds them together. I want A and B to be my last two previous sums.
I'll use an example
1,1,2,3,5,8,13
A and B are initially 1. So new is equal to 2 first. I then check if I'm over my input number or equal to it. But if my input number is less. I want to keep going.
I want A to equal new (value = 2) then, before we get to our next iteration of the while loop. So that new will equal 2 + 1 as A + B on the next iteration.
But, then THE next iteration of the loop, I want to set B as 3, and I want to leave A being equal to 2. So I have to keep switching between putting the current fibonacci number I'm at, in A or B. And that's why I have the flip logic! It just keeps switching between True and False.
Try this function:
def isfib(number):
num1 = 1
num2 = 1
while True:
if num2 <= number:
if num2 == number:
return True
else:
tempnum = num2
num2 += num1
num1 = tempnum
else:
return False
Here's how it works:
Set num1 and num2 to 0.
If num2 isn't less than or equal to the number return False.
If num2 is equal to the number return True.
Set add num1 to num2, set num1 to num2's original value and go back to step 2.
num=int(input("Enter a number : "))
n1=0
n2=1
i=1
lst=[]
lst.append(n1)
lst.append(n2)
while i<num-1:
n3=n1+n2
n1=n2
n2=n3
lst.append(n3)
i=i+1
for i in lst:
if (num == i):
print("Fibonacci number")
break
else:
print("Not fibonacci")
def isfib(number):
num1 = 0
num2 = 1
while True:
if num2 <= number:
if num2 == number:
return True
else:
tempnum = num2
num2 += num1
num1 = tempnum
else:
return False
n=int(input())
number=n
fibonacci=isfib(number)
if (fibonacci):
print("true")
elif n==0:
print("true")
else:
print("false")

Categories