Syntax for Greatest Common Divisor - Python - python

The program below was more precise and shorter than mine, and thus more appealing. I understand mod (%), but the rest of the syntax on the line noted is confusing me. Does anyone know what this syntax is called or how it works?
The problem asked to create a function to find the greatest common divisor (gcd) for two integers, which is the largest number that divides both numbers without a remainder.
For example, the gcd of 20 and 12 is 4.
def gcd(x, y):
while y != 0:
(x, y) = (y, x % y) ## What is happening here? What's this syntax called?
return x
Link to where I found this program: How to calculate a mod b in python?
Thank you so much for your help!

You have stumbled upon tuple assignments!
In a nutshell, in python, You can assign groups of variables so long as you are assigning them from a structure with the same format
Here is a simpler illustration of what is happening:
a,b = 3,5
#a is now equal to 3 and b is now equal to 5
#You literally could go:
# a = 3
# b = 5
#And it would be logically equivalent
a+b
Returns
>>>8
In your function, you are assigning the value of y (the second parameter of the function) to the variable x, and updating the value of y to the remainder of x/y.
I hope this helps.

Related

How do I write an iterative function that computes the sum of the first n odd numbers it returns 1 + 3 + .... + (2n - 1), using a for loop?

Assuming that n is a positive integer
this is my code:
def sum_odd_n(n):
x =1
for x in range(n):
if x%2==1:
continue
return x + 2
but when I run it on Python it gives me the answer 2. Could you help me by telling me what's wrong and what I should do to solve this?
Since you want to find the sum of first 'n' odd numbers, I suggest you to use range function with step=2. I'll elaborate:
def sum_n(n):
addition=0
for x in range(1,2*n,2):
addition+=x
return addition
s=sum_n(5)
print(s)
This gives output as: 25
Here, in range function, 1st attribute provides starting point, 2nd attribute provides the end point, and 3rd attribute gives the Difference between each number in the sequence.
I hope this helps.
There are a few problems with your code.
The first is that you have a return statement inside the for loop.
Secondly, you just visit the first n integers and check which of them are odd. You won't visit all the first n odd integers.
A list comprehension solution solution is as follows.
def sum_odd_n(n):
# sum up the first n odd numbers
return sum([2*i + 1 for i in range(n)])
Check this program it will work:
a=int(input("how many first odd number sum you want"))
x=1
i=0
def OddSum():
global i
global x
while i<=a:
x+=2
i+=1
print(x)
OddSum()

Repeated String Match

I did Contest 52 of leetcode.com and I had trouble understanding the solution. The problem statement is:
Given two strings A and B, find the minimum number of times A has to be >repeated such that B is a substring of it. If no such solution, return -1.
For example, with A = "abcd" and B = "cdabcdab.
Return 3, because by repeating A three times (“abcdabcdabcd”), B is a >substring of it; and B is not a substring of A repeated two times
("abcdabcd").
The solution is:
def repeatedStringMatch(self, A, B):
"""
:type A: str
:type B: str
:rtype: int
"""
times = int(math.ceil(float(len(B)) / len(A)))
for i in range(2):
if B in (A * (times + i)):
return times + i
return -1
The explanation from one of the collaborators was:
A has to be repeated sufficient times such that it is at least as long as >B (or one more), hence we can conclude that the theoretical lower bound >for the answer would be length of B / length of A.
Let x be the theoretical lower bound, which is ceil(len(B)/len(A)).
The answer n can only be x or x + 1
I don't understand why n can only be x or x+1, can someone help?
If x+1 < n and B is a substring of A repeated n times and you've embedded B in it then either you can chop off the last copy of A without hitting B (meaning that n is not minimal) or else the start of B in A is after the end of the first copy so you can chop off the first copy (and again n is not minimal).
Therefore if it fits at all, it must fit within x+1 copies. Based on length alone it can't fit within < x copies. So the only possibilities left are x and x+1 copies. (And examples can be found where each is the answer.)
Suppose we have two strings m = "abcde" and any 11 character string "e_abcde_abcde", n to be searched. Since the 11 digits are to be matched, the minimum number of characters required is 11 which requires ((n/m)+1)=3 minimum sets for search due to integer rounding. Now the ending position depends on the beginning position and there are at most length(m) unique starting points in each set of m elements. So we can start at each of the positions till the first set is exhausted. The last try may go to m_last = 4, hence the last element of the matched string will go to (n/m+2) set. After the first set is exhausted, the above pattern is exhausted and there is no new searches. Hence we require (n/m + 2) * length (m) for full search.
I know this is an old question still, I would like to add my 2 cents here.
I think #btilly has provided enough clarity but a picture may help further.

Project Euler using Python, Regarding definition of multiples

I started programming recently, my first language being python. I know just the basics of the language including conditionals, loops, range and some other functions.
I tried to solve project euler's problem 1 using python. The problem statement is as follows:
If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000.
Here's my solution:
z=0
for x in range(0,1000,1):
if type(x%3)==int or type(x%5)==int:
z=x+z
print z
The answer i get is 499500 which is wrong. I tried searching for an answer and found that replacing the third line of my solution:
if type(x%3)==int or type(x%5)==int
with
if x%3==0 or x%5==0
yields the correct answer which is 233168.
Why is my code wrong? So far as I'm aware, a multiple need not leave the remainder as zero. For instance, 255 is a multiple of 5. But 255%5 does not leave the remainder as zero. So how does the line if x%3==0 or x%5==0 correct the answer when in fact, it ignores the definition of multiples.
Or perhaps I have wrongly assumed what multiples are. Please help me.
Thank you.
The problem with your original code, is that Modulo operation with natural numbers always yields a natural number.
print type(4%3)
#print <type 'int'>
print type(4%3)==int
#print True
So, what you are doing is basically summing all numbers between 0 and 1000:
print sum(range(0,1000,1))
#prints 499500
Hope that helps
a is a multiple of b iff a = k b with k an integer. Then % is modulo, which is defined like that:
a % b = z iff a = k b + z with k (and z) integers (and 0 <= z < b)
Therefore if z= 0, then a = k b and a is a multiple of b.

