https://projecteuler.net/problem=93
1~9から4つの順列を発生させて、それぞれに対して3つ演算の順番の種類で計算します。なかなかめんどうです。
from math import sqrt import sys #################### library #################### fn gcd(n: Int, m: Int) -> Int: return n if m == 0 else gcd(m, n % m) #################### 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 copy_list[T: CollectionElement](a: List[T]) -> List[T]: return sublist(a, 0, len(a)) fn sublist[T: CollectionElement](a: List[T], first: Int, last: Int) -> List[T]: var b = List[T]() for i in range(first, last): b.append(a[i]) return b fn range_list(first: Int, last: Int) -> List[Int]: var v = List[Int]() for n in range(first, last): v.append(n) return v 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 move_to_top[T: CollectionElement](a: List[T], i: Int) -> List[T]: var b = copy_list(a) b[0] = b[i] for j in range(1, i + 1): b[j] = a[j-1] return b fn combinations[T: CollectionElement](a: List[T], n: Int) -> List[List[T]]: return combinations_core(a, n, 0) # [0, m)のn個の順列 fn permutations_core(m: Int, n: Int) -> List[List[Int]]: if n == 0: return List[List[Int]](List[Int]()) else: var vs = List[List[Int]]() var perms = permutations_core(m - 1, n - 1) var a = range_list(0, m) # 最初はどの要素か for i in range(m): var b = move_to_top(a, i) for perm in perms: var v = List[Int](b[0]) for i in range(n - 1): v.append(b[perm[][i]+1]) vs.append(v) return vs fn permutations[T: CollectionElement](a: List[T], n: Int) -> List[List[T]]: var vs = List[List[T]]() var L = len(a) var b = range_list(0, L) var perms = permutations_core(L, n) for perm in perms: var v = List[T]() for i in range(n): v.append(a[perm[][i]]) vs.append(v) return vs #################### Fraction #################### @value struct Fraction(Stringable): var num: Int var den: Int fn __add__(self, other: Fraction) -> Fraction: var d = gcd(self.den, other.den) var num = self.num * (other.den // d) + other.num * (self.den // d) var den = self.den // d * other.den return Fraction(num, den) fn __sub__(self, other: Fraction) -> Fraction: var d = gcd(self.den, other.den) var num = self.num * (other.den // d) - other.num * (self.den // d) var den = self.den // d * other.den return Fraction(num, den) fn __mul__(self, other: Fraction) -> Fraction: var num = self.num * other.num var den = self.den * other.den var d = gcd(num, den) return Fraction(num // d, den // d) fn __truediv__(self, other: Fraction) -> Fraction: var num = self.num * other.den var den = self.den * other.num var d = gcd(num, den) return Fraction(num // d, den // d) fn __str__(self) -> String: if self.den == 1: return str(self.num) else: return str(self.num) + "/" + str(self.den) #################### process #################### fn operate(inout s: List[Fraction], inout op_oder: List[Int], ops: Int) -> Fraction: for i in range(3): var io = op_oder[i] var op = (ops >> (i*2)) & 3 if op == 0: s[io] = s[io] + s[io+1] elif op == 1: s[io] = s[io] - s[io+1] elif op == 2: s[io] = s[io] * s[io+1] else: if s[io+1].num == 0: return Fraction(0, 1) s[io] = s[io] / s[io+1] for j in range(io + 1, 3 - i): s[j] = s[j+1] for j in range(i, 3): if op_oder[j] > io: op_oder[j] -= 1 return s[0] fn f_each(s: List[Int]) -> Int: var nums = Set[Int]() for t in permutations(s, 4): for op_order in permutations(range_list(0, 3), 3): for ops in range(64): var t1 = List[Fraction]() for i in range(4): t1.append(Fraction(t[][i], 1)) var op_o = copy_list(op_order[]) var n = operate(t1, op_o, ops) if n.den == 1: nums.add(n.num) var n = 1 while n in nums: n += 1 return n - 1 fn f() -> String: var max_seq = 0 var max_set = List[Int]() for s in permutations(range_list(1, 10), 4): var seq = f_each(s[]) if seq > max_seq: max_seq = seq max_set = s return str(max_set[0]) + str(max_set[1]) + str(max_set[2]) + str(max_set[3]) fn main(): print(f())