MojoでProject Euler 68

https://projecteuler.net/problem=68

しらみつぶしすればいいですが、ちょっとややこしいですね。

import sys


#################### List ####################

fn initialize_list[T: CollectionElement](N: Int, init: T) -> List[T]:
    var a = List[T](capacity=N)
    for n in range(N):
        a.append(init)
    return a

trait Printable(CollectionElement, Stringable):
    pass

fn print_list[T: Printable](a: List[T]):
    if a.size > 0:
        var s = "[" + str(a[0])
        for i in range(1, a.size):
            s += ", " + str(a[i])
        s += "]"
        print(s)
    else:
        print("[]")

fn max_list[T: ComparableCollectionElement](a: List[T]) -> T:
    var max_elem = a[0]
    for i in range(1, len(a)):
        if a[i] > max_elem:
            max_elem = a[i]
    return max_elem


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

fn to_number(v: List[Int]) -> Int:
    var n = 0
    for e in v:
        n = n * (10 if e[] < 10 else 100) + e[]
    return n

fn find_max_ring(pos: Int, used: Int, inout ns: List[Int]) -> Int:
    if pos == len(ns):
        return to_number(ns)
    elif pos >= 4 and pos % 3 == 1:
        # すでに数字がハマっているはず
        var pos2 = pos - 2
        ns[pos] = ns[pos-2]
        return find_max_ring(pos+1, used, ns)
    elif 5 <= pos <= len(ns) - 2 and pos % 3 == 2:
        var n = ns[0] + ns[1] + ns[2] - ns[pos-2] - ns[pos-1]
        if n <= 0 or n > len(ns) or ((used >> n) & 1) == 1:
            return 0
        ns[pos] = n
        return find_max_ring(pos+1, used | (1 << n), ns)
    elif pos == len(ns) - 1:
        ns[pos] = ns[1]
        if ns[0] + ns[1] + ns[2] == ns[pos-2] + ns[pos-1] + ns[pos]:
            return find_max_ring(pos+1, used, ns)
        else:
            return 0
    
    var ring = 0
    for n in range(1, len(ns)//3*2+1):
        if ((used >> n) & 1) == 1:
            continue
        elif pos >= 3 and pos % 3 == 0 and ns[0] > n:
            continue
        ns[pos] = n
        var ring1 = find_max_ring(pos+1, used | (1 << n), ns)
        if ring1 != 0:
            ring = ring1
    return ring

fn f(N: Int) -> Int:
    var ns = initialize_list(N * 3, 0)
    return find_max_ring(0, 0, ns)

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