GCD without using recursion - python-3.x

The code given below is only working correctly for some of the inputs such as gcdIter(2, 12) which gives me correct output i.e 2 but if I give input as gcdIter(220,120) it gives me 110 instead of 20. I need some help with the logic.
def gcdIter(a, b):
'''
a, b: positive integers
returns: a positive integer, the greatest common divisor of a & b.
'''
if a<b:
while a>0:
if b%a==0:
print('the gcd is : '+''+str(a))
break
else:
a -= 1
else:
while b>0:
if a%b==0:
print('the gcd is :'+''+str(b))
break
else:
b -= 1

it's simple like that.No need to check a<b or a>b
def gcdIter(a, b):
while b:
a, b = b, a%b
print('the gcd is :'+str(a))

Related

Having an issue relating to finding an Armstrong number from a list in Python [duplicate]

n=int(input("Enter a Number: "))
x=0
y=0
z=0
while(n>0):
x=n%10
y=x**3
z=z+y
n=n//10
print (z)
#The z here is the same value which I enter, yet it doesn't work.
#If I enter 407 as n, z becomes (4^3)+(0^3)+(7^3) which is 407
if (z==n):
#But even when 407==407, it just wont print the bottom statement
print ("The number is Armstrong")
else:
print ("The number isn't Armstrong")
#it prints that it isn't an Armstrong number
After the while loop, n already became 4//10 which is 0, so it'll never equal z which is 407.
You will want to keep a copy of the original input for comparison.
As a general advice, use a debugger or at least print() your objects to see where the assignments went wrong.
Without using any built-in method
Armstrong number is 371 because 3**3 + 7**3 + 1**3 = 371. according this rule 123 is not Armstrong number because 1**3 + 2**3 + 3**3 is not equal to 123
def count_digit(n):
count = 0
while n > 0:
count += 1
n //= 10
return count
def is_armstrong(n):
given = n
result = 0
digit = count_digit(n)
while n > 0:
reminder = n % 10
result += reminder ** digit
n //= 10
return given == result
is_armstrong(371)
>> True
is_armstrong(123)
>> False
You can take in your initial number as a string so we can more easily convert it to a list. We can then map to create that list of ints. After we can use list comprehension to raise all int in that list to the power that is the len of our list. If the sum of this list equals our input, then we have an Armstrong number.
n = input('Enter a number: ')
nums = list(map(int, n))
raised = [i**len(nums) for i in nums]
if sum(raised) == int(n):
print('The number is Armstrong')
else:
print('The number is not Armstrong')
Expanded list comprehension:
raised = []
for i in nums:
i = i**len(nums)
raised.append(i)
print(raised)
Alternate for map:
nums = []
for i in n:
i = int(i)
nums.append(int(i))
I corrected your code:
n = int(input("Enter a Number: "))
x = 0
y = 0
z = 0
num = n
while n > 0:
x = n % 10
y = x**len(str(num))
z = z+y
n = n//10
print(z)
if (z == num):
print ("The number is Armstrong")
else:
print ("The number isn't Armstrong")
But you can still do it in many ways better. Look at the code of vash_the_stampede and ggorlen.
Or:
def isArmstrong(n):
print(f"{n} is {'' if int(n) == sum(int(i)**len(n) for i in n) else 'not '}an Armstrong number")
isArmstrong(input("Please enter a number: "))
Definition: a number n is an Armstrong number if the sum of each digit in n taken to the power of the total digits in n is equal to n.
It's important to keep track of the original number n, because it'll be needed to compare against the result of z (your variable representing the sum). Since you're mutating n in your while loop, there's no grounds for comparison against your original input, so if (z==n): isn't working like you expect. Save n in another variable, say, original, before reducing it to 0.
Additionally, your code has arbitrarily chosen 3 as the number of digits in the number. For your function to work correctly for any number, you'll need a way to count its digits. One way is to convert the number to a string and take the length.
I strongly recommend using descriptive variable names which reduces the chance of confusing yourself and others. It's only apparent that z represents your sum and x your remainder by virtue of reading through the code. If the code was any longer or more complex, it could be a nightmare to make sense of.
Lastly, Python is not a particularly flexible language from a style standpoint. I recommend adhering to the style guide as best as possible to keep your code readable.
Here's a working example:
def armstrong(n):
total = 0
original = n
digits = len(str(n))
while n > 0:
total += (n % 10) ** digits
n //= 10
return total == original
if __name__ == "__main__":
while 1:
print(armstrong(int(input("Enter a Number: "))))
Output:
Enter a Number: 407
True
Enter a Number: 1234
False
Enter a Number: 23
False
Enter a Number: 8
True
Enter a Number: 371
True
Try it!
total=0
def Armstrong(n):
m=list(n)
global total
for i in m:
total+=pow(int(i),len(n))
if total==int(n):
print ("it is Armstrong number")
else:
print("it is not Armstrong number")
Armstrong(input("enter your number"))
print(total)

How to 'Write a script that computes and prints all of the positive divisors of a user-inputted positive number from lowest to highest in Python?'

