Project Euler #86: Cuboid route

  • + 0 comments
    import math
    from typing import List
    
    def get_square_root(a: int) -> int:
        f = 0
        ret = 0
        for i in range(16):
            ret <<= 1
            kari_f = (f + 1) << ((15 - i) * 2)
            if a >= kari_f:
                f = f + 2
                a -= kari_f
                ret += 1
            f <<= 1
        return ret
    
    def combinations(a: int, b_c: int) -> int:
        if 2 * a < b_c:
            return 0
        if a >= b_c:
            return b_c // 2
        return a - (b_c - 1) // 2
    
    def gcd(a: int, b: int) -> int:
        while a != 0:
            temp = a
            a = b % a
            b = temp
        return b
    
    def count_all(limit: int) -> List[int]:
        solutions = [0] * (limit + 1)
        for m in range(1, get_square_root(2 * limit) + 1):
            for n in range(1, m):
                if (m % 2) != (n % 2) and gcd(m, n) == 1:
                    x = m * m - n * n
                    y = 2 * m * n
                    for k in range(1, (limit // x) + 1):
                        solutions[k * x] += combinations(k * x, k * y)
                    for k in range(1, (limit // y) + 1):
                        solutions[k * y] += combinations(k * y, k * x)
        return solutions
    
    def main():
        limit = 10**6
        solutions = count_all(limit)
        total = []
        sum_val = 0
        for i in solutions:
            sum_val += i
            total.append(sum_val)
    
        T = int(input())
        for _ in range(T):
            N = int(input())
            print(total[N])
    
    if __name__ == "__main__":
        main()