Python Set Comprehension

So I have these two problems for a homework assignment and I'm stuck on the second one.
Use a Python Set Comprehension (Python's equivalent of Set Builder notation) to generate a set of all of the prime numbers that are less than 100. Recall that a prime number is an integer that is greater than 1 and not divisible by any integer other than itself and 1. Store your set of primes in a variable (you will need it for additional parts). Output your set of primes (e.g., with the print function).
Use a Python Set Comprehension to generate a set of ordered pairs (tuples of length 2) consisting of all of the prime pairs consisting of primes less than 100. A Prime Pair is a pair of consecutive odd numbers that are both prime. Store your set of Prime Pairs in a variable. Your set of number 1 will be very helpful. Output your Set of Prime Pairs.
For the first one, this works perfectly:
r= {x for x in range(2, 101)
if not any(x % y == 0 for y in range(2, x))}
However, I'm pretty stumped on the second one. I think I may have to take the Cartesian product of the set r with something but I'm just not sure.
This gets me somewhat close but I just want the consecutive pairs.
cart = { (x, y) for x in r for y in r
if x < y }
primes = {x for x in range(2, 101) if all(x%y for y in range(2, min(x, 11)))}
I simplified the test a bit - if all(x%y instead of if not any(not x%y
I also limited y's range; there is no point in testing for divisors > sqrt(x). So max(x) == 100 implies max(y) == 10. For x <= 10, y must also be < x.
pairs = {(x, x+2) for x in primes if x+2 in primes}
Instead of generating pairs of primes and testing them, get one and see if the corresponding higher prime exists.
You can get clean and clear solutions by building the appropriate predicates as helper functions. In other words, use the Python set-builder notation the same way you would write the answer with regular mathematics set-notation.
The whole idea behind set comprehensions is to let us write and reason in code the same way we do mathematics by hand.
With an appropriate predicate in hand, problem 1 simplifies to:
low_primes = {x for x in range(1, 100) if is_prime(x)}
And problem 2 simplifies to:
low_prime_pairs = {(x, x+2) for x in range(1,100,2) if is_prime(x) and is_prime(x+2)}
Note how this code is a direct translation of the problem specification, "A Prime Pair is a pair of consecutive odd numbers that are both prime."
P.S. I'm trying to give you the correct problem solving technique without actually giving away the answer to the homework problem.
You can generate pairs like this:
{(x, x + 2) for x in r if x + 2 in r}
Then all that is left to do is to get a condition to make them prime, which you have already done in the first example.
A different way of doing it: (Although slower for large sets of primes)
{(x, y) for x in r for y in r if x + 2 == y}

List of numbers whose squares are the sum of two squares

I've just started learning Python and have started doing some problems just to help buid my skills however I am pretty stuck on this question.
Make a list containing all positive integers up to 1000 whose squares can be expressed as a sum of two squares, (i,e., integers p for which p^2=m^2+n^2, where m and n are integers greater than 0.)
Hints: There are several approaches. You might find it helpful to have a list of all the square numbers. The in operator might be useful.
Here's the code that I've come up with so far:
numbers=xrange(1001)
numbers_squared=[x**2 for x in numbers]
a=[]
for x in numbers_squared:
for b in numbers_squared:
if (x+b)**.5 <= 1001:
a.append(x+b)
print a
The problem I get with this is that Python takes years to do these calculations (I've waited about ten minutes and it's still printing numbers). Any hints on how to solve this would be very appreciated.
p.s. The main point is to use lists. Also hints would be more appreciated than the solution itself.
Thank You!
First of all, you aren't solving the problem. You need to do a check to make sure (x+b)**.5 is actually an integer.
Secondly, if you are printing numbers, you have already calculated out all the numbers. Doing the above will decrease the time required for this step.
how about a list comprehension?
calculate for c in range(1,1011)
for b in range (1, c)
for a in range (1, b)
as follows:
x = [(a,b,c) for c in range(1,1001) for b in range(1, c) for a in range(1,b) if a**2+b**2==c**2]
print x
I have timed this and it takes 46 seconds to complete on my computer
This might work:
def isSumOfSquares(n):
"""return True if n can be expressed as the sum of two squares; False otherwise"""
for a in xrange(1,n):
b = n-(a**2)
if b<=0:
return False
elif not math.sqrt(b)%1:
return True
return False
answer = [i for i in xrange(1,1001) if isSumOfSquares(i**2)]
Let me know if this works for you
I just answered this elsewhere!
import math
def is_triple(hypotenuse):
"""return (a, b, c) if Pythagrean Triple, else None"""
if hypotenuse < 4:
return None
c = hypotenuse ** 2
for a in xrange(3, hypotenuse):
b = math.sqrt(c - (a ** 2))
if b == int(b):
return a, int(b), hypotenuse
return None
>>> results = [x for x in range(1001) if is_triple(x)]
>>> len(results)
567
Runs almost instantly.

Categories