Task: Successive prime differences



C#: using System;
using System.Collections.Generic;
using static System.Linq.Enumerable;

public static class SuccessivePrimeDifferences {

    public static void Main() {
        var primes = GeneratePrimes(1_000_000).ToList();
        foreach (var d in new[] {
            new [] { 2 },
            new [] { 1 },
            new [] { 2, 2 },
            new [] { 2, 4 },
            new [] { 4, 2 },
            new [] { 6, 4, 2 },
        }) {
            IEnumerable<int> first = null, last = null;
            int count = 0;
            foreach (var grp in FindDifferenceGroups(d)) {
                if (first == null) first = grp;
                last = grp;
                count++;
            }
            Console.WriteLine($"{$"({string.Join(", ", first)})"}, {$"({string.Join(", ", last)})"}, {count}");
        }

        IEnumerable<IEnumerable<int>> FindDifferenceGroups(int[] diffs) {
            for (int pi = diffs.Length; pi < primes.Count; pi++)
                if (Range(0, diffs.Length).All(di => primes[pi-diffs.Length+di+1] - primes[pi-diffs.Length+di] == diffs[di]))
                    yield return Range(pi - diffs.Length, diffs.Length + 1).Select(i => primes[i]);
        }

        IEnumerable<int> GeneratePrimes(int lmt) {
            bool[] comps = new bool[lmt + 1];
            comps[0] = comps[1] = true;
            yield return 2; yield return 3;
            for (int j = 4; j <= lmt; j += 2) comps[j] = true;
            for (int j = 9; j <= lmt; j += 6) comps[j] = true;
            int i = 5, d = 4, rt = (int)Math.Sqrt(lmt);
            for ( ; i <= rt; i += (d = 6 - d))
                if (!comps[i]) {
                    yield return i;
                    for (int j = i * i, k = i << 1; j <= lmt; j += k)
                        comps[j] = true;
                }
            for ( ; i <= lmt; i += (d = 6 - d)) if (!comps[i]) yield return i;
        }
    }
}





Python: 
from sympy import Sieve

def nsuccprimes(count, mx):
    "return tuple of <count> successive primes <= mx (generator)"
    sieve = Sieve()
    sieve.extend(mx)
    primes = sieve._list
    return zip(*(primes[n:] for n in range(count)))

def check_value_diffs(diffs, values):
    "Differences between successive values given by successive items in diffs?"
    return all(v[1] - v[0] == d 
               for d, v in zip(diffs, zip(values, values[1:])))

def successive_primes(offsets=(2, ), primes_max=1_000_000):
    return (sp for sp in nsuccprimes(len(offsets) + 1, primes_max) 
            if check_value_diffs(offsets, sp))

if __name__ == '__main__':
    for offsets, mx in [((2,),      1_000_000), 
                        ((1,),      1_000_000),
                        ((2, 2),    1_000_000),
                        ((2, 4),    1_000_000),
                        ((4, 2),    1_000_000),
                        ((6, 4, 2), 1_000_000),
                       ]:
        print(f"
              f"SUCCESSIVE DIFFERENCES OF {str(list(offsets))[1:-1]}")
        for count, last in enumerate(successive_primes(offsets, mx), 1):
            if count == 1:
                first = last
        print("  First group:", str(first)[1:-1])
        print("   Last group:", str(last)[1:-1])
        print("        Count:", count)