Project Euler #66: Diophantine equation

Sort by

recency

|

13 Discussions

|

  • + 0 comments

    I solved this problem using Pell's Equation fundermental solution.

    import math
    
    def is_perfect_square(n):
        """Check if a number is a perfect square."""
        root = int(math.sqrt(n))
        return root * root == n
    
    def continued_fraction_sqrt(n):
        """Compute the continued fraction representation of sqrt(n)."""
        m, d, a = 0, 1, int(math.sqrt(n))
        initial_a = a
        period = []
        
        if initial_a * initial_a == n:  # Perfect square check
            return None, []
        
        while True:
            m = d * a - m
            d = (n - m * m) // d
            a = (initial_a + m) // d
            period.append(a)
            if a == 2 * initial_a:  # Period repeats here
                break
        
        return initial_a, period
    
    def solve_pell_equation(n):
        """Solve Pell's equation x^2 - n * y^2 = 1 for the minimal solution."""
        if is_perfect_square(n):
            raise ValueError(f"The given number {n} is a perfect square, no solution exists.")
        
        a0, period = continued_fraction_sqrt(n)
        if not period:
            return None
        
        # Compute convergents using the periodic continued fraction
        p_prev, p_curr = 1, a0
        q_prev, q_curr = 0, 1
        
        for k in range(1, len(period) * 2 + 1):  # Repeat until period length is hit
            a_k = period[(k - 1) % len(period)]
            p_next = a_k * p_curr + p_prev
            q_next = a_k * q_curr + q_prev
            
            # Check if the solution satisfies Pell's equation
            if p_next * p_next - n * q_next * q_next == 1:
                return p_next, q_next
            
            # Update for the next iteration
            p_prev, p_curr = p_curr, p_next
            q_prev, q_curr = q_curr, q_next
    
    if __name__ == '__main__':
        N = int(input())
        max_x = 0
        index = 2
        for i in range(2, N + 1):
            try:
                x, y = solve_pell_equation(i)
                if x > max_x:
                    max_x = x
                    index = i
            except ValueError as e:
                pass
        print(index)
    
  • + 1 comment

    I'll summarize the Wikipedia/Wolfram info

    1. The minimum solution is the numerator of a continued fraction aproximation of sqrt(D)
    2. let p be the period of the continued fraction and n_i / d_i be the ith convergent in the sequence of continued fraction aproximations of sqrt(D)
    3. if D is even, the solution is n_(p-1)
    4. if D is odd, the solution is n_(2p-1)
    5. Project Euler+ problems 64 and 65 lay the groundwork for this problem
  • + 0 comments

    here is my python 3 100/- Point Solution

    # Enter your code here. Read input from STDIN. Print output to STDOUT
    import math
    
    def is_square(n):
        sqrt_n = int(math.sqrt(n))
        return sqrt_n * sqrt_n == n
    
    def minimal_solution(D):
        m, d, a = 0, 1, int(math.sqrt(D))
        num1, num2 = 1, a
        den1, den2 = 0, 1
    
        while num2*num2 - D*den2*den2 != 1:
            m = d*a - m
            d = (D - m*m) // d
            a = (int(math.sqrt(D)) + m) // d
    
            num1, num2 = num2, a*num2 + num1
            den1, den2 = den2, a*den2 + den1
    
        return num2
    
    def largest_minimal_solution(limit):
        max_D = 0
        max_minimal_solution = 0
    
        for D in range(2, limit + 1):
            if not is_square(D):
                solution = minimal_solution(D)
                if solution > max_minimal_solution:
                    max_minimal_solution = solution
                    max_D = D
    
        return max_D
    
    # Read input and calculate the result
    limit = int(input())
    result = largest_minimal_solution(limit)
    print(result)
    
  • + 0 comments

    Is there a way for you to see the time taken by your code in each test case? I am a noobie and I like to know how fast the computer can crunch the numbers.

  • + 0 comments

    I finally got my solution to work. It was taking too long on the last two cases. Turns out that manual calculation was faster than using python's fractions library.