Find GCD of 2 numbers - python

What is wrong here?
The loop conditions should be fulfilled but the program is not entering the loop.
a=100
b=55
c = min(a,b)
while (a % c !=0 // b % c != 0):
c = c - 1
gcd = c
print(gcd)
EDIT: I'm dumb.

// is the floor division operator. You need to use or for the logical OR function. Here is a simple article on basic Python operators.
a=100
b=55
c = min(a,b)
while (a % c !=0) or (b % c != 0):
c = c - 1
gcd = c
print(gcd) # prints 5

Not strictly what you're asking about, but the far more efficient way to compute the gcd is with the Euclidean algorithm. Also, gcd = c does not need to be inside the while loop.
Here's some alternative code.
a = 100
b = 55
while b != 0:
a, b = b, a % b
gcd = a
print(gcd)

Related

How to find exponent of pow(a,b,c) in python

pow(a,x,c) operator in python returns (a**x)%c . If I have values of a, c, and the result of this operation, how can I find the value of x?
Additionally, this is all the information I have
pow(a,x,c) = pow(d,e,c)
Where I know the value of a,c,d, and e.
These numbers are very large (a = 814779647738427315424653119, d = 3, e = 40137673778629769409284441239, c = 1223334444555556666667777777) so I can not just compute these values directly.
I'm aware of the Carmichael's lambda function that can be used to solve for a, but I am not sure if and/or how this applies to solve for x.
Any help will be appreciated.
As #user2357112 says in the comments, this is the discrete logarithm problem, which is computationally very difficult for large c, and no fast general solution is known.
However, for small c there are still some things you can do. Given that a and c are coprime, there is an exponent k < c such that a^k = 1 mod c, after which the powers repeat. Let b = a^x. So, if you brute force it by calculating all powers of a until you get b, you'll have to loop at most c times:
def do_log(a, b, c):
x = 1
p = a
while p != b and p != 1:
x += 1
p *= a
p %= c
if p == b:
return x
else:
return None # no such x
If you run this calculation multiple times with the same a, you can do even better.
# a, c constant
p_to_x = {1: 0}
x = 1
p = a
while p != 1:
p_to_x[p] = x
x += 1
p *= a
p %= c
def do_log_a_c(b):
return p_to_x[b]
Here a cache is made in a loop running at most c times and the cache is accessed in the log function.

Define a function to choose 2 bigger number out of 3 numbers then sum the square of the 2 numbers

Define a function that takes three numbers as arguments and returns the sum of the squares of the two larger numbers.
For example, given 6,7,8, the function that I defined should return 113
When I gave my code, it solves most of the problems but apparently there is some possibility that I haven't tried?? I think my code is flawed but not sure what other possibilities are there. Would really appreciate some help thank you so much!
def bigger_sum(a,b,c):
if(a+b>b+c):
return(a*a+b*b)
if(a+c>b+c):
return(a*a+c*c)
if(b+c>a+c):
return(b*b+c*c)
You can use min for this problem:
def big2_sqrsum(a,b,c):
x = min(a,b,c)
return (a*a + b*b + c*c) - (x*x)
print(big2_sqrsum(6,7,8))
Output:
113
Alternate solution with if-else
def big2_sqrsum2(a,b,c):
if a < b and a <c:
return b*b + c*c
elif b < a and b < c:
return a*a + c*c
elif c < a and c < b:
return a*a + b*b
Just check for the smallest number. That known, assign the values to two new variables that will hold the largest and second largest value and sum their squares.
Something like this :
big1 = 0
big2 = 0
if ([a is smallest]):
big1 = b
big2 = c
elif ([b is smallest]):
big1 = a
big2 = c
elif ([c is smallest]):
big1 = a
big2 = b
allows you to have only one place to calculate your formula :
return big1 * big1 + big2 * big2
Let's take a look at why your code is flawed. Given a comparison like if a + b > b + c:, the implication that both a and b are both greater than c is false. b can be the smallest number. All you know is that a > c, since you can subtract b from both sides of the inequality.
You need to find and discard the smallest number. The simplest way is to compute the minimum with min and subtract it off, as #Sociopath's answer suggests.
If you want to keep your if-elsestructure, you have to compare numbers individually:
if a > b:
n1= a
n2 = b if b > c else c
elif a > c:
n1, n2 = a, b
else:
n1, n2 = b, c
You can Simply Define Function With Using min()
def two_bigger_sum(num1,num2,num3):
min_num = min(num1,num2,num3) # it returns minimum number
return ((num1**2 + num2**2 + num3**2)-(min_num**2)) # num**2 = square of num
print(two_bigger_sum(6,7,8))
Output = 113
Sociopath's answer works, but is inefficient since it requires two extra floating point multiplies. If you're doing this for a large number of items, it will take twice as long! Instead, you can find the two largest numbers directly. Basically, we're sorting the list and taking the two largest, this can be directly as follows:
def sumsquare(a,b,c):
# Strategy: swap, and make sure c is the smallest by the end
if c > b:
b, c = c, b
if c > a:
a, c = c, a
return a**2 + b**2
# Test:
print(sumsquare(3,1,2))
print(sumsquare(3,2,1))
print(sumsquare(1,2,3))
print(sumsquare(1,3,2))
print(sumsquare(2,1,3))
print(sumsquare(2,3,2))
I have tried to use list comprehension & list slicing with sorting method.
def b2(l):
return sum([x**2 for x in sorted(l)[1:]])
print(b2([1,2,3]))
OP:-
13

Error in for loop. (Finding three integers)

So, our teacher gave us an assignment to find three integers a, b c. They are in all between 0 and 450 using Python.
a = c + 11 if b is even
a = 2c-129 if b is odd
b = ac mod 2377
c = (∑(b-7k) from k = 0 too a-1) +142 (Edited. I wrote it wrong. Was -149)
I tired my code that looks like this: (Still a newbie. I guess a lot of my code is wrong)
for a, b, c in range(0, 450):
if b % 2 == 0:
a = c + 11
else:
a = 2 * c - 129
b = (a * c) % 2377
c = sum(b - 7 * k for k in range(0, a - 1))
but I get the error:
for a, b, c in range(0, 450):
TypeError: 'int' object is not iterable
What am I doing wrong and how can I make it check every number between 0 and 450?
The answers by Nick T and Eric hopefully helped you solve your issue with iterating over values of a, b, and c. I would like to also point out that the way you're approaching this problem isn't going to work. What's the point of iterating over various values of a if you're going to re-assign a to something anyway at each iteration of the loop? And likewise for b and c. A better approach involves checking that any given triple (a, b, c) satisfies the conditions given in the assignment. For example:
from itertools import product, tee
def test(a, b, c):
flags = {'a': False,
'b': False,
'c': False}
if (b % 2 == 0 and a == c+11) or (b % 2 == 1 and a == 2*c-129):
flags['a'] = True
if b == (a * c) % 2377:
flags['b'] = True
if c == sum(b - 7*k for k in range(a-1)) - 149:
flags['c'] = True
return all(flags.values()) # True if zero flags are False
def run_tests():
# iterate over all combinations of a=0..450, b=0..450, c=0..450
for a, b, c in product(*tee(range(451), 3)):
if test(a, b, c):
return (a, b, c)
print(run_tests())
NOTE: This is a slow solution. One that does fewer loops, like in glglgl's answer, or Duncan's comment, is obviously favorable. This is really more for illustrative purposes than anything.
import itertools
for b, c in itertools.product(*[range(450)]*2):
if b % 2 == 0:
a = c + 11
else:
a = 2 * c - 129
derived_b = (a * c) % 2377
derived_c = sum(b - 7 * k for k in range(0, a - 1))
if derived_b == b and derived_c == c:
print a, b, c
You need to nest the loops to brute-force it like you are attempting:
for a in range(451): # range(450) excludes 450
for b in range(451):
for c in range(451):
...
It's very obviously O(n3), but if you want a quick and dirty answer, I guess it'll work—only 91 million loops, worst case.
The stuff with [0, 450] is just as a hint.
In fact, your variables are coupled together. You can immediately eliminate at least one loop directly:
for b in range(0, 451):
for c in range(0, 451):
if b % 2: # odd
a = 2 * c - 129
else:
a = c + 11
if b != (a * c) % 2377: continue # test failed
if c != sum(b - 7 * k for k in range(a)): continue # test failed as well
print a, b, c
should do the job.
I won't post full code (after all, it is homework), but you can eliminate two of the outer loops. This is easiest if you iterate over c.
You code should then look something like:
for c in range(451):
# calculate a assuming b is even
# calculate b
# if b is even and a and b are in range:
# calculate what c should be and compare against what it is
# calculate a assuming b is odd
# calculate b
# if b is odd and a and b are in range:
# calculate what c should be and compare against what it is
Extra credit for eliminating the duplication of the code to calculate c
a = c + 11 if b is even
a = 2c-129 if b is odd
b = ac mod 2377
c = (∑(b-7k) from k = 0 to a-1) +142
This gives you a strong relation between all 3 numbers
Given a value a, there are 2 values c (a-11 or (a+129)/2), which in turn give 2 values for b (ac mod 2377 for both values of c, conditioned on the oddity of the result for b), which in turn gets applied in the formula for validating c.
The overall complexity for this is o(n^2) because of the formula to compute c.
Here is an implementation example:
for a in xrange(451):
c_even = a - 11
b = (a*c_even) % 2377
if b % 2 == 0:
c = sum(b - 7 * k for k in range(a)) + 142
if c == c_even:
print (a, b, c)
break
c_odd = (a+129)/2
b = (a*c_odd) % 2377
if b % 2 == 1:
c = sum(b - 7 * k for k in range(a)) + 142
if c == c_odd:
print (a, b, c)
break

Sum of even integers from a to b in Python

This is my code:
def sum_even(a, b):
count = 0
for i in range(a, b, 1):
if(i % 2 == 0):
count += [i]
return count
An example I put was print(sum_even(3,7)) and the output is 0. I cannot figure out what is wrong.
Your indentation is off, it should be:
def sum_even(a, b):
count = 0
for i in range(a, b, 1):
if(i % 2 == 0):
count += i
return count
so that return count doesn't get scoped to your for loop (in which case it would return on the 1st iteration, causing it to return 0)
(And change [i] to i)
NOTE: another problem - you should be careful about using range:
>>> range(3,7)
[3, 4, 5, 6]
so if you were to do calls to:
sum_even(3,7)
sum_even(3,8)
right now, they would both output 10, which is incorrect for sum of even integers between 3 and 8, inclusive.
What you really want is probably this instead:
def sum_even(a, b):
return sum(i for i in range(a, b + 1) if i % 2 == 0)
Move the return statement out of the scope of the for loop (otherwise you will return on the first loop iteration).
Change count += [i] to count += i.
Also (not sure if you knew this), range(a, b, 1) will contain all the numbers from a to b - 1 (not b). Moreover, you don't need the 1 argument: range(a,b) will have the same effect. So to contain all the numbers from a to b you should use range(a, b+1).
Probably the quickest way to add all the even numbers from a to b is
sum(i for i in xrange(a, b + 1) if not i % 2)
You can make it far simpler than that, by properly using the step argument to the range function.
def sum_even(a, b):
return sum(range(a + a%2, b + 1, 2))
You don't need the loop; you can use simple algebra:
def sum_even(a, b):
if (a % 2 == 1):
a += 1
if (b % 2 == 1):
b -= 1
return a * (0.5 - 0.25 * a) + b * (0.25 * b + 0.5)
Edit:
As NPE pointed out, my original solution above uses floating-point maths. I wasn't too concerned, since the overhead of floating-point maths is negligible compared with the removal of the looping (e.g. if calling sum_even(10, 10000)). Furthermore, the calculations use (negative) powers of two, so shouldn't be subject by rounding errors.
Anyhow, with the simple trick of multiplying everything by 4 and then dividing again at the end we can use integers throughout, which is preferable.
def sum_even(a, b):
if (a % 2 == 1):
a += 1
if (b % 2 == 1):
b -= 1
return (a * (2 - a) + b * (2 + b)) // 4
I'd like you see how your loops work if b is close to 2^32 ;-)
As Matthew said there is no loop needed but he does not explain why.
The problem is just simple arithmetic sequence wiki. Sum of all items in such sequence is:
(a+b)
Sn = ------- * n
2
where 'a' is a first item, 'b' is last and 'n' is number if items.
If we make 'a' and b' even numbers we can easily solve given problem.
So making 'a' and 'b' even is just:
if ((a & 1)==1):
a = a + 1
if ((b & 1)==1):
b = b - 1
Now think how many items do we have between two even numbers - it is:
b-a
n = --- + 1
2
Put it into equation and you get:
a+b b-a
Sn = ----- * ( ------ + 1)
2 2
so your code looks like:
def sum_even(a,b):
if ((a & 1)==1):
a = a + 1
if ((b & 1)==1):
b = b - 1
return ((a+b)/2) * (1+((b-a)/2))
Of course you may add some code to prevent a be equal or bigger than b etc.
Indentation matters in Python. The code you write returns after the first item processed.
This might be a simple way of doing it using the range function.
the third number in range is a step number, i.e, 0, 2, 4, 6...100
sum = 0
for even_number in range(0,102,2):
sum += even_number
print (sum)
def sum_even(a,b):
count = 0
for i in range(a, b):
if(i % 2 == 0):
count += i
return count
Two mistakes here :
add i instead of [i]
you return the value directly at the first iteration. Move the return count out of the for loop
The sum of all the even numbers between the start and end number (inclusive).
def addEvenNumbers(start,end):
total = 0
if end%2==0:
for x in range(start,end):
if x%2==0:
total+=x
return total+end
else:
for x in range(start,end):
if x%2==0:
total+=x
return total
print addEvenNumbers(4,12)
little bit more fancy with advanced python feature.
def sum(a,b):
return a + b
def evensum(a,b):
a = reduce(sum,[x for x in range(a,b) if x %2 ==0])
return a
SUM of even numbers including min and max numbers:
def sum_evens(minimum, maximum):
sum=0
for i in range(minimum, maximum+1):
if i%2==0:
sum = sum +i
i= i+1
return sum
print(sum_evens(2, 6))
OUTPUT is : 12
sum_evens(2, 6) -> 12 (2 + 4 + 6 = 12)
List based approach,
Use b+1 if you want to include last value.
def sum_even(a, b):
even = [x for x in range (a, b) if x%2 ==0 ]
return sum(even)
print(sum_even(3,6))
4
[Program finished]
This will add up all your even values between 1 and 10 and output the answer which is stored in the variable x
x = 0
for i in range (1,10):
if i %2 == 0:
x = x+1
print(x)

True/False right angle function in python

I can't seem to get my function to work. When I type in 3 for a, 2 for b, and 3.61 for c. That works. However, when I try those values in a different order (Ex: 3.61 for a, 3 for b and 2 for c) It returns as false. I can't figure out what the problem is. Thanks in advance!
a = input("Enter a ")
b = input("Enter b ")
c = input("Enter c ")
def isright_angled():
if abs((a**2+b**2)-(c**2)) < 0.1 or abs((c**2-a**2)-(b**2)) < 0.1 or abs((c**2-b**2)-(a**2)) < 0.1:
return True
else:
return False
print isright_angled()
The hypotenuse, if the triangle is right-angled, will be the largest of a, b and c. You can use that to avoid duplicating the test 3 times (this is the "don't repeat yourself" principle). A second thing to avoid is that if something: return True else: return False. It's usually better expressed as simply return something. Thirdly, functions can take arguments rather than relying on global variables: this makes things easier to understand and there's then less chance of functions interfering with each other. I find a * a easier to understand than a ** 2 but that's personal taste. Putting all that together:
def is_approximately_right_angled(a, b, c):
a, b, c = sorted([a, b, c])
return abs(a * a + b * b - c * c) < 0.1
a = input('enter a ')
b = input('enter b ')
c = input('enter c ')
print is_approximately_right_angled(a, b, c)
If it's not working, you can speed up your development by adding some checks. If you were writing a big program you can write unit tests, but here just some asserts in the module will avoid you having to type a, b, c in each time to test.
I'd add something like this (before the a = input... line):
assert is_approximately_right_angled(3, 4, 5)
assert is_approximately_right_angled(3, 5, 4)
assert is_approximately_right_angled(3, 2, 3.61)
assert not is_approximately_right_angled(3, 5, 5)
With these lines in place, you can have some confidence in the code before you get to type numbers in. When you find cases where the code doesn't work you can add them as additional checks.
a = int(input("Enter the side length" ))
b = int(input("Enter the side length" ))
c = int(input("Enter the side length" ))
def is_right_triangle(a,b,c):
'''
is_right_triangle(a,b,c) -> bool
returns True if a,b,c is a right triangle with hypotenuse c
'''
a, b, c = sorted([a, b, c])
return a*a + b*b == c*c
print(is_right_triangle(a,b,c))
for more accuracy you can use
return abs(a * a + b * b - c * c) < 0.001

Categories