• Hi Jeff,

    Here's some code so you can run it yourself. I'll add some run results in the next post.

    --Inputs

    DECLARE @MaxNumber INT

    SET @MaxNumber = 5000000

    --Preparation

    SET NOCOUNT ON

    DECLARE @Time DATETIME

    SELECT @Time = GETDATE()

    --Preparation - Numbers table

    DECLARE @SqrtMaxNumber INT

    SET @SqrtMaxNumber = SQRT(@MaxNumber)

    SET ROWCOUNT @SqrtMaxNumber

    CREATE TABLE #Numbers (i BIGINT IDENTITY(1, 1) PRIMARY KEY CLUSTERED, j BIGINT, x bit)

    INSERT INTO #Numbers (x) SELECT NULL FROM syscomments c1, syscomments c2, syscomments c3, syscomments c4

    SET ROWCOUNT 0

    UPDATE #Numbers SET j = i*i

    PRINT 'Checkpoint A: ' + CAST(DATEDIFF(ms, @Time, GETDATE()) AS VARCHAR(10)) + ' ms'

    --Preparation - Put candidate primes into a Primes table

    -- (integers which have an odd number of representations by certain quadratic forms)

    CREATE TABLE #Primes (i BIGINT PRIMARY KEY CLUSTERED)

    INSERT #Primes

    SELECT 2 UNION ALL SELECT 3 UNION ALL

    SELECT k FROM (

        SELECT k FROM (SELECT 4 * a.j + b.j AS k FROM #Numbers a, #Numbers b) c WHERE k <= @MaxNumber AND k % 12 IN (1, 5)

        UNION ALL

        SELECT k from (select 3 * a.j + b.j AS k FROM #Numbers a, #Numbers b) c WHERE k <= @MaxNumber AND k % 12 = 7

        UNION ALL

        SELECT k from (select 3 * a.j - b.j AS k FROM #Numbers a INNER JOIN #Numbers b ON a.i > b.i) c WHERE k <= @MaxNumber AND k % 12 = 11

    ) d GROUP BY k HAVING COUNT(*) IN (1, 3)

    PRINT 'Checkpoint B: ' + CAST(DATEDIFF(ms, @Time, GETDATE()) AS VARCHAR(10)) + ' ms'

    --Calculation - Eliminate composites by sieving

    DECLARE @i BIGINT

    SET @i = 5

    WHILE @i * @i < @MaxNumber

    BEGIN

        DELETE #Primes WHERE i > @i and i % @i = 0

        SELECT @i = min(i) FROM #Primes WHERE i > @i

        PRINT @i

    END

    --Show results

    PRINT 'Finish: ' + CAST(DATEDIFF(ms, @Time, GETDATE()) AS VARCHAR(10)) + ' ms'

    SELECT COUNT(*) AS 'Number of primes', MAX(i) AS 'Max prime', AVG(i) AS 'Average of primes' FROM #Primes

    SELECT * FROM #Primes ORDER BY i

    --Tidy up

    DROP TABLE #Primes

    DROP TABLE #Numbers

    Ryan Randall

    Solutions are easy. Understanding the problem, now, that's the hard part.