LCM using recursive? - python

Here is my code:
def lcm(a, b):
if b == 0:
return a
return a * b / lcm(a, b)
print lcm(5,3)
This is what I could manage so far, any idea on how to find the LCM (least common multiple) of two numbers using recursive and one function?

We have lcm(a, b) * gcd(a, b) = a * b. So we can write the following equation:
lcm(a, b) = a; if a % b == 0
lcm(a, b) ; if a % b != 0
= a * b / gcd(a, b)
= a * b / gcd(b, a % b)
= a * b / (b * (a % b) / lcm(b, a % b))
= a / (a % b) * lcm(b, a % b)
And translate to Python, we have:
def lcm(a, b):
t = a % b
if t == 0: return a
return a * lcm(b, t) / t

Edit: I didn't read the recursive / one function bit in your question cause I'm dumb. Incorporated now.
The lcm isn't a * b / lcm(a, b), it's a * b / gcd(a, b) (greatest common divisor).
So the cleanest way to do this is:
def gcd(x, y):
while y:
x, y = y, x % y
return x
def lcm(x, y):
return x * y / gcd(x, y)
If you are limited to recursion only (e.g. for an exam) then this doesn't have to be efficient, so you might as well just recursively count up until you find the lowest number that both x and y divide into:
def lcm(x, y, counter=1):
if (counter%x == 0 and counter%y == 0):
return counter
return lcm(x, y, counter+1)
That just increases counter until counter%x == 0 and counter%y == 0 is true, which is the LCM. Don't try it on large numbers though, you'll just get a stack overflow.

As stated in the other answers here lcm = a*b / gcd(a, b)but then you will need to define another function gcd(a, b) for it.
Since you needed only 1 function with recursion, maybe this piece of code will do.
N.B. : This function has one extra parameter c which should be always passed as 1 while calling it outside the function only :
def lcm(a, b, c):
d = c
m = min(a, b)
while m > 1 :
if a%m == 0 and b%m == 0 :
d*=m
return lcm(int(a/m), int(b/m), d)
else:
m-= 1
d*= a*b
return d

