https://projecteuler.net/problem=49
10進で表した数字をソートした数をキーに素数を集めます。ただし降順に並べます。例えば、1320なら3210です。昇順だと123になってしまい違う桁の数も同じキーになってしまいます。
問題なのは4つの数が等差数列になるかですが、5桁で早くもそういう数が出てきました。
from collections import Dict import sys #################### List #################### 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 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 fn insert_list[T: CollectionElement](inout v: List[T], e: T, i: Int): v.append(e) for k in range(len(v) - 1, i, -1): v[k] = v[k-1] v[i] = e fn combinations_core[T: CollectionElement](a: List[T], n: Int, k: Int) -> List[List[T]]: if n == 0: return List[List[T]](List[T]()) var vs = List[List[T]]() for k1 in range(k, len(a) - n + 1): var v = combinations_core(a, n-1, k1+1) for w in v: insert_list(w[], a[k1], 0) vs.append(w[]) return vs fn combinations[T: CollectionElement](a: List[T], n: Int) -> List[List[T]]: return combinations_core(a, n, 0) #################### library #################### fn make_prime_table(N: Int) -> List[Int]: var a = initialize_list(N+1, True) for p in range(2, N+1): if p * p > N: break elif not a[p]: continue for n in range(p*p, N+1, p): a[n] = False var ps = List[Int]() for n in range(2, N+1): if a[n]: ps.append(n) return ps fn digits(owned n: Int) -> List[Int]: var ds = List[Int]() while n > 0: var d = n % 10 ds.append(d) n //= 10 return ds #################### process #################### fn sort_number(n: Int) -> Int: var ds = digits(n) sort(ds) var m = 0 for i in range(len(ds)-1, -1, -1): m = m * 10 + ds[i] return m fn classify(N: Int, primes: List[Int]) -> Dict[Int, List[Int]]: var dic = Dict[Int, List[Int]]() for p in primes: if p[] < 10**(N-1): continue var m = sort_number(p[]) if m in dic: try: dic[m].append(p[]) except: pass else: dic[m] = List[Int](p[]) return dic fn is_arithmetic(v: List[Int]) -> Bool: var d = v[1] - v[0] for k in range(2, len(v)): if v[k] - v[k-1] != d: return False return True fn f(N: Int, M: Int): var primes = make_prime_table(10**N) var dic = classify(N, primes) for ns in dic.values(): for v in combinations(ns[], M): if is_arithmetic(v[]): var s = String("") for n in v[]: s += str(n[]) print(s) fn main() raises: var args = sys.argv() var N = atol(args[1]) var M = atol(args[2]) f(N, M)