トップページに戻る
次のC#のサンプルへ
前のC#のサンプルへ
Problem51 素数の桁置換
問題
*3の第1桁を置き換えることで, 13, 23, 43, 53, 73, 83という6つの素数が得られる.
56**3の第3桁と第4桁を同じ数で置き換えることを考えよう.
この5桁の数は7つの素数をもつ最初の例である: 56003, 56113, 56333, 56443, 56663, 56773, 56993.
よって, この族の最初の数である56003は, このような性質を持つ最小の素数である.
桁を同じ数で置き換えることで8つの素数が得られる最小の素数を求めよ.
(注:連続した桁でなくても良い)
ソース
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
//const int JyougenKeta = 2; const int NeedsCnt = 6;
//const int JyougenKeta = 5; const int NeedsCnt = 7;
const int JyougenKeta = 6; const int NeedsCnt = 8;
static int[] SosuuArr = new int[(int)Math.Pow(10D, JyougenKeta) + 1];
//エラトステネスの篩
static void Eratosthenes()
{
for (int I = 2; I <= SosuuArr.GetUpperBound(0); I++) {
SosuuArr[I] = I;
}
for (int I = 2; I * I <= SosuuArr.GetUpperBound(0); I++) {
if (I != 2 && I % 2 == 0) continue;
if (SosuuArr[I] != 0) {
for (int J = I * 2; J <= SosuuArr.GetUpperBound(0); J += I) {
SosuuArr[J] = 0;
}
}
}
SosuuArr = SosuuArr.Where(X => X != 0).ToArray();
}
static List<string> PatternList = new List<string>();
static void DerivePatternList()
{
foreach (char EachChar in "123456789*") {
PatternList.Add(EachChar.ToString());
}
for (int Ketasuu = 2; Ketasuu <= JyougenKeta; Ketasuu++) {
foreach (string EachStr in PatternList.FindAll(X => X.Length + 1 == Ketasuu)) {
foreach (char EachChar in "0123456789*") {
PatternList.Add(EachStr + EachChar.ToString());
}
}
}
//少なくとも1つの*があるマッチパターンのみを抽出
PatternList = PatternList.FindAll(X => X.Contains('*'));
//末尾が*の場合は対象外(末尾が0,4,6,8は素数でなく、残りの数字の123579だと6通りしかないから)
PatternList.RemoveAll(X => X.EndsWith("*"));
//末尾が0,2,4,6,8は対象外(末尾が0,4,6,8は素数でなく、末尾が2の素数は1つしかない)
PatternList.RemoveAll(X => X.EndsWith("0") || X.EndsWith("2") || X.EndsWith("4")
|| X.EndsWith("6") || X.EndsWith("8"));
//*を0に変換して数値としてソートしておく (For文のBreakのため)
PatternList = PatternList.OrderBy(X => int.Parse(X.Replace('*', '0'))).
ThenBy(X => X.Length).ToList();
}
static void Main()
{
Eratosthenes();
DerivePatternList();
int AnswerMinStartSosuu = int.MaxValue;
bool HasAnswerKouho = false;
string AnswerPattern = "";
string AnswerSosuuStrs = "";
foreach (string EachPattern in PatternList) {
Console.WriteLine("{0,6}をチェック中", EachPattern);
if (HasAnswerKouho && int.Parse(EachPattern.Replace('*', '0')) > AnswerMinStartSosuu)
break;
var SosuuStrs = new System.Text.StringBuilder();
int OKCnt = 0;
int MinStartSosuu = int.MaxValue;
const string SuutiArr = "0123456789";
for (int I = 0; I <= SuutiArr.Length - 1; I++) {
//先頭が*の場合の0は対象外
if (EachPattern.StartsWith("*") && SuutiArr[I] == '0') continue;
int WillSearchInt = int.Parse(EachPattern.Replace('*', SuutiArr[I]));
if (Array.BinarySearch<int>(SosuuArr, WillSearchInt) >= 0) {
OKCnt++;
if (OKCnt == 1) MinStartSosuu = WillSearchInt;
SosuuStrs.AppendFormat("{0},", WillSearchInt.ToString());
}
int RestCnt = SuutiArr.Length - (I + 1);
if (NeedsCnt - OKCnt > RestCnt) break; //試行回数不足
}
if (NeedsCnt <= OKCnt && MinStartSosuu < AnswerMinStartSosuu) {
AnswerMinStartSosuu = MinStartSosuu;
AnswerPattern = EachPattern;
AnswerSosuuStrs = SosuuStrs.ToString();
HasAnswerKouho = true;
}
}
Console.WriteLine("パターンは{0}", AnswerPattern);
Console.WriteLine("素数リストは{0}", AnswerSosuuStrs.ToString());
}
}
実行結果
省略
1212*9をチェック中
1213*1をチェック中
1213*3をチェック中
1213*5をチェック中
1213*7をチェック中
1213*9をチェック中
1214*1をチェック中
パターンは*2*3*3
素数リストは121313,222323,323333,424343,525353,626363,828383,929393,
解説