Using the mathematical relationship that the product of two numbers is equal to the product of the Greatest Common Divisor and the Least Common Multiplier of those two numbers: A * B = GCD(A,B) * LCM(A,B)
def gcd(a,b):
if a % b == 0: return b
return gcd(b, a % b)
def lcm(a, b):
return ((a*b) // gcd(a,b))
The first function is recursive and it's used to find the Greatest Common Divisor, it has cost O(log(n)).

This should do:
# Python Program to find the L.C.M. of two input number
# define a function
def lcm(x, y):
"""This function takes two
integers and returns the L.C.M."""
# 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
# take input from the user
num1 = int(input("Enter first number: "))
num2 = int(input("Enter second number: "))
print("The L.C.M. of", num1,"and", num2,"is", lcm(num1, num2))

I created my own easy programme.
def lcm(greater,a,b):
# while(True):
if (greater % a == 0 and greater % b == 0):
lcm1 = greater
return lcm1
else:
lcm1=lcm(greater + 1,a,b)
return lcm1
a=int(input(" Enter 1st number :"))
b=int(input(" Enter 2nd number :"))
if(a>b):
greater=a
else:
greater=b
print(lcm(greater,a,b))

Related

Equation solving using bisection method using python

I wrote a python code to find root of 2*x-4 using bisection method
def func(x):
return 2*x-4
def bisection(a,b):
if (func(a) * func(b) >= 0):
print("You have not assumed right a and b\n")
return
c = a
while ((b-a) >= 0.01):
c = (a+b)/2
if (func(c) == 0.0):
break
if (func(c)*func(a) < 0):
b = c
else:
a = c
print("The value of root is : ","%.0f"%c)
a =-2
b = 4
bisection(a, b)
Now i want that the function input should be given by the user in the form of mx+n where m and n are integers. Can anyone help how can i do that ?
m, n = list(map(int, input("Please enter the value of [m] [n] for f(x) = mx +n: ").split()))
def Input():
a, b = list(map(int, input("Enter values of [a] [b]: ").split()))
if f(a)*f(b)<0:
Bisection(a, b)
else:
print("Oops! The root of function doesn't belong to the above domain\nPlease try to again:")
Input()
def f(x):
return m*x + n
def Bisection(a, b):
c = (a+b)/2
if f(c)*f(b)<0:
Bisection(c, b)
elif f(c)*f(a)<0:
Bisection(c, a)
elif f(c)==0:
print(c)
Input()
See we know that Bisection, Newton-Raphson, or most of all Numerical methods are the iteration processes so better we use function inside of function: f(f(f(f.....) Of course! by checking the conditions.
Here, I have used elif f(c)==0 this is something which we can't use for quadratic/cubic or higher-order polynomials because getting the exact root will not be possible for all the types of equations say like f(x) = mx^2 - n where m, n > 0 However, we can define the iterations to be performed.
By asking like Please enter the number of iterations to be performed:

How to compare values of mathematic functions in a python function (def)

I am writting a code to compare mathematic functions and say which one of them has the biggest value for given x and y
import math
def r(x,y):
r = 3 * math.pow(x, 2) + math.pow(y, 2)
return r
def b(x,y):
b = 2 * math.pow(x, 2) + 5 * math.pow(y, 2)
return b
def c(x,y):
c = -100 * x + math.pow(y, 3)
return c
def compare():
x = float(input("Type the value of x: "))
y = float(input("Type the value of y: "))
r(x,y)
b(x,y)
c(x,y)
if r > b and c:
print("r is the biggest.")
return
elif b > r and c:
print("b is the biggest.")
return
elif c > b and r:
print("c is the biggest.")
return
compare()
But I get the following error:
TypeError: '>' not supported between instances of 'function' and 'function'
You must assign the result of each function to a variable. Try the following:
import math
def r(x,y):
r = 3 * math.pow(x, 2) + math.pow(y, 2)
return r
def b(x,y):
b = 2 * math.pow(x, 2) + 5 * math.pow(y, 2)
return b
def c(x,y):
c = -100 * x + math.pow(y, 3)
return c
def compare():
x = float(input("Type the value of x: "))
y = float(input("Type the value of y: "))
R=r(x,y)
B=b(x,y)
C=c(x,y)
if R > B and R>C:
print("r is the biggest.")
return
elif B > R and B>C:
print("b is the biggest.")
return
elif C > B and C>R:
print("c is the biggest.")
return
compare()
There are two bugs here:
You need to compare the actual results of the function, not the function object itself.
You can't compare one numerical value to the and of two other values; what you're actually testing for in that case is a single comparison plus whether the other value is non-zero!
I'd use the max function to get the largest value rather than building a complicated chain of conditionals to do the same thing. That way if you add another function it's easy to just add it to the list:
import math
def r(x, y):
return 3 * math.pow(x, 2) + math.pow(y, 2)
def b(x, y):
return 2 * math.pow(x, 2) + 5 * math.pow(y, 2)
def c(x, y):
return -100 * x + math.pow(y, 3)
def compare():
functions = [r, b, c] # maybe this could be a parameter?
x = float(input("Type the value of x: "))
y = float(input("Type the value of y: "))
result, func_name = max((f(x, y), f.__name__) for f in functions)
print(f"{func_name} is the biggest.")
compare()
Type the value of x: 1
Type the value of y: 2
b is the biggest.
Type the value of x: 0
Type the value of y: 0
r is the biggest.
Type the value of x: -1
Type the value of y: -2
c is the biggest.

Totient maximum (project euler) - programm crashes

I'm trying to solve this excercise: https://projecteuler.net/problem=69. It works fine with the example given in the excercise, but it crashes when I try to calculate the maximum for n <= 1.000.000 and it is already pretty slow when I try to calculate it for n <= 5.000. How could I optimize my code? I'm using PyScripter.
def gcd(a, b):
while b != 0:
a, b = b, a % b
return a
def coprime(b):
x = 0 # define a counter for the number of co-primes of b
for a in range(1, b):
if gcd(a, b) == 1: # check if a and b are co-prime
x += 1
return x
def main():
maximum = 1
for n in range(1, 1000001):
m = coprime(n)
x = n / m # calculate n/phi(n)
if x > maximum: # check if you have a new maximum
maximum = n
print(maximum)
if __name__ == '__main__':
main()

Sum of Two Integers without using '+' operator in python 2 or 3

class Solution(object):
def getSum(self, a, b):
if (a == 0):
return b
if (b == 0):
return a;
while(b != 0):
_a = a ^ b
_b = (a & b) << 1
a = _a
b = _b
return a
But when one of a, b < 0 or both, how the script should be like?
+ operator internally makes a call to __add__(). So, you may directly call a.__add__(b) to get sum. Below is the modified code:
>>> class Solution(object):
... def getSum(self, a, b):
... return a.__add__(b)
...
>>> s = Solution()
>>> s.getSum(1, 2)
3
OR, you may use operator.add(a, b) as:
>>> import operator
>>> operator.add(1, 2)
3
I enjoy solving other people's problems.
class Solution(object):
def getSum(self, a, b):
return sum([a, b])
Edit: If you are in for some fantasy. You can do operator overloading.
class CrappyInt(int):
def __init__(self, num):
self.num = num
def __eq__(self, a):
return self.__add__(a)
m = CrappyInt(3)
n = CrappyInt(4)
print m == n
# 7
This maybe a little hard for you now. But it is fun.
You can also use operator package
import operator
class Solution(object):
def getSum(self, a, b):
return operator.add(a, b)
And if you want to hassle with binary bitwise operations. Here is first method:
def complex_add_1(x, y):
while y != 0:
b = x & y
x = x ^ y
y = b << 1
return x
And here is the another one with recursion:
def complex_add_2(x, y):
if y == 0:
return x
else:
return complex_add_2(x ^ y, (x & y) << 1)
Edit: methods with bitwise operations are working only in Python 3
My old highschool program that I found on my usb stick. Yes it's crude but it works.
def s(a,b):
a = bin(a)[2:]
b = bin(b)[2:]
c_in = 0
value = ''
if not len(a) == len(b):
to_fill = abs(len(a) - len(b))
if len(a) > len(b):
b = b.zfill(len(a))
else:
a = a.zfill(len(b))
for i,j in zip(reversed(a),reversed(b)):
i_xor_j = int(i) ^ int(j)
i_and_j = int(i) and int(j)
s = int(c_in) ^ int(i_xor_j)
c_in_and_i_xor_j = int(c_in) and int(i_xor_j)
c_in = int(i_and_j) or int(c_in_and_i_xor_j)
value += str(int(s))
value += str(int(c_in))
return int(value[::-1],2)
print(s(5,9))
#>> 14
Or I would have see if I could cheat with sum.
This was kinda fun :) I'm not sure if this is what you're after, but these all should work so long as you're using integers
def subtract(a, b):
if a < 0:
return negative(add(negative(a), b))
if b < 0:
return add(a, negative(b))
if a < b:
return negative(subtract(b, a))
if b == 0:
return a
return subtract(a^b, (~a & b) << 1)
def negative(a):
if a == 0: return 0
a = ~a
b = 1
while b > 0:
a, b = a^b, (a&b) << 1
return a
def add(a, b):
if a < 0:
return negative(subtract(negative(a), b))
if b < 0:
return subtract(a, negative(b))
if b == 0:
return a
return add(a^b, (a & b) << 1)
def multiply(a, b):
if a == 0 or b == 0:
return 0
if b < 0:
a = negative(a)
b = negative(b)
A = 0
while b > 0:
A = add(A, a)
b = subtract(b, 1)
return A
def div(a, b):
if b == 0:
raise ZeroDivisionError
if a == 0:
return 0
if b < 0:
a = negative(a)
b = negative(b)
A = 0
if a < 0:
while a < 0:
a = add(a, b)
A = subtract(A, 1)
else:
while b < a :
a = subtract(a, b)
A = add(A, 1)
return A
def mod(a, b):
return subtract(a, multiply(div(a, b),b))
negation by two's compliment is used to get a function where a and b are both greater than 0 and the correct operation (addition or subtraction) is selected. further with subtraction, care is taken to not yield a negative result. This is done because the recursive definitions of add and subtract hate crossing 0. Also in this case the recursive add and subtract do the exact same thing as your loop.

How to check if the number can be represented prime power (nth root is prime or not)

I am trying this problem for a while but getting wrong answer again and again.
number can be very large <=2^2014.
22086. Prime Power Test
Explanation about my algorithm:
For a Given number I am checking if the number can be represented as form of prime power or not.
So the the maximum limit to check for prime power is log n base 2.
Finally problem reduced to finding nth root of a number and if it is prime we have our answer else check for all i till log (n base 2) and exit.
I have used all sort of optimizations and have tested enormous test-cases and for all my algorithm gives correct answer
but Judge says wrong answer.
Spoj have another similar problem with small constraints n<=10^18 for which I already got accepted with Python and C++(Best solver in c++)
Here is My python code Please suggest me if I am doing something wrong I am not very proficient in python so my algorithm is a bit lengthy. Thanks in advance.
My Algorithm:
import math
import sys
import fractions
import random
import decimal
write = sys.stdout.write
def sieve(n):
sqrtn = int(n**0.5)
sieve = [True] * (n+1)
sieve[0] = False
sieve[1] = False
for i in range(2, sqrtn+1):
if sieve[i]:
m = n//i - i
sieve[i*i:n+1:i] = [False] * (m+1)
return sieve
def gcd(a, b):
while b:
a, b = b, a%b
return a
def mr_pass(a, s, d, n):
a_to_power = pow(a, d, n)
if a_to_power == 1:
return True
for i in range(s-1):
if a_to_power == n - 1:
return True
a_to_power = (a_to_power * a_to_power) % n
return a_to_power == n - 1
isprime=sieve(1000000)
sprime= [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127,131,137,139,149,151,157,163,167,173,179,181,191,193,197,199,211,223,227,229,233,239,241,251,257,263,269,271,277,281,283,293,307,311,313,317,331,337,347,349,353,359,367,373,379,383,389,397,401,409,419,421,431,433,439,443,449,457,461,463,467,479,487,491,499,503,509,521,523,541,547,557,563,569,571,577,587,593,599,601,607,613,617,619,631,641,643,647,653,659,661,673,677,683,691,701,709,719,727,733,739,743,751,757,761,769,773,787,797,809,811,821,823,827,829,839,853,857,859,863,877,881,883,887,907,911,919,929,937,941,947,953,967,971,977,983,991,997]
def smooth_num(n):
c=0
for a in sprime:
if(n%a==0):
c+=1
if(c>=2):
return True;
return False
def is_prime(n):
if(n<1000000):
return isprime[n]
if any((n % p) == 0 for p in sprime):
return False
if n==2:
return True
d = n - 1
s = 0
while d % 2 == 0:
d >>= 1
s += 1
for repeat in range(10):
a=random.randint(1,n-1)
if not mr_pass(a, s, d, n):
return False
return True
def iroot(n,k):
hi = 1
while pow(hi, k) < n:
hi *= 2
lo = hi // 2
while hi - lo > 1:
mid = (lo + hi) // 2
midToK = (mid**k)
if midToK < n:
lo = mid
elif n < midToK:
hi = mid
else:
return mid
if (hi**k) == n:
return hi
else:
return lo
def isqrt(x):
n = int(x)
if n == 0:
return 0
a, b = divmod(n.bit_length(), 2)
x = pow(2,(a+b))
while True:
y = (x + n//x)>>1
if y >= x:
return x
x = y
maxx=2**1024;minn=2**64
def nth_rootp(n,k):
return int(round(math.exp(math.log(n)/k),0))
def main():
for cs in range(int(input())):
n=int(sys.stdin.readline().strip())
if(smooth_num(n)):
write("Invalid order\n")
continue;
order = 0;m=0
power =int(math.log(n,2))
for i in range(1,power+1):
if(n<=maxx):
if i==1:m=n
elif(i==2):m=isqrt(n)
elif(i==4):m=isqrt(isqrt(n))
elif(i==8):m=isqrt(isqrt(isqrt(n)))
elif(i==16):m=isqrt(isqrt(isqrt(isqrt(n))))
elif(i==32):m=isqrt(isqrt(isqrt(isqrt(isqrt(n)))))
elif(i==64):m=isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(n))))))
elif(i==128):m=isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(n)))))))
elif(i==256):m=isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(n))))))))
else:m=int(nth_rootp(n,i))
else:
if i==1:m=n
elif i==2:m=isqrt(n)
elif(i==4):m=isqrt(isqrt(n))
elif(i==8):m=isqrt(isqrt(isqrt(n)))
elif(i==16):m=isqrt(isqrt(isqrt(isqrt(n))))
elif(i==32):m=isqrt(isqrt(isqrt(isqrt(isqrt(n)))))
elif(i==64):m=isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(n))))))
elif(i==128):m=isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(n)))))))
elif(i==256):m=isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(isqrt(n))))))))
else:m=iroot(n,i)
if m<2:
order=0
break
if(is_prime(m) and n==(m**i)):
write("%d %d\n"%(m,i))
order = 1
break
if(order==0):
write("Invalid order\n")
main()
I'm not going to read all that code, though I suspect the problem is floating-point inaccuracy. Here is my program to determine if a number n is a prime power; it returns the prime p and the power k:
# prime power predicate
from random import randint
from fractions import gcd
def findWitness(n, k=5): # miller-rabin
s, d = 0, n-1
while d % 2 == 0:
s, d = s+1, d/2
for i in range(k):
a = randint(2, n-1)
x = pow(a, d, n)
if x == 1 or x == n-1: continue
for r in range(1, s):
x = (x * x) % n
if x == 1: return a
if x == n-1: break
else: return a
return 0
# returns p,k such that n=p**k, or 0,0
# assumes n is an integer greater than 1
def primePower(n):
def checkP(n, p):
k = 0
while n > 1 and n % p == 0:
n, k = n / p, k + 1
if n == 1: return p, k
else: return 0, 0
if n % 2 == 0: return checkP(n, 2)
q = n
while True:
a = findWitness(q)
if a == 0: return checkP(n, q)
d = gcd(pow(a,q,n)-a, q)
if d == 1 or d == q: return 0, 0
q = d
The program uses Fermat's Little Theorem and exploits the witness a to the compositeness of n that is found by the Miller-Rabin algorithm. It is given as Algorithm 1.7.5 in Henri Cohen's book A Course in Computational Algebraic Number Theory. You can see the program in action at http://ideone.com/cNzQYr.
this is not really an answer, but I don't have enough space to write it as a comment.
So, if the problem still not solved, you may try the following function for nth_rootp, though it is a bit ugly (it is just a binary search to find the precise value of the function):
def nth_rootp(n,k):
r = int(round(math.log(n,2)/k))
left = 2**(r-1)
right = 2**(r+1)
if left**k == n:
return left
if right**k == n:
return right
while left**k < n and right**k > n:
tmp = (left + right)/2
if tmp**k == n:
return tmp
if tmp == left or tmp == right:
return tmp
if tmp**k < n:
left = tmp
else:
if tmp**k > n:
right = tmp
your code look like a little overcomplicated for this task, I will not bother to check it, but the thing you need are the following
is_prime, naturally
a prime generator, optional
calculate the nth root of a number in a precise way
for the first one I recommend the deterministic form of the Miller-Rabin test with a appropriate set of witness to guaranty a exact result until 1543267864443420616877677640751301 (1.543 x 1033) for even bigger numbers you can use the probabilistic one or use a bigger list of witness chosen at your criteria
with all that a template for the solution is as follow
import math
def is_prime(n):
...
def sieve(n):
"list of all primes p such that p<n"
...
def inthroot(x,n):
"calculate floor(x**(1/n))"
...
def is_a_power(n):
"return (a,b) if n=a**b otherwise throw ValueError"
for b in sieve( math.log2(n) +1 ):
a = inthroot(n,b)
if a**b == n:
return a,b
raise ValueError("is not a power")
def smooth_factorization(n):
"return (p,e) where p is prime and n = p**e if such value exists, otherwise throw ValueError"
e=1
p=n
while True:
try:
p,n = is_a_power(p)
e = e*n
except ValueError:
break
if is_prime(p):
return p,e
raise ValueError
def main():
for test in range( int(input()) ):
try:
p,e = smooth_factorization( int(input()) )
print(p,e)
except ValueError:
print("Invalid order")
main()
And the code above should be self explanatory
Filling the blacks
As you are familiar with Miller-Rabin test, I will only mention that if you are interested you can find a implementation of the determinist version here just update the list of witness and you are ready to go.
For the sieve, just change the one you are using to return a list with primes number like this for instance [ p for p,is_p in enumerate(sieve) if is_p ]
With those out of the way, the only thing left is calculate the nth root of the number and to do that in a precise way we need to get rip of that pesky floating point arithmetic that only produce headaches, and the answer is implement the Nth root algorithm using only integer arithmetic, which is pretty similar to the one of isqrt that you already use, I guide myself with the one made by Mark Dickinson for cube root and generalize it and I get this
def inthroot(A, n) :
"calculate floor( A**(1/n) )"
#https://en.wikipedia.org/wiki/Nth_root_algorithm
#https://en.wikipedia.org/wiki/Nth_root#nth_root_algorithm
#https://stackoverflow.com/questions/35254566/wrong-answer-in-spoj-cubert/35276426#35276426
#https://stackoverflow.com/questions/39560902/imprecise-results-of-logarithm-and-power-functions-in-python/39561633#39561633
if A<0:
if n%2 == 0:
raise ValueError
return - inthroot(-A,n)
if A==0:
return 0
n1 = n-1
if A.bit_length() < 1024: # float(n) safe from overflow
xk = int( round( pow(A,1.0/n) ) )
xk = ( n1*xk + A//pow(xk,n1) )//n # Ensure xk >= floor(nthroot(A)).
else:
xk = 1 << -(-A.bit_length()//n) # 1 << sum(divmod(A.bit_length(),n))
# power of 2 closer but greater than the nth root of A
while True:
sig = A // pow(xk,n1)
if xk <= sig:
return xk
xk = ( n1*xk + sig )//n
and with all the above you can solve the problem without inconvenient
from sympy.ntheory import factorint
q=int(input("Give me the number q="))
fact=factorint(q) #We factor the number q=p_1^{n_1}*p_2^{n_2}*...
p_1=list(fact.keys()) #We create a list from keys to be the the numbers p_1,p_2,...
n_1=list(fact.values()) #We create a list from values to be the the numbers n_1,n_2,...
p=int(p_1[0])
n=int(n_1[0])
if q!=p**n: #Check if the number q=p_{1}[0]**n_{1}[0]=p**n.
print("The number "+str(q)+" is not a prime power")
else:
print("The number "+str(q)+" is a prime power")
print("The prime number p="+str(p))
print("The natural number n="+str(n))

Categories