Skip to content
Snippets Groups Projects

Abs. Alg. HW III Problem 3

  • Clone with SSH
  • Clone with HTTPS
  • Embed
  • Share
    The snippet can be accessed without any authentication.
    Authored by Tyler Bloom

    This is a python3 script to find the GCD of 85 and 1 + 13i (but is generalized to find more).

    Edited
    problem3.py 3.96 KiB
    
    ffrom math import sqrt, ceil
    
    class comp:
        # Constructor (used to create our complex number)
        def __init__( self, x: int, y: int ):
            self.a = x
            self.b = y
        
        # Defines the "-" operation between two complex numbers
        def __eq__( self, other: 'comp' ):
            return (self.a == other.a) and (self.b == other.b)
        
        # Defines the "-" operation between two complex numbers
        def __add__( self, other: 'comp' ):
            return comp( self.a + other.a, self.b + other.b )
    
        # Defines the "-" operation between two complex numbers
        def __sub__( self, other: 'comp' ):
            return comp( self.a - other.a, self.b - other.b )
    
        # Defines the "*" operation between two complex numbers
        def __mul__( self, other: 'comp' ):
            return comp( self.a * other.a - self.b * other.b, self.a * other.b + self.b * other.a )
        
        # Defines how a complex number should be turned into a string (i.e. text)
        def __str__( self ):
            return f'{self.a} {"-" if self.b < 0 else "+"} {abs(self.b)}i'
        
        # Defines the norm of a complex number
        def norm( self ) -> int:
            return self.a**2 + self.b**2
        
        # Creates a shorthand for determining if a complex number is zero
        def isZero( self ) -> bool:
            return self.a == 0 and self.b == 0
    
    
    # Determines if the norm of the remainder is larger than the norm of y
    def canBeQuotient( q , x, y ) -> bool:
        tmp = x - (y*q)
        return tmp.norm() < y.norm() 
    
    
    # Outputs all valid quotients for a pair x, y
    # Creates a box around the valid locations for the remainder and scan that box.
    # All valid quotients for the x, y are put into a list and returned
    def searchForQuotient( x, y ):
        # Determines the radius of the circle that encloses all possible quotients
        radius = ceil(sqrt(x.norm())) if x.norm() > y.norm() else ceil(sqrt(y.norm()))
    
        digest = [ ]
        
        # Scan the real and imag. axises
        for r in range(0, radius):
            if canBeQuotient( comp(  r,  0 ), x, y ): digest.append( comp(  r,  0) )
            if canBeQuotient( comp( -r,  0 ), x, y ): digest.append( comp( -r,  0) )
            if canBeQuotient( comp(  0,  r ), x, y ): digest.append( comp(  0,  r) )
            if canBeQuotient( comp(  0, -r ), x, y ): digest.append( comp(  0, -r ) )
        
        # Scan the box between (1,1) and (radius, radius) 
        # We'll trim out the circle later
        for r_a in range(1, radius):
            for r_b in range(1, radius):
                # If we are outside the circle, go to the next r_a value
                if r_a**2 + r_b**2 > radius**2:
                    break
                if canBeQuotient( comp(  r_a,  r_b ), x, y ): digest.append( comp(  r_a,  r_b) )
                if canBeQuotient( comp( -r_a,  r_b ), x, y ): digest.append( comp( -r_a,  r_b) )
                if canBeQuotient( comp(  r_a, -r_b ), x, y ): digest.append( comp(  r_a, -r_b) )
                if canBeQuotient( comp( -r_a, -r_b ), x, y ): digest.append( comp( -r_a, -r_b) )
        
        return digest
            
    # Finds all common divisors of x, y and returns them
    # This uses recurrsion to implement the Chinese Remainder Theorem 
    def getCommonDivisors( x, y ):
        digest = [ ]
        
        # Finds all valid quotients for x, y
        Qs = searchForQuotient( x, y )
        for q in Qs:
            if (x - y*q).isZero():
                # If the remainder using a quotient, then y is a common divisor of x, y
                digest.append( y )
            else:
                # Otherwise, per the CRT, y becomes x and x-yq (the remainder) becomes y and you try again.
                digest += [ CD for CD in getCommonDivisors( y, x - y*q ) if CD not in digest ]
        
        return digest
    
    
    # Our numbers that we are asked to compute the GCD of
    first = comp( 850, 0 )
    second = comp( 10, 50 )
    
    Qs = searchForQuotient( first, second )
    Ds = getCommonDivisors( first, second )
    
    # Prints some numbers to make sure everything is working
    print( [ str(c) for c in Qs ] )
    print( [ str(c) for c in Ds ] ) # This is our answer
    
    
    for i in range(len(Qs)):
        print( f'{second*Qs[i] + Ds[i]} = ({second})*({Qs[i]}) + ({Ds[i]})' )
    
    problem3_again.py 4.35 KiB
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Finish editing this message first!
    Please register or to comment