Write a script that computes and prints all of the positive divisors of a user-inputted positive number from lowest to highest.
It was with the help of Pythontutor that I was able to get this far. If someone can suggest a better way than what I've done that is appreciated as well.
print('Please enter a positive number:')
num = int(input())
if num < 0:
print('Please enter a positive number:')
else:
for i in range(1,num+1):
calc = i / 2
if calc==int(calc):
print(i)
else:
continue
I expected for this to be considered correct since factors are being returned, but I think the problem is, for example if I input '4', it only returns 2 and 4, not 1.
The below code will work. The below code runs infinitely, Hit Ctrl + c to quit from below code. Remove while True: to remove infinite loop.
while True:
value = int(input('Please enter a positive number: '))
if value < 0:
continue
for i in range(1, value + 1):
if value % i == 0:
print(i)
Output:
1
2
4

Dynamic Programming Primitive calculator code optimization

I am currently doing coursera course on algorithms. I have successfully completed this assignment. All test cases passed. My code looks messy and I want to know if there is any thing availiable in Python which can help run my code faster. Thanks
The problem statement is as follows: You are given a primitive calculator that can perform the following three operations with
the current number đť‘Ą: multiply đť‘Ą by 2, multiply đť‘Ą by 3, or add 1 to đť‘Ą. Your goal is given a
positive integer đť‘›, find the minimum number of operations needed to obtain the number đť‘›
starting from the number 1.
# Uses python3
import sys
def optimal_sequence(m):
a=[0,0]
for i in range(2,m+1):
if i%3==0 and i%2==0:
a.append(min(a[i//2],a[i//3],a[i-1])+1)
elif i%3==0:
a.append(min(a[i//3],a[i-1])+1)
elif i%2==0:
a.append(min(a[i//2],a[i-1])+1)
else:
a.append((a[i-1])+1)
return backtrack(a,m)
def backtrack(a,m):
result=[]
result.append(m)
current = m
for i in range(a[-1],0,-1):
if current%3==0 and a[current//3]==(i-1):
current=current//3
result.append(current)
elif current%2==0 and a[current//2]==(i-1):
current = current//2
result.append(current)
elif a[current-1]==(i-1):
current = current-1
result.append(current)
return result
n = int(input())
if n == 1:
print(0)
print(1)
sys.exit(0)
a= (optimal_sequence(n))
print(len(a)-1)
for x in reversed(a):
print(x,end=" ")
I would use a breadth first search for number 1 starting from number n. Keep track of the numbers that were visited, so that the search backtracks on already visited numbers. For visited numbers remember which is the number you "came from" to reach it, i.e. the next number in the shortest path to n.
In my tests this code runs faster than yours:
from collections import deque
def findOperations(n):
# Perform a BFS
successor = {} # map number to next number in shortest path
queue = deque() # queue with number pairs (curr, next)
queue.append((n,None)) # start at n
while True:
curr, succ = queue.popleft()
if not curr in successor:
successor[curr] = succ
if curr == 1:
break
if curr%3 == 0: queue.append((curr//3, curr))
if curr%2 == 0: queue.append((curr//2, curr))
queue.append((curr-1, curr))
# Create list from successor chain
result = []
i = 1
while i:
result.append(i)
i = successor[i]
return result
Call this function with argument n:
findOperations(n)
It returns a list.

define a function for user input then assign it in another defined function

Creating a function which is based on fermat's last theorem, how to take assign user input to other function and then evaluate it?
def take_input(a,b,c,n):#take input from user
a = int(input("Enter a: "))
b = int(input("Enter b: "))
c = int(input("Enter c: "))
n = int(input("Enter n: "))
c = c**n
return n
def check_fermat(n):#evaluate the input and print results
if n > 2:
if c == a**n + b**n:
print("Holy smokes, Fermat was wrong!")
else:
print("No, that doesn’t work.")
else:
print(n, "enter greater than this.")
check_fermat(take_input)
There are several ways to combine the two functions, the correct way depends on what you want. #Hari_Sheldon's answer uses nested function. In this case check_fermat() can be used only in the body of take_input() function.
Maybe you want two independent functions. Imagine a situation where a function collects the input, and this input can be used by different functions to perform different tasks, calculations, or whatever. Being the input the same, make sense to use a separate function so that you do not have to repeat yourself. In your example (checking Fermat's Last Theorem) you could write:
def take_input(): #take input from user
i_a = int(input("Enter a: "))
i_b = int(input("Enter b: "))
i_c = int(input("Enter c: "))
i_n = int(input("Enter n: "))
return i_a, i_b, i_c, i_n
def check_fermat(): #evaluate the input and print results
a, b, c, n = take_input()
if n > 2:
if c**n == a**n + b**n:
print("Holy smokes, Fermat was wrong!")
else:
print("No, that doesn’t work.")
else:
print(n, "enter greater than this.")
check_fermat()
You do not need to pass as argument the variables which you want from the user (the ones obtained with input()), they will be overwritten in any case. But the function which reads them, must return them otherwise they will be lost.
For greater flexibility I would change the interfaces of the functions in the following way. The input function should return all input values and do not do any calculation. The check function should take all relevant values as parameters.
def take_input():#take input from user
a = int(input("Enter a: "))
b = int(input("Enter b: "))
c = int(input("Enter c: "))
n = int(input("Enter n: "))
return (a, b, c, n)
def check_fermat(a, b, c, n):#evaluate the input and print results
if n > 2:
if c**n == a**n + b**n:
print("Holy smokes, Fermat was wrong!")
else:
print("No, that doesn’t work.")
else:
print("Invalid value for n:", n)
(a, b, c, n) = take_input()
check_fermat(a, b, c, n)
Another possibility would be to move the check for illegal values of n to the input function so it only returns valid inputs.
def take_input(a,b,c,n):#take input from user
a = int(input("Enter a: ")) ##Indentation should be strictly followed in python
b = int(input("Enter b: "))
c = int(input("Enter c: "))
n = int(input("Enter n: "))
c = c**n
def check_fermat():#evaluate the input and print results
if n > 2:
if c == a**n + b**n:
print("Holy smokes, Fermat was wrong!")
else:
print("No, that doesn’t work.")
else:
print(n, "enter greater than this.")
check_fermat()
return n ##return should be last otherwise check_fermat cannot be called

Using Recursive Functions in Python to find Factors of a Given Number

Have tried searching for this, but can't find exactly what I'm looking for.
I want to make a function that will recursively find the factors of a number; for example, the factors of 12 are 1, 2, 3, 4, 6 & 12.
I can write this fairly simply using a for loop with an if statement:
#a function to find the factors of a given number
def print_factors(x):
print ("The factors of %s are:" % number)
for i in range(1, x + 1):
if number % i == 0: #if the number divided by i is zero, then i is a factor of that number
print (i)
number = int(input("Enter a number: "))
print (print_factors(number))
However, when I try to change it to a recursive function, I am getting just a loop of the "The factors of x are:" statement. This is what I currently have:
#uses recursive function to print all the letters of an integer
def print_factors(x): #function to print factors of the number with the argument n
print ("The factors of %s are:" % number)
while print_factors(x) != 0: #to break the recursion loop
for i in range(1,x + 1):
if x % i == 0:
print (i)
number = int(input("Enter a number: "))
print_factors(number)
The error must be coming in either when I am calling the function again, or to do with the while loop (as far as I understand, you need a while loop in a recursive function, in order to break it?)
There are quite many problems with your recursive approach. In fact its not recursive at all.
1) Your function doesn't return anything but your while loop has a comparision while print_factors(x) != 0:
2) Even if your function was returning a value, it would never get to the point of evaluating it and comparing due to the way you have coded.
You are constantly calling your function with the same parameter over and over which is why you are getting a loop of print statements.
In a recursive approach, you define a problem in terms of a simpler version of itself.
And you need a base case to break out of recursive function, not a while loop.
Here is a very naive recursive approach.
def factors(x,i):
if i==0:
return
if x%i == 0:
print(i)
return factors (x,i-1) #simpler version of the problem
factors(12,12)
I think we do using below method:
def findfactor(n):
factorizeDict
def factorize(acc, x):
if(n%x == 0 and n/x >= x):
if(n/x > x):
acc += [x, n//x]
return factorize(acc, x+1)
else:
acc += [x]
return acc
elif(n%x != 0):
return factorize(acc, x+1)
else:
return acc
return factorize(list(), 1)
def factors(x,i=None) :
if i is None :
print('the factors of %s are : ' %x)
print(x,end=' ')
i = int(x/2)
if i == 0 :
return
if x % i == 0 :
print(i,end=' ')
return factors(x,i-1)
num1 = int(input('enter number : '))
print(factors(num1))
Recursion is a functional heritage and so using it with functional style yields the best results. This means avoiding things like mutations, variable reassignments, and other side effects. That said, here's how I'd write factors -
def factors(n, m = 2):
if m >= n:
return
if n % m == 0:
yield m
yield from factors(n, m + 1)
print(list(factors(10))) # [2,5]
print(list(factors(24))) # [2,3,4,6,8,12]
print(list(factors(99))) # [3,9,11,33]
And here's prime_factors -
def prime_factors(n, m = 2):
if m > n:
return
elif n % m == 0:
yield m
yield from prime_factors(n // m, m)
else:
yield from prime_factors(n, m + 1)
print(list(prime_factors(10))) # [2,5]
print(list(prime_factors(24))) # [2,2,2,3]
print(list(prime_factors(99))) # [3,3,11]
def fact (n , a = 2):
if n <= a :
return n
elif n % a != 0 :
return fact(n , a + 1 )
elif n % a == 0:
return str(a) + f" * {str(fact(n / a , a ))}"
Here is another way. The 'x' is the number you want to find the factors of. The 'c = 1' is used as a counter, using it we'll divide your number by 1, then by 2, all the way up to and including your nubmer, and if the modular returns a 0, then we know that number is a factor, so we print it out.
def factors (x,c=1):
if c == x: return x
else:
if x%c == 0: print(c)
return factors(x,c+1)

Resources