我目前正在解决Project Euler问题#37:
3797号有一个有趣的属性。作为素数本身,可以从左到右连续删除数字,并在每个阶段保持素数:3797,797,97和7.同样,我们可以从右到左工作:3797,379,37和3。
找到从左到右和从右到左都可截断的仅有11个素数之和。
注意:2,3,5和7不被视为可截断的素数。
所以我做了两个方法1,从左到右删除数字,1从右到左删除,它给出了与示例中相同的结果。但是我得到了11个早期的素数,它们恰好符合截断数字描述,如:
13,17,23,31,37,53,71,73,113,131,137
总和为699.正确的答案是748317.我没有看到任何理由为什么代码没有给出正确的结果或为什么正确的答案不是699。为什么这些数字不算作截断?
private static void Main()
{
int countPrimes = 0;
long sum = 0;
long i = 13;
Stopwatch sw = Stopwatch.StartNew();
while (countPrimes < 11)
{
if (IsTruncatable(i))
{
countPrimes++;
sum += i;
}
i+=2;
}
sw.Stop();
Console.WriteLine(sum);
Console.WriteLine("Time to calculate in milliseconds : {0}", sw.ElapsedMilliseconds);
Console.ReadKey();
}
private static bool IsPrime(long input) // sitoto na eratosten
{
for (int i = 2; i <= Math.Sqrt(input); i++)
{
if (input%i == 0)
{
return false;
}
}
return true;
}
private static bool IsTruncatable(long inputPrime)
{
char[] charDigits = inputPrime.ToString().ToCharArray();
long[] digits = new long[charDigits.Length];
for (int i = 0; i < charDigits.Length; i++)
{
digits[i] = (int)char.GetNumericValue(charDigits[i]);
}
return RemoveDigitsLeft(digits) && RemoveDigitsRight(digits);
}
private static bool RemoveDigitsRight(IReadOnlyList<long> digits)
{
for (int i = 0; i < digits.Count; i++)
{
string tempNumber = string.Empty;
for (int j = i; j < digits.Count; j++)
{
tempNumber += digits[j];
}
if (!IsPrime(long.Parse(tempNumber)))
{
return false;
}
}
return true;
}
private static bool RemoveDigitsLeft(IReadOnlyList<long> digits)
{
for (int i = 0; i < digits.Count; i++)
{
string tempNumber = string.Empty;
for (int j = 0; j < digits.Count - i; j++)
{
tempNumber += digits[j];
}
if (!IsPrime(long.Parse(tempNumber)))
{
return false;
}
}
return true;
}