1から9の全ての数字を使い, 自由につなげることで
10進数の数字を作り,複数の集合を作ることができる.
集合 {2,5,47,89,631} は面白いことに全ての要素が素数である.
1から9の数字をちょうど1個ずつ含み,
素数の要素しか含まない集合はいくつあるか?
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
const int Jyougen = 98765432;
//const int Jyougen = 631;
static string[] StrSosuuArr;
//エラトステネスの篩
static void Eratosthenes()
{
var IsSosuuArr = new System.Collections.BitArray(Jyougen + 1);
for (int I = 2; I <= IsSosuuArr.Count - 1; I++) {
IsSosuuArr[I] = true;
}
for (int I = 2; I * I <= IsSosuuArr.Count - 1; I++) {
if (I != 2 && I % 2 == 0) continue;
if (IsSosuuArr[I]) {
for (int J = I * 2; J <= IsSosuuArr.Count - 1; J += I) {
IsSosuuArr[J] = false;
}
}
}
var StrSosuuList = new List<string>();
for (int I = 2; I <= IsSosuuArr.Count - 1; I++)
if (IsSosuuArr[I]) StrSosuuList.Add(I.ToString());
//0を含む場合は、対象外
StrSosuuList.RemoveAll(X => X.Contains('0'));
//同じ数字を複数含んだ場合は、対象外
StrSosuuList.RemoveAll(X => HasDuplicate(X));
//8桁で、2と3と5と7を含んだら対象外(1,4,6,8,9は素数でないため)
StrSosuuList.RemoveAll(X =>
{
if (X.Length != 8) return false;
if (X.Contains('2') && X.Contains('3')
&& X.Contains('5') && X.Contains('7')) return true;
return false;
});
//987654321は
//8+7=15 で 5+4=9 で2+1=3 なので、3の倍数であり、素数ではない
//よって、987654321(数字を入れ替えた数を含む)の考慮は不要
StrSosuuArr = StrSosuuList.ToArray();
}
static bool HasDuplicate(string pStr)
{
var wkSet = new HashSet<char>();
foreach (var EachChar in pStr) {
if (wkSet.Add(EachChar) == false)
return true;
}
return false;
}
struct JyoutaiDef
{
internal int CurrP;
internal string Path;
}
static void Main()
{
var sw = System.Diagnostics.Stopwatch.StartNew();
Console.WriteLine("エラトステネスの篩を実行中");
Eratosthenes();
Console.WriteLine("深さ優先探索を実行中");
var Stk = new Stack<JyoutaiDef>();
JyoutaiDef WillPush;
for (int I = 0; I <= StrSosuuArr.GetUpperBound(0); I++) {
//昇順で素数の組み合わせを列挙するので、4桁を超えたらBreak
if (StrSosuuArr[I].Length > 4) break;
WillPush.CurrP = I;
WillPush.Path = StrSosuuArr[I].ToString();
Stk.Push(WillPush);
}
int AnswerCnt = 0;
while (Stk.Count > 0) {
JyoutaiDef Popped = Stk.Pop();
char[] SortedArr = Popped.Path.Where(X => X != ',').OrderBy(X => X).ToArray();
if (SortedArr.SequenceEqual("123456789")) {
AnswerCnt++;
Console.WriteLine("{0}。Answer{1}。{2}", sw.Elapsed, AnswerCnt, Popped.Path);
continue;
}
for (int I = Popped.CurrP + 1; I <= StrSosuuArr.GetUpperBound(0); I++) {
if (SortedArr.Length + StrSosuuArr[I].Length > 9) break;
if (SortedArr.Intersect(StrSosuuArr[I]).Any()) continue;
WillPush.CurrP = I;
WillPush.Path = Popped.Path + "," + StrSosuuArr[I].ToString();
Stk.Push(WillPush);
}
}
}
}
省略 00:00:58.3596577。Answer44668。2,3,5,7,84961 00:00:58.3597300。Answer44669。2,3,5,7,84691 00:00:58.3597960。Answer44670。2,3,5,7,81649 00:00:58.3598608。Answer44671。2,3,5,7,69481 00:00:58.3599256。Answer44672。2,3,5,7,68491 00:00:58.3599898。Answer44673。2,3,5,7,64891 00:00:58.3600546。Answer44674。2,3,5,7,64189 00:00:58.3601262。Answer44675。2,3,5,7,49681 00:00:58.3601901。Answer44676。2,3,5,7,48619 00:00:58.3602547。Answer44677。2,3,5,7,46819 00:00:58.3603192。Answer44678。2,3,5,7,14869 00:00:58.3608458。Answer44679。2,3,5,7,89,641 00:00:58.3609285。Answer44680。2,3,5,7,89,461
ListジェネリックのRemoveAllメソッドで、余計な要素を削除してます。 MSDN --- List<T>.RemoveAll メソッド