MojoでProject Euler 78

https://projecteuler.net/problem=78

分割数そのものですが、剰余計算をします。
上限が分からないので、上限を倍々にします。

import sys


#################### Pair ####################

@value
struct Pair(KeyElement, Stringable):
    var x: Int
    var y: Int
    
    fn __eq__(self, other: Pair) -> Bool:
        return self.x == other.x and self.y == other.y
    
    fn __ne__(self, other: Pair) -> Bool:
        return self.x != other.x or self.y != other.y
    
    fn __hash__(self) -> Int:
        return self.x * 10000 + self.y
    
    fn __str__(self) -> String:
        return '(' + str(self.x) + ', ' + str(self.y) + ')'


#################### process ####################

fn create_divisor(N: Int) -> List[Pair]:
    var a = List[Pair](Pair(0, 1))
    for n in range(1, N+1):
        var m1 = n * (3 * n - 1) // 2
        if m1 > N:
            break
        a.append(Pair(m1, (-1)**n))
        var m2 = n * (3 * n + 1) // 2
        if m2 > N:
            break
        a.append(Pair(m2, (-1)**n))
    return a

fn inverse(a: List[Pair], N: Int, D: Int) -> List[Int]:
    var b = List[Int](1)
    for _ in range(N):
        b.append(0)
    var c = List[Int]()
    for i in range(N+1):
        var be = b[i]
        c.append(be)
        for e in a:
            var j = e[].x + i
            var d = e[].y
            if j > N:
                break
            b[j] = (b[j] - be * d) % D
    return c

fn calc_p(N: Int, D: Int) -> List[Int]:
    var a = create_divisor(N)
    var c = inverse(a, N, D)
    return c

fn f(N: Int) -> Int:
    var n = 2
    while True:
        var p = calc_p(n, N)
        for m in range(n//2+1, n+1):
            if p[m] == 0:
                return m
        n *= 2

fn main() raises:
    var args = sys.argv()
    var N = atol(args[1])
    print(f(N))