Problem #146 says:
The smallest positive integer n for which the numbers n^(2)+1, n^(2)+3, n^(2)+7, n^(2)+9, n^(2)+13, and n^(2)+27 are consecutive primes is 10.
The sum of all such integers n below one-million is 1242490.What is the sum of all such integers n below 150 million?
This problem is rather complicated to say the least and my below solution is my first attempt at solving it, it takes about a half hour to run on a quad core machine. There are some tests in place to remove numbers as fast as possible for instance the numbers must be a multiple of 10 before we add a 1,3,7,9,13, or 27 to it, there is also a few modulus test being performed to narrow the search area down some. Then the list of possible numbers is filtered in parallel to make sure we only get consecutive primes. This solution uses the Miller-Rabin code posted earlier with a modified non-recursive toBinary method. There are 12 valid numbers.
Solution provided in f# and requires .net 4.0 and the Fsharp powerpack.
#light
module ProjectEuler
open System
open System.Diagnostics
open Microsoft.FSharp.Linq
open Microsoft.FSharp.Collections
open Microsoft.FSharp.Math
open System.Numerics
let toBinary (n:BigInteger) =
let mutable m = n
let mutable r = []
while m > BigInteger.Zero do
r <- r @ [(m % (BigInteger 2))]
m <- m / BigInteger 2
r
let test (a:BigInteger) (n:BigInteger) =
let (b:List<BigInteger>) = toBinary (n - BigInteger.One)
let mutable d = BigInteger.One
let mutable Prime = false
let CheckList = [0 .. b.Length-1 ] |> List.rev
for i in CheckList do
let x = d
d <- (d*d) % n
if (d = BigInteger.One && x <> BigInteger.One && x <> n-BigInteger.One) then
Prime <- true // complex
if b.[i] = BigInteger.One then
d <- (d*a) % n
if d <> BigInteger.One then
Prime <- true //complex
Prime //if its still false then prime
let MillerRabin (n:uint64) (s:int) =
let Rand = new System.Random()
let mutable Prime = true
if n < Convert.ToUInt64(Int32.MaxValue) then
for j in [1 .. s+1] do
let a = Rand.Next(1, Convert.ToInt32(n)-1)
if (test (BigInteger a) (BigInteger n)) then
Prime <- false
else
for j in [1 .. s+1] do
let a = Rand.Next(1, Int32.MaxValue)
if (test (BigInteger a) (BigInteger n)) then
Prime <- false
Prime
let ntest n =
let k = n / 10UL
if (n%3UL=1UL || n%3UL=2UL)
&& n%13UL<>0UL
&& n%2UL=0UL
&& n%5UL=0UL &&
((n%7UL=3UL || n%7UL=4UL) &&
(n%210UL=10UL ||
n%210UL=80UL ||
n%210UL=130UL ||
n%210UL=200UL )) &&
(k % 7UL = 1UL ||
k % 7UL = 6UL ||
k % 3UL <> 0UL ||
k % 13UL <> 0UL ||
k % 17UL <> 0UL ||
k % 29UL <> 0UL ||
k % 19UL <> 0UL ||
k % 23UL <> 0UL ) then
true
else
false
let nsquaretest n =
let ns = n*n
if ((MillerRabin ((ns)+13UL) 5) &&
(MillerRabin ((ns)+3UL) 5) &&
(MillerRabin ((ns)+7UL) 5) &&
(MillerRabin ((ns)+9UL) 5) &&
(MillerRabin ((ns)+1UL) 5) &&
(MillerRabin ((ns)+27UL) 5) ) then
if (MillerRabin (ns + 19UL) 5 ||
MillerRabin (ns + 21UL) 5) then
false
else
true
else
false
let rec sum (a:uint64) (n:List<uint64>) =
if n = List.empty then
a
else
sum (a+n.Head) n.Tail
let watch = new Stopwatch()
watch.Start()
let check =
[10UL .. 10UL .. 1000000UL]
|> PSeq.filter ntest
|> PSeq.toList
let Answer =
check
|> PSeq.filter nsquaretest
|> PSeq.toList
Console.WriteLine(Answer |> sum 0UL)
Console.WriteLine(Answer.Length)
watch.Stop()
Console.WriteLine(watch.Elapsed)
Console.Beep() |> ignore
Console.ReadKey() |> ignore