Problem #51 says:
By replacing the 1st digit of *3, it turns out that six of the nine possible values: 13, 23, 43, 53, 73, and 83, are all prime.
By replacing the 3rd and 4th digits of 56**3 with the same digit, this 5-digit number is the first example having seven primes among the ten generated numbers, yielding the family: 56003, 56113, 56333, 56443, 56663, 56773, and 56993. Consequently 56003, being the first member of this family, is the smallest prime with this property.
Find the smallest prime which, by replacing part of the number (not necessarily adjacent digits) with the same digit, is part of an eight prime value family.
For this problem what we need to look for are prime numbers that have repeating digits. We replace all of the similar digits with a new value. This means that the digits we replace cannot include the last digit because this will make the number non-prime for almost every replacement. The simplest way to do this is to pre-compute the digit that we are going to replace before going through all of the numbers and swapping digits out. So we have a class called CheckSet which does this for us allowing us to focus on swapping the digits and checking to see if the result is prime.
Solution below is in c#/mono and runs in about 18 seconds.
using System;
using System.Collections;
using System.Diagnostics;
namespace ProjectEuler
{
class MainClass
{
public static void Main (string[] args)
{
Stopwatch sw = new Stopwatch();
sw.Start();
ArrayList p = GeneratePrimes(999999);
ArrayList sub_p = new ArrayList();
foreach (long l in p)
{
if (l > 100000)
{
CheckSet c = new CheckSet(l);
if (c.DigitCount >= 1)
{
sub_p.Add(c);
}
}
}
foreach (CheckSet c in sub_p)
{
int size = FamilySize(ref p,c);
if (size >=8)
{
Console.WriteLine(c.ToString());
sw.Stop();
Console.WriteLine(sw.Elapsed);
Console.ReadLine();
break;
}
}
}
static bool IsPrime(ref ArrayList primes, long num)
{
bool RetVal = true;
long check = Convert.ToInt64(Math.Ceiling(Math.Sqrt(Convert.ToDouble(num))));
foreach (long l in primes)
{
if (l > check)
break;
if (num % l == 0)
RetVal = false;
}
return RetVal;
}
static ArrayList GeneratePrimes(long num)
{
ArrayList RetValue = new ArrayList();
RetValue.Add((long)2);
RetValue.Add((long)3);
long Stepper = 5;
long Check = 1;
while (Stepper <= num)
{
foreach (long i in RetValue)
{
if (Stepper % i == 0)
{
Check = 0;
break;
}
if (Math.Sqrt(Stepper) < i)
{
break;
}
}
if (Check == 1)
{
//Console.WriteLine(((float)Stepper / (float)num) * 100);
RetValue.Add(Stepper);
}
Check = 1;
Stepper++;
Stepper++;
}
return RetValue;
}
static int FamilySize (ref ArrayList primes, CheckSet c)
{
int RetVal = 0;
int[] digits = new int[10] {0,1,2,3,4,5,6,7,8,9};
string num = c.Number.ToString();
string cha = c.Digit;
for (int i = 0; i<10;i++)
{
if (primes.Contains(long.Parse(num.Replace(cha,digits[i].ToString())))
&& long.Parse(num.Replace(cha,digits[i].ToString())).ToString().Length == 6)
{
RetVal++;
}
}
return RetVal;
}
}
class CheckSet
{
public long Number;
public string Digit;
public int DigitCount;
public CheckSet(long number)
{
Number = number;
string s = number.ToString();
string lastc = s[s.Length-1].ToString();
int lengthcheck = s.Length;
int[] digits = new int[10] {0,0,0,0,0,0,0,0,0,0};
if (lastc != "0")
{
s = s.Replace("0","");
digits[0] = lengthcheck - s.Length;
lengthcheck = s.Length;
}
if (lastc != "1")
{
s = s.Replace("1","");
digits[1] = lengthcheck - s.Length;
lengthcheck = s.Length;
}
if (lastc != "2")
{
s = s.Replace("2","");
digits[2] = lengthcheck - s.Length;
lengthcheck = s.Length;
}
if (lastc != "3")
{
s = s.Replace("3","");
digits[3] = lengthcheck - s.Length;
lengthcheck = s.Length;
}
if (lastc != "4")
{
s = s.Replace("4","");
digits[4] = lengthcheck - s.Length;
lengthcheck = s.Length;
}
if (lastc != "5")
{
s = s.Replace("5","");
digits[5] = lengthcheck - s.Length;
lengthcheck = s.Length;
}
if (lastc != "6")
{
s = s.Replace("6","");
digits[6] = lengthcheck - s.Length;
lengthcheck = s.Length;
}
if (lastc != "7")
{
s = s.Replace("7","");
digits[7] = lengthcheck - s.Length;
lengthcheck = s.Length;
}
if (lastc != "8")
{
s = s.Replace("8","");
digits[8] = lengthcheck - s.Length;
lengthcheck = s.Length;
}
if (lastc != "9")
{
s = s.Replace("9","");
digits[9] = lengthcheck - s.Length;
lengthcheck = s.Length;
}
int MostCommonDigit = 0;
int MostCommonDigitCount = 0;
for (int i = 0;i<10;i++)
{
if (digits[i] > MostCommonDigitCount)
{
MostCommonDigit = i;
MostCommonDigitCount = digits[i];
}
}
Digit = MostCommonDigit.ToString();
DigitCount = MostCommonDigitCount;
}
public override string ToString ()
{
return string.Format(Number.ToString() + " :: " + Digit+ " :: " + DigitCount.ToString());
}
}
}