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;
        }
    }
}


Go: package main

import "fmt"

func sieve(limit int) []int {
    primes := []int{2}
    c := make([]bool, limit+1) 
    
    p := 3
    for {
        p2 := p * p
        if p2 > limit {
            break
        }
        for i := p2; i <= limit; i += 2 * p {
            c[i] = true
        }
        for {
            p += 2
            if !c[p] {
                break
            }
        }
    }
    for i := 3; i <= limit; i += 2 {
        if !c[i] {
            primes = append(primes, i)
        }
    }
    return primes
}

func successivePrimes(primes, diffs []int) [][]int {
    var results [][]int
    dl := len(diffs)
outer:
    for i := 0; i < len(primes)-dl; i++ {
        group := make([]int, dl+1)
        group[0] = primes[i]
        for j := i; j < i+dl; j++ {
            if primes[j+1]-primes[j] != diffs[j-i] {
                group = nil
                continue outer
            }
            group[j-i+1] = primes[j+1]
        }
        results = append(results, group)
        group = nil
    }
    return results
}

func main() {
    primes := sieve(999999)
    diffsList := [][]int{{2}, {1}, {2, 2}, {2, 4}, {4, 2}, {6, 4, 2}}
    fmt.Println("For primes less than 1,000,000:-\n")
    for _, diffs := range diffsList {
        fmt.Println("  For differences of", diffs, "->")
        sp := successivePrimes(primes, diffs)
        if len(sp) == 0 {
            fmt.Println("    No groups found")
            continue
        }
        fmt.Println("    First group   = ", sp[0])
        fmt.Println("    Last group    = ", sp[len(sp)-1])
        fmt.Println("    Number found  = ", len(sp))
        fmt.Println()
    }
}