この問題はどうやっても解けると思いますが、なるべく速そうな方法を考えます。
まず0〜9で4要素の重複組合せを生成します。例えば[1, 4, 7, 8]です。順番を入れ替えて生成される4桁の数はこれで代表されます。そして、ここから順列を生成します。例えば、[1, 1, 2, 3]なら、
[1, 1, 2, 3], [1, 1, 3, 2], [1, 2, 1, 3], [1, 2, 3, 1],
[1, 3, 1, 2], [1, 3, 2, 1], [2, 1, 1, 3], [2, 1, 3, 1],
[2, 3, 1, 1], [3, 1, 1, 2], [3, 1, 2, 1], [3, 2, 1, 1]
重複を避けるためにふつうの順列生成から少し変えています。nextsという関数が少し違います。[1, 1, 2, 3]なら
[(1, [1, 2, 3]), (2, [1, 1, 3]), (3, [1, 1, 2])]
が生成されて、今選んだ要素が第1項、再帰的に生成されるための種が第2項です。
そして、このように生成されたリストの中から、頭が0または最後が偶数または5のものは排除します。ここで数に直します。[1, 4, 7, 8]なら、
[1487, 1847, 4187, 4781, 4817, 4871, 7481, 7841, 8147, 8417, 8471, 8741]
ここからペアを生成します。例えば、1487と1847です。これを等差数列の初項と第2項とみなして第3項を求めます。2207ですね。これが上のリストにあれば、3項とも素数かどうか調べます。
def number(a :List[Int]) = a.foldLeft(0)(_ * 10 + _) def is_prime(n :Int) = Iterator.from(2).takeWhile(p => p * p <= n).forall(n % _ != 0) def repeated_combination[T](a :List[T], n :Int) :Iterator[List[T]] = (a, n) match { case (_, 0) => Iterator(Nil) case (Nil, _) => Iterator() case _ => repeated_combination(a, n - 1).map(a.head :: _) ++ repeated_combination(a.tail, n) } def nexts[T](a :List[T], prev :Option[T]) :List[(T,List[T])] = (a, prev) match { case (Nil, _) => Nil case (h :: t, Some(p)) if h == p => for((n, b) <- nexts(t, prev)) yield (n, h :: b) case (h :: t, _) => (h, t) :: (for((n, b) <- nexts(t, Some(h))) yield (n, h :: b)) } def permutations[T](a :List[T]) :List[List[T]] = if(a == Nil) List(Nil) else for((h, b) <- nexts(a, None); t <- permutations(b)) yield h :: t def solve(a :List[Int]) = { val s = permutations(a). filter(b => b.head != 0 && b.last % 2 == 1 && b.last != 5). map(number) for(b <- s.tails.take(s.size - 1); n1 = b.head; n2 <- b.tail; n3 = n2 * 2 - n1; if b.tail.contains(n3) && List(n1, n2, n3).forall(is_prime)) yield (n1, n2, n3) } val N = 4 for(a <- repeated_combination(List.range(0, 10), 4); b <- solve(a))