Related
I need to write a function that will convert the number A to base N. In this case, the number 19 is binary. All I have to do is rewrite the resulting number backwards and return from the function.
I looked into debug mode and didn't understood a thing honestly, it's just looping over line 15 because of... reasons I guess.
def translate(a, n=2):
r1 = []
r2 = ()
r3 = ()
b = int(a/n)
c = a%n
if b >= 1:
r1.append(str(c))
r1.append(str(translate(b,n)))
else:
r1.append(str(c))
return r1
print(translate(19,2))
I didn’t manage to come up with much, after all, I’m not a programmer at all, but I need to do this so that I don’t get expelled.
You don't really need a recursive approach for this. Here's a technique that will work for where 2 <= base <= 10 and a >= 0
def translate(a, base=2):
r = ''
while a > 0:
r += str(a % base)
a //= base
return r[::-1] if r else '0'
The problem was that every time you call the function, it would append to the list and also, the list would be initialized every time it was called. Hence using a global variable and instead of appending the returned value in the if block just running the function again worked. Code:
r1 = []
def translate(a, n=2):
global r1
r2 = ()
r3 = ()
b = int(a/n)
c = a%n
if b >= 1:
r1.append(str(c))
# print(r1)
translate(b,n)
# print(r1)
else:
r1.append(str(c))
# return r1
translate(2,2)
print(''.join(r1)[::-1])# Join and reverse
The assignment is to write a recursive function that receives 2 whole non-negative numbers b, x, and returns True if there's a natural integer n so that b**n=x and False if not. I'm not allowed to use any math operators or loops, except % to determine if a number is even or odd.
but i do have external functions that i can use. Which can add 2 numbers, multiply 2 numbers, and divides a number by 2. also i can write helper function that i can use in the main function.
this is what i got so far, but it only works if b is in the form of 2^y (2,4,8,16 etc)
def is_power(b, x):
if b == x:
return True
if b > x:
return False
return is_power(add(b, b), x) # the func 'add' just adds 2 numbers
Furthermore, the complexity needs to be O(logb * logx)
Thank you.
You can essentially keep multiplying b by b until you reach, or pass, n.
A recursive implementation of this, using a helper function, could look something like this:
def is_power(b, x):
if b == 1: # Check special case
return x == 1
return helper(1, b, x)
def helper(counter, b, x):
if counter == x:
return True
elif counter > x:
return False
else:
return helper(mul(counter, b), b, x) # mul is our special multiplication function
Use the function you say you can use to multiply 2 numbers like:
power = False
result = b
while result < x:
result = yourMultiplyFunction(b,b)
if result == x:
power = True
break
print(power)
Question was EDITTED (can't use loops):
def powerOf(x, b, b1=-1):
if b1 == -1:
b1 = b
if (b == 1) and (x == 1):
return True
elif ( b==1 ) or (x == 1):
return False
if b*b1 < x:
return powerOf(x, b*b1, b1)
elif b*b1 > x:
return False
return True
print(powerOf(625, 25))
A solution that is O(logb * logx) would be slower than a naive sequential search
You can get O(logx / logb) by simply doing this:
def is_power(b,x,bn=1):
if bn == x: return True
if bn > x: return False
return is_power(b,x,bn*b)
I suspect that the objective is to go faster than O(logx/logb) and that the complexity requirement should be something like O(log(logx/logb)^2) which is equivalent to O(log(n)*log(n)).
To get a O(log(n)*log(n)) solution, you can convert the problem into a binary search by implementing a helper function to raise a number to a given power in O(log(n)) time and use it in the O(log(n)) search logic.
def raise_power(b,n): # recursive b^n O(logN)
if not n: return 1 # b^0 = 1
if n%2: return b*raise_power(b*b,n//2) # binary decomposition
return raise_power(b*b,n//2) # of power over base
def find_power(b,x,minp,maxp): # binary search
if minp>maxp: return False # no matching power
n = (minp+maxp)//2 # middle of exponent range
bp = raise_power(b,n) # compute power
if bp == x: return True # match found
if bp > x: return find_power(b,x,minp,n-1) # look in lower sub-range
return find_power(b,x,n+1,maxp) # look in upper sub-range
def max_power(b,x):
return 2*max_power(b*b,x) if b<x else 1 # double n until b^n > x
def is_power(b,x):
maxp = max_power(b,x) # determine upper bound
return find_power(b,x,0,maxp) # use binary search
Note that you will need to convert the *, + and //2 operations to their equivalent external functions in order to meet the requirements of your assignment
In this code, I am trying to get prime factors for the prime method to find LCM. then I am trying to save it by counter but I am not able to divide both key and values for the proper method.
I'm stuck at counter, please can anyone help me?
from collections import Counter
def q2_factor_lcm(a, b): #function for lcm
fa = factor_list(a) #factor list for a
fb = factor_list(b) #factorlist for b
c = Counter(fa) #variables to save counter for a
d = Counter(fb) #variables to save counter for b
r = c | d
r.keys()
for key, value in sorted(r.items()): # for loop for getting counter subtraction
l = pow(key, value)
result = [] # I am getting confused what to do now
for item in l:
result.append(l)
return result #will return result
def factor_list(n): # it is to generate prime numbers
factors = [] # to save list
iprimes = iter( primes_list(n) ) # loop
while n > 1:
p = next(iprimes)
while n % p == 0: # python calculation
n = n // p
factors.append(p)
return factors # it will return factors
First this method is not really efficient to find a lcm. As there are some nice and clean algo to find a gcd, it is easier to get the lcm of a and b by lcm = a * b / gcd(a,b) (*).
Second, never use pow with integer values. Floating point arithmetics is know to be broken not accurate.
Now for your question. The update operation on the 2 counters in not what you want: you lose one of the values when a key is present in both dicts. You should instead use the union of the key sets, and then use the max of both values (a non existent key is seen as a 0 value for the exponent):
...
# use a true dict to be able to later use the get method with a default
c = dict(Counter(fa)) #variables to save counter for a
d = dict(Counter(fb)) #variables to save counter for b
result = []
for key in sorted(set(c.keys()).union(set(d.keys()))):
exp = max(c.get(key, 0), d.get(key, 0))
for i in range(exp):
result.append(key)
return result
(*) The trick is that when a > b, GCD(a,b) is GCD(b, mod(a,b)). In Python it gives immediately:
def gcd(a, b):
if b > a:
return gcd(b, a)
if b == 1:
return b
m = a % b
return b if m == 0 else gcd(b, m)
def lcm(a,b):
return a * b / gcd(a,b)
So I'm writing a program in Python to get the GCD of any amount of numbers.
def GCD(numbers):
if numbers[-1] == 0:
return numbers[0]
# i'm stuck here, this is wrong
for i in range(len(numbers)-1):
print GCD([numbers[i+1], numbers[i] % numbers[i+1]])
print GCD(30, 40, 36)
The function takes a list of numbers.
This should print 2. However, I don't understand how to use the the algorithm recursively so it can handle multiple numbers. Can someone explain?
updated, still not working:
def GCD(numbers):
if numbers[-1] == 0:
return numbers[0]
gcd = 0
for i in range(len(numbers)):
gcd = GCD([numbers[i+1], numbers[i] % numbers[i+1]])
gcdtemp = GCD([gcd, numbers[i+2]])
gcd = gcdtemp
return gcd
Ok, solved it
def GCD(a, b):
if b == 0:
return a
else:
return GCD(b, a % b)
and then use reduce, like
reduce(GCD, (30, 40, 36))
Since GCD is associative, GCD(a,b,c,d) is the same as GCD(GCD(GCD(a,b),c),d). In this case, Python's reduce function would be a good candidate for reducing the cases for which len(numbers) > 2 to a simple 2-number comparison. The code would look something like this:
if len(numbers) > 2:
return reduce(lambda x,y: GCD([x,y]), numbers)
Reduce applies the given function to each element in the list, so that something like
gcd = reduce(lambda x,y:GCD([x,y]),[a,b,c,d])
is the same as doing
gcd = GCD(a,b)
gcd = GCD(gcd,c)
gcd = GCD(gcd,d)
Now the only thing left is to code for when len(numbers) <= 2. Passing only two arguments to GCD in reduce ensures that your function recurses at most once (since len(numbers) > 2 only in the original call), which has the additional benefit of never overflowing the stack.
You can use reduce:
>>> from fractions import gcd
>>> reduce(gcd,(30,40,60))
10
which is equivalent to;
>>> lis = (30,40,60,70)
>>> res = gcd(*lis[:2]) #get the gcd of first two numbers
>>> for x in lis[2:]: #now iterate over the list starting from the 3rd element
... res = gcd(res,x)
>>> res
10
help on reduce:
>>> reduce?
Type: builtin_function_or_method
reduce(function, sequence[, initial]) -> value
Apply a function of two arguments cumulatively to the items of a sequence,
from left to right, so as to reduce the sequence to a single value.
For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
((((1+2)+3)+4)+5). If initial is present, it is placed before the items
of the sequence in the calculation, and serves as a default when the
sequence is empty.
Python 3.9 introduced multiple arguments version of math.gcd, so you can use:
import math
math.gcd(30, 40, 36)
3.5 <= Python <= 3.8.x:
import functools
import math
functools.reduce(math.gcd, (30, 40, 36))
3 <= Python < 3.5:
import fractions
import functools
functools.reduce(fractions.gcd, (30, 40, 36))
A solution to finding out the LCM of more than two numbers in PYTHON is as follow:
#finding LCM (Least Common Multiple) of a series of numbers
def GCD(a, b):
#Gives greatest common divisor using Euclid's Algorithm.
while b:
a, b = b, a % b
return a
def LCM(a, b):
#gives lowest common multiple of two numbers
return a * b // GCD(a, b)
def LCMM(*args):
#gives LCM of a list of numbers passed as argument
return reduce(LCM, args)
Here I've added +1 in the last argument of range() function because the function itself starts from zero (0) to n-1. Click the hyperlink to know more about range() function :
print ("LCM of numbers (1 to 5) : " + str(LCMM(*range(1, 5+1))))
print ("LCM of numbers (1 to 10) : " + str(LCMM(*range(1, 10+1))))
print (reduce(LCMM,(1,2,3,4,5)))
those who are new to python can read more about reduce() function by the given link.
The GCD operator is commutative and associative. This means that
gcd(a,b,c) = gcd(gcd(a,b),c) = gcd(a,gcd(b,c))
So once you know how to do it for 2 numbers, you can do it for any number
To do it for two numbers, you simply need to implement Euclid's formula, which is simply:
// Ensure a >= b >= 1, flip a and b if necessary
while b > 0
t = a % b
a = b
b = t
end
return a
Define that function as, say euclid(a,b). Then, you can define gcd(nums) as:
if (len(nums) == 1)
return nums[1]
else
return euclid(nums[1], gcd(nums[:2]))
This uses the associative property of gcd() to compute the answer
Try calling the GCD() as follows,
i = 0
temp = numbers[i]
for i in range(len(numbers)-1):
temp = GCD(numbers[i+1], temp)
My way of solving it in Python. Hope it helps.
def find_gcd(arr):
if len(arr) <= 1:
return arr
else:
for i in range(len(arr)-1):
a = arr[i]
b = arr[i+1]
while b:
a, b = b, a%b
arr[i+1] = a
return a
def main(array):
print(find_gcd(array))
main(array=[8, 18, 22, 24]) # 2
main(array=[8, 24]) # 8
main(array=[5]) # [5]
main(array=[]) # []
Some dynamics how I understand it:
ex.[8, 18] -> [18, 8] -> [8, 2] -> [2, 0]
18 = 8x + 2 = (2y)x + 2 = 2z where z = xy + 1
ex.[18, 22] -> [22, 18] -> [18, 4] -> [4, 2] -> [2, 0]
22 = 18w + 4 = (4x+2)w + 4 = ((2y)x + 2)w + 2 = 2z
As of python 3.9 beta 4, it has got built-in support for finding gcd over a list of numbers.
Python 3.9.0b4 (v3.9.0b4:69dec9c8d2, Jul 2 2020, 18:41:53)
[Clang 6.0 (clang-600.0.57)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import math
>>> A = [30, 40, 36]
>>> print(math.gcd(*A))
2
One of the issues is that many of the calculations only work with numbers greater than 1. I modified the solution found here so that it accepts numbers smaller than 1. Basically, we can re scale the array using the minimum value and then use that to calculate the GCD of numbers smaller than 1.
# GCD of more than two (or array) numbers - alows folating point numbers
# Function implements the Euclidian algorithm to find H.C.F. of two number
def find_gcd(x, y):
while(y):
x, y = y, x % y
return x
# Driver Code
l_org = [60e-6, 20e-6, 30e-6]
min_val = min(l_org)
l = [item/min_val for item in l_org]
num1 = l[0]
num2 = l[1]
gcd = find_gcd(num1, num2)
for i in range(2, len(l)):
gcd = find_gcd(gcd, l[i])
gcd = gcd * min_val
print(gcd)
HERE IS A SIMPLE METHOD TO FIND GCD OF 2 NUMBERS
a = int(input("Enter the value of first number:"))
b = int(input("Enter the value of second number:"))
c,d = a,b
while a!=0:
b,a=a,b%a
print("GCD of ",c,"and",d,"is",b)
As You said you need a program who would take any amount of numbers
and print those numbers' HCF.
In this code you give numbers separated with space and click enter to get GCD
num =list(map(int,input().split())) #TAKES INPUT
def print_factors(x): #MAKES LIST OF LISTS OF COMMON FACTROS OF INPUT
list = [ i for i in range(1, x + 1) if x % i == 0 ]
return list
p = [print_factors(numbers) for numbers in num]
result = set(p[0])
for s in p[1:]: #MAKES THE SET OF COMMON VALUES IN LIST OF LISTS
result.intersection_update(s)
for values in result:
values = values*values #MULTIPLY ALL COMMON FACTORS TO FIND GCD
values = values//(list(result)[-1])
print('HCF',values)
Hope it helped
UPDATED
a = int(input("Give a value: "))
b = int(input("Give a value: "))
c = int(input("Give a value: "))
def middle(a, b ,c) :
m = min(a,b,c)
M = max(a,b,c)
return a+b+c-m-M
This is where im at. It takes my numbers into the data. How would I get it to display the middle one?! Sorry I'm so terrible at this. Way in over my head on this intro course. #CommuSoft #Zorg #paxdiablo and everyone else
Like others mentioned, you're missing a colon, but for simplicity sake:
def middle(a, b, c):
return sorted([a, b, c])[1]
You should put a colon (:) on the first line (def) as well.
This works for the online python environment:
def input(a, b, c) :
if a <= b <= c or c <= b <= a :
return b
elif b <= a <= c or c <= a <= b :
return a
else:
return c
Furthermore it is more advisable to make use of min and max I guess. Min and max are sometimes directly supported by a CPU and there are implementations that avoid branching (if-then-else's):
def input(a, b, c) :
m = min(a,b,c)
M = max(a,b,c)
return a+b+c-m-M
or:
def input(a, b, c) :
return min(max(a,b),max(b,c),max(a,c))
The last one is also numerically stable.
In most cases if-then-else clauses should be avoided. They reduce the amount of pipelining although in interpreted languages this might not increase performance.
Based on the comments, I guess you want to write an interactive program. This can be done like:
def middle(a, b, c) : #defining a method
return min(max(a,b),max(b,c),max(a,c))
a = int(input("Give a value: "))
b = int(input("Give b value: "))
c = int(input("Give c value: "))
print("The requested value is ")
print(middle(a,b,c)) #calling a method
Defining a method will never result in Python using that method. The a, b and c in the def block are not the a, b and c in the rest of your program. These are "other variables that happen to have the same name". In order to call a method. You write the methods name and between brackets the parameters with which you wish to call your method.
Post your full syntax error (or any other full traceback) whenever you're having trouble.
And your def line needs a colon.
You could do:
def middle(a,b,c):
s={a,b,c}
s-={min(s),max(s)}
return s.pop()
What this does:
Create a set of the unduplicated values:
>>> a,b,c=1,2,3
>>> s={a,b,c}
>>> s
{1, 2, 3}
Remove the max and the min, leaving the middle:
>>> s-={min(s), max(s)}
>>> s
{2}
Pop the only remaining value:
>>> s.pop()
2