どーも、みつおです。
問題
3797は面白い性質を持っている. まずそれ自身が素数であり, 左から右に桁を除いたときに全て素数になっている (3797, 797, 97, 7). 同様に右から左に桁を除いたときも全て素数である (3797, 379, 37, 3).
右から切り詰めても左から切り詰めても素数になるような素数は11個しかない. 総和を求めよ.
注: 2, 3, 5, 7を切り詰め可能な素数とは考えない.
出典:Problem37
解答
using System;
namespace Problem37
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Solve());
Console.ReadLine();
}
private static int Solve()
{
int ret = 0;
int limit = 11;
int cnt = 0;
int i = 0;
//切り詰め可能素数が11になるまでループ
while(cnt != limit)
{
i++;
//素数判定
if(IsSosu(i))
{
//切り詰め素数判定
if (IsKiritsumeSosu(i))
{
ret = ret + i;
cnt++;
}
}
}
return ret;
}
private static bool IsKiritsumeSosu(int no)
{
bool ret = true;
int syou = no; //商
int amari = no; //余り
int keta = (int)Math.Pow(10, no.ToString().Length - 1); //最上位の桁を取得するための値
//1桁は切り詰め可能素数と数えない
if (no.ToString().Length == 1) return false;
#region 左から右で素数判定
//桁数分ループ
for (int i = 1; i < no.ToString().Length; i++)
{
//余りを取得
amari = amari % keta;
//素数じゃなければfalseを返す
if (!IsSosu(amari)) return false;
else keta /= 10;
}
#endregion
keta = (int)Math.Pow(10, no.ToString().Length - 1); //最上位の桁を取得するための値
#region 右から左で素数判定
//桁数分ループ
for (int i = 1; i < no.ToString().Length; i++)
{
//商を取得
syou = no / keta;
//素数じゃなければfalseを返す
if (!IsSosu(syou)) return false;
else keta /= 10;
}
#endregion
return ret;
}
private static bool IsSosu(long no)
{
bool ret = true;
//数値が2未満(1)なら素数じゃない、2なら素数
if (no < 2) return false;
else if (no == 2) return true;
//数値が2で割り切れるなら素数じゃない
if (no % 2 == 0) return false;
//合成数xはp≦√xを満たす素因子pをもつ
double sqrtno = Math.Sqrt(no);
//奇数でループ
for (int i = 3; i <= sqrtno; i += 2)
{
//割り切れるので素数じゃない
if (no % i == 0) return false;
}
return ret;
}
}
}
出力
748317


コメント