Jump to content

Consecutive primes with ascending or descending differences

From Rosetta Code
Task
Consecutive primes with ascending or descending differences
You are encouraged to solve this task according to the task description, using any language you may know.
Task



Find and display here on this page, the longest sequence of consecutive prime numbers where the differences between the primes are strictly ascending.

Do the same for sequences of primes where the differences are strictly descending.

In both cases, show the sequence for primes   <   1,000,000.

If there are multiple sequences of the same length, only the first need be shown.



11l

Translation of: Python
F primes_upto(limit)
   V is_prime = [0B] * 2 [+] [1B] * (limit - 1)
   L(n) 0 .< Int(limit ^ 0.5 + 1.5)
      I is_prime[n]
         L(i) (n * n .. limit).step(n)
            is_prime[i] = 0B
   R enumerate(is_prime).filter((i, prime) -> prime).map((i, prime) -> i)

V primelist = primes_upto(1'000'000)

V listlen = primelist.len

V pindex = 1
V old_diff = -1
V curr_list = [primelist[0]]
[Int] longest_list

L pindex < listlen

   V diff = primelist[pindex] - primelist[pindex - 1]
   I diff > old_diff
      curr_list.append(primelist[pindex])
      I curr_list.len > longest_list.len
         longest_list = curr_list
   E
      curr_list = [primelist[pindex - 1], primelist[pindex]]

   old_diff = diff
   pindex++

print(longest_list)

pindex = 1
old_diff = -1
curr_list = [primelist[0]]
longest_list.drop()

L pindex < listlen

   V diff = primelist[pindex] - primelist[pindex - 1]
   I diff < old_diff
      curr_list.append(primelist[pindex])
      I curr_list.len > longest_list.len
         longest_list = curr_list
   E
      curr_list = [primelist[pindex - 1], primelist[pindex]]

   old_diff = diff
   pindex++

print(longest_list)
Output:
[128981, 128983, 128987, 128993, 129001, 129011, 129023, 129037]
[322171, 322193, 322213, 322229, 322237, 322243, 322247, 322249]

ALGOL 68

BEGIN # find sequences of primes where the gaps between the elements #
      # are strictly ascending/descending                            #
    # reurns a list of primes up to n #
    PROC prime list = ( INT n )[]INT:
         BEGIN
            # sieve the primes to n #
            INT no = 0, yes = 1;
            [ 1 : n ]INT p;
            p[ 1 ] := no; p[ 2 ] := yes;
            FOR i FROM 3 BY 2 TO n DO p[ i ] := yes OD;
            FOR i FROM 4 BY 2 TO n DO p[ i ] := no  OD;
            FOR i FROM 3 BY 2 TO ENTIER sqrt( n ) DO
                IF p[ i ] = yes THEN FOR s FROM i * i BY i + i TO n DO p[ s ] := no OD FI
            OD;
            # replace the sieve with a list #
            INT p pos := 0;
            FOR i TO n DO IF p[ i ] = yes THEN p[ p pos +:= 1 ] := i FI OD;
            p[ 1 : p pos ]
         END # prime list # ;
    # shos the results of a search #
    PROC show sequence = ( []INT primes, STRING seq name, INT seq start, seq length )VOID:
         BEGIN
            print( ( "    The longest sequence of primes with "
                   , seq name
                   , " differences contains "
                   , whole( seq length, 0 )
                   , " primes"
                   , newline
                   , "        First such sequence (differences in brackets):"
                   , newline
                   , "            "
                   )
                 );
            print( ( whole( primes[ seq start ], 0 ) ) );
            FOR p FROM seq start + 1 TO seq start + ( seq length - 1 ) DO
                print( ( " (", whole( ABS( primes[ p ] - primes[ p - 1 ] ), 0 ), ") " ) );
                print( ( whole( primes[ p ], 0 ) ) )
            OD;
            print( ( newline ) )
         END # show seuence # ;
    # find the longest sequence of primes where the successive differences are ascending/descending #
    PROC find sequence = ( []INT primes, BOOL ascending, REF INT seq start, seq length )VOID:
         BEGIN
            seq start     := seq length := 0;
            INT start diff = IF ascending THEN 0 ELSE UPB primes + 1 FI;
            FOR p FROM LWB primes TO UPB primes DO
                INT prev diff := start diff;
                INT length    := 1;
                FOR s FROM p + 1 TO UPB primes
                WHILE INT diff = ABS ( primes[ s ] - primes[ s - 1 ] );
                      IF ascending THEN diff > prev diff ELSE diff < prev diff FI
                DO
                    length   +:= 1;
                    prev diff := diff
                OD;
                IF length > seq length THEN
                    # found a longer sequence #
                    seq length := length;
                    seq start  := p
                FI
            OD
         END # find sequence #;
    BEGIN
        INT max number   = 1 000 000;
        []INT primes     = prime list( max number );
        INT asc length  := 0;
        INT asc start   := 0;
        INT desc length := 0;
        INT desc start  := 0;
        find sequence( primes, TRUE,   asc start,  asc length );
        find sequence( primes, FALSE, desc start, desc length );
        # show the sequences #
        print( ( "For primes up to ", whole( max number, 0 ), newline ) );
        show sequence( primes, "ascending",   asc start,  asc length );
        show sequence( primes, "descending", desc start, desc length )
    END
END
Output:
For primes up to 1000000
    The longest sequence of primes with ascending differences contains 8 primes
        First such sequence (differences in brackets):
            128981 (2) 128983 (4) 128987 (6) 128993 (8) 129001 (10) 129011 (12) 129023 (14) 129037
    The longest sequence of primes with descending differences contains 8 primes
        First such sequence (differences in brackets):
            322171 (22) 322193 (20) 322213 (16) 322229 (8) 322237 (6) 322243 (4) 322247 (2) 322249

BASIC

FreeBASIC

Use any of the primality testing code on this site as an include; I won't reproduce it here.

#define UPPER 1000000
#include"isprime.bas"

dim as uinteger champ = 0, record = 0, streak, i, j, n

'first generate all the primes below UPPER
redim as uinteger prime(1 to 2)
prime(1) = 2 : prime(2) = 3
for i = 5 to UPPER step 2
    if isprime(i) then
        redim preserve prime(1 to ubound(prime) + 1)
        prime(ubound(prime)) = i
    end if
next i
n = ubound(prime)

'now look for the longest streak of ascending primes
for i = 2 to n-1
    j = i + 1
    streak = 1
    while j<=n andalso prime(j)-prime(j-1) > prime(j-1)-prime(j-2)
        streak += 1
        j+=1
    wend
    if streak > record then
        champ = i-1
        record = streak
    end if
next i

print "The longest sequence of ascending primes (with their difference from the last one) is:"
for i = champ+1 to champ+record
    print prime(i-1);" (";prime(i)-prime(i-1);") ";
next i
print prime(i-1) : print
'now for the descending ones

record = 0 : champ = 0
for i = 2 to n-1
    j = i + 1
    streak = 1
    while j<=n andalso prime(j)-prime(j-1) < prime(j-1)-prime(j-2)   'identical to above, but for the inequality sign
        streak += 1
        j+=1
    wend
    if streak > record then
        champ = i-1
        record = streak
    end if
next i

print "The longest sequence of descending primes (with their difference from the last one) is:"
for i = champ+1 to champ+record
    print prime(i-1);" (";prime(i)-prime(i-1);") ";
next i
print prime(i-1)
Output:
The longest sequence of ascending primes (with their difference from the last one) is:
128981 (2) 128983 (4) 128987 (6) 128993 (8) 129001 (10) 129011 (12) 129023 (14) 129037

The longest sequence of descending primes (with their difference from the last one) is:
322171 (22) 322193 (20) 322213 (16) 322229 (8) 322237 (6) 322243 (4) 322247 (2) 322249

C

Translation of: Wren

More or less.

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <string.h>

bool *sieve(int limit) {
    int i, p;
    limit++;
    // True denotes composite, false denotes prime.
    bool *c = calloc(limit, sizeof(bool)); // all false by default
    c[0] = true;
    c[1] = true;
    for (i = 4; i < limit; i += 2) c[i] = true;
    p = 3; // Start from 3.
    while (true) {
        int p2 = p * p;
        if (p2 >= limit) break;
        for (i = p2; i < limit; i += 2 * p) c[i] = true;
        while (true) {
            p += 2;
            if (!c[p]) break;
        }
    }
    return c;
}

void longestSeq(int *primes, int pc, bool asc) {
    int i, j, d, pd = 0, lls = 1, lcs = 1;
    int longSeqs[25][10] = {{2}};
    int lsl[25] = {1};
    int currSeq[10] = {2};
    const char *dir = asc ? "ascending" : "descending";
    for (i = 1; i < pc; ++i) {
        d = primes[i] - primes[i-1];
        if ((asc && d <= pd) || (!asc && d >= pd)) {
            if (lcs > lsl[0]) {
                memcpy((void *)longSeqs[0], (void *)currSeq, lcs * sizeof(int));
                lsl[0] = lcs;
                lls = 1;
            } else if (lcs == lsl[0]) {
                memcpy((void *)longSeqs[lls], (void *)currSeq, lcs * sizeof(int));
                lsl[lls++] = lcs;
            }
            currSeq[0] = primes[i-1];
            currSeq[1] = primes[i];
            lcs = 2;
        } else {
            currSeq[lcs++] = primes[i];
        }
        pd = d;
    }
    if (lcs > lsl[0]) {
        memcpy((void *)longSeqs[0], (void *)currSeq, lcs * sizeof(int));
        lsl[0] = lcs;
        lls = 1;
    } else if (lcs == lsl[0]) {
        memcpy((void *)longSeqs[lls], (void *)currSeq, lcs * sizeof(int));
        lsl[lls++] = lcs;
    }
    printf("Longest run(s) of primes with %s differences is %d:\n", dir, lsl[0]);
    for (i = 0; i < lls; ++i) {
        int *ls = longSeqs[i];
        for (j = 0; j < lsl[i]-1; ++j) printf("%d (%d) ", ls[j], ls[j+1] - ls[j]);
        printf("%d\n", ls[lsl[i]-1]);
    }
    printf("\n");
}

int main() {
    const int limit = 999999;
    int i, j, pc = 0;
    bool *c = sieve(limit);
    for (i = 0; i < limit; ++i) {
        if (!c[i]) ++pc;
    }
    int *primes = (int *)malloc(pc * sizeof(int));
    for (i = 0, j = 0; i < limit; ++i) {
        if (!c[i]) primes[j++] = i;
    }
    free(c);
    printf("For primes < 1 million:\n");
    longestSeq(primes, pc, true);
    longestSeq(primes, pc, false);
    free(primes);
    return 0;
}
Output:
For primes < 1 million:
Longest run(s) of primes with ascending differences is 8:
128981 (2) 128983 (4) 128987 (6) 128993 (8) 129001 (10) 129011 (12) 129023 (14) 129037
402581 (2) 402583 (4) 402587 (6) 402593 (8) 402601 (12) 402613 (18) 402631 (60) 402691
665111 (2) 665113 (4) 665117 (6) 665123 (8) 665131 (10) 665141 (12) 665153 (24) 665177

Longest run(s) of primes with descending differences is 8:
322171 (22) 322193 (20) 322213 (16) 322229 (8) 322237 (6) 322243 (4) 322247 (2) 322249
752207 (44) 752251 (12) 752263 (10) 752273 (8) 752281 (6) 752287 (4) 752291 (2) 752293

C#

Extended the limit up to see what would happen.

using System.Linq;
using System.Collections.Generic;
using TG = System.Tuple<int, int>;
using static System.Console;

class Program
{
    static void Main(string[] args)
    {
        const int mil = (int)1e6;
        foreach (var amt in new int[] { 1, 2, 6, 12, 18 })
        {
            int lmt = mil * amt, lg = 0, ng, d, ld = 0;
            var desc = new string[] { "A", "", "De" };
            int[] mx = new int[] { 0, 0, 0 },
                  bi = new int[] { 0, 0, 0 },
                   c = new int[] { 2, 2, 2 };
            WriteLine("For primes up to {0:n0}:", lmt);
            var pr = PG.Primes(lmt).ToArray();
            for (int i = 0; i < pr.Length; i++)
            {
                ng = pr[i].Item2; d = ng.CompareTo(lg) + 1;
                if (ld == d)
                    c[2 - d]++;
                else
                {
                    if (c[d] > mx[d]) { mx[d] = c[d]; bi[d] = i - mx[d] - 1; }
                    c[d] = 2;
                }
                ld = d; lg = ng;
            }
            for (int r = 0; r <= 2; r += 2)
            {
                Write("{0}scending, found run of {1} consecutive primes:\n  {2} ",
                    desc[r], mx[r] + 1, pr[bi[r]++].Item1);
                foreach (var itm in pr.Skip(bi[r]).Take(mx[r]))
                    Write("({0}) {1} ", itm.Item2, itm.Item1); WriteLine(r == 0 ? "" : "\n");
            }
        }
    }
}

class PG
{
    public static IEnumerable<TG> Primes(int lim)
    {
        bool[] flags = new bool[lim + 1];
        int j = 3, lj = 2;
        for (int d = 8, sq = 9; sq <= lim; j += 2, sq += d += 8)
            if (!flags[j])
            {
                yield return new TG(j, j - lj);
                lj = j;
                for (int k = sq, i = j << 1; k <= lim; k += i) flags[k] = true;
            }
        for (; j <= lim; j += 2)
            if (!flags[j])
            {
                yield return new TG(j, j - lj);
                lj = j;
            }
    }
}
Output:
For primes up to 1,000,000:
Ascending, found run of 8 consecutive primes:
  128981 (2) 128983 (4) 128987 (6) 128993 (8) 129001 (10) 129011 (12) 129023 (14) 129037
Descending, found run of 8 consecutive primes:
  322171 (22) 322193 (20) 322213 (16) 322229 (8) 322237 (6) 322243 (4) 322247 (2) 322249

For primes up to 2,000,000:
Ascending, found run of 9 consecutive primes:
  1319407 (4) 1319411 (8) 1319419 (10) 1319429 (14) 1319443 (16) 1319459 (18) 1319477 (32) 1319509 (34) 1319543
Descending, found run of 8 consecutive primes:
  322171 (22) 322193 (20) 322213 (16) 322229 (8) 322237 (6) 322243 (4) 322247 (2) 322249

For primes up to 6,000,000:
Ascending, found run of 9 consecutive primes:
  1319407 (4) 1319411 (8) 1319419 (10) 1319429 (14) 1319443 (16) 1319459 (18) 1319477 (32) 1319509 (34) 1319543
Descending, found run of 9 consecutive primes:
  5051309 (32) 5051341 (28) 5051369 (14) 5051383 (10) 5051393 (8) 5051401 (6) 5051407 (4) 5051411 (2) 5051413

For primes up to 12,000,000:
Ascending, found run of 9 consecutive primes:
  1319407 (4) 1319411 (8) 1319419 (10) 1319429 (14) 1319443 (16) 1319459 (18) 1319477 (32) 1319509 (34) 1319543
Descending, found run of 10 consecutive primes:
  11938793 (60) 11938853 (38) 11938891 (28) 11938919 (14) 11938933 (10) 11938943 (8) 11938951 (6) 11938957 (4) 11938961 (2) 11938963

For primes up to 18,000,000:
Ascending, found run of 10 consecutive primes:
  17797517 (2) 17797519 (4) 17797523 (8) 17797531 (10) 17797541 (12) 17797553 (20) 17797573 (28) 17797601 (42) 17797643 (50) 17797693
Descending, found run of 10 consecutive primes:
  11938793 (60) 11938853 (38) 11938891 (28) 11938919 (14) 11938933 (10) 11938943 (8) 11938951 (6) 11938957 (4) 11938961 (2) 11938963

C++

Library: Primesieve
#include <cstdint>
#include <iostream>
#include <vector>
#include <primesieve.hpp>

void print_diffs(const std::vector<uint64_t>& vec) {
    for (size_t i = 0, n = vec.size(); i != n; ++i) {
        if (i != 0)
            std::cout << " (" << vec[i] - vec[i - 1] << ") ";
        std::cout << vec[i];
    }
    std::cout << '\n';
}

int main() {
    std::cout.imbue(std::locale(""));
    std::vector<uint64_t> asc, desc;
    std::vector<std::vector<uint64_t>> max_asc, max_desc;
    size_t max_asc_len = 0, max_desc_len = 0;
    uint64_t prime;
    const uint64_t limit = 1000000;
    for (primesieve::iterator pi; (prime = pi.next_prime()) < limit; ) {
        size_t alen = asc.size();
        if (alen > 1 && prime - asc[alen - 1] <= asc[alen - 1] - asc[alen - 2])
            asc.erase(asc.begin(), asc.end() - 1);
        asc.push_back(prime);
        if (asc.size() >= max_asc_len) {
            if (asc.size() > max_asc_len) {
                max_asc_len = asc.size();
                max_asc.clear();
            }
            max_asc.push_back(asc);
        }
        size_t dlen = desc.size();
        if (dlen > 1 && prime - desc[dlen - 1] >= desc[dlen - 1] - desc[dlen - 2])
            desc.erase(desc.begin(), desc.end() - 1);
        desc.push_back(prime);
        if (desc.size() >= max_desc_len) {
            if (desc.size() > max_desc_len) {
                max_desc_len = desc.size();
                max_desc.clear();
            }
            max_desc.push_back(desc);
        }
    }
    std::cout << "Longest run(s) of ascending prime gaps up to " << limit << ":\n";
    for (const auto& v : max_asc)
        print_diffs(v);
    std::cout << "\nLongest run(s) of descending prime gaps up to " << limit << ":\n";
    for (const auto& v : max_desc)
        print_diffs(v);
    return 0;
}
Output:
Longest run(s) of ascending prime gaps up to 1,000,000:
128,981 (2) 128,983 (4) 128,987 (6) 128,993 (8) 129,001 (10) 129,011 (12) 129,023 (14) 129,037
402,581 (2) 402,583 (4) 402,587 (6) 402,593 (8) 402,601 (12) 402,613 (18) 402,631 (60) 402,691
665,111 (2) 665,113 (4) 665,117 (6) 665,123 (8) 665,131 (10) 665,141 (12) 665,153 (24) 665,177

Longest run(s) of descending prime gaps up to 1,000,000:
322,171 (22) 322,193 (20) 322,213 (16) 322,229 (8) 322,237 (6) 322,243 (4) 322,247 (2) 322,249
752,207 (44) 752,251 (12) 752,263 (10) 752,273 (8) 752,281 (6) 752,287 (4) 752,291 (2) 752,293

This task uses Extensible Prime Generator (F#)

Delphi

Works with: Delphi version 6.0

The code makes heavy use of "Sieve" object developed for other Rosetta Code tasks. The Sieve object is described here: Extensible_prime_generator#Delphi

procedure LongestAscendDescend(Memo: TMemo);
{Find the longest Ascending and Descending sequences of primes}
var I: integer;
var Sieve: TPrimeSieve;

	procedure FindLongestSequence(Ascend: boolean);
	{Find the longest sequence - Ascend controls}
	{ whether it ascending or descending}
	var I,J,Count,BestCount,BestStart: integer;
        var S: string;

		function Compare(N1,N2: integer; Ascend: boolean): boolean;
		{Compare for ascending or descending}
		begin
		if Ascend then Result:=N1>N2
		else Result:=N1<N2;
		end;

	begin
	BestStart:=0; BestCount:=0;
	{Check all the primes in the sieve}
	for I:=2 to High(Sieve.Primes)-1 do
		begin
		J:=I + 1;
		Count:= 1;
		{Count all the elements in the sequence}
		while (j<=High(Sieve.Primes)) and
		      Compare(Sieve.Primes[J]-Sieve.Primes[J-1],Sieve.Primes[J-1]-Sieve.Primes[j-2],Ascend) do
			begin
			Inc(Count);
			Inc(J);
			end;
		{Save the info if it is the best so far}
		if Count > BestCount then
			begin
			BestStart:=I-1;
			BestCount:= Count;
			end;
		end;
	Memo.Lines.Add('Count = '+IntToStr(BestCount+1));
	{Display the sequence}
	S:='[';
	for I:=BestStart to BestStart+BestCount do
		begin
		S:=S+IntToStr(Sieve.Primes[I]);
		if I<(BestStart+BestCount) then S:=S+' ('+IntToStr(Sieve.Primes[I+1]-Sieve.Primes[I])+') ';
		end;
	S:=S+']';
	Memo.Lines.Add(S);
	end;



begin
Sieve:=TPrimeSieve.Create;
try
{Generate all primes below 1 million}
Sieve.Intialize(1000000);

Memo.Lines.Add('The longest sequence of ascending primes');
FindLongestSequence(True);
Memo.Lines.Add('The longest sequence of ascending primes');
FindLongestSequence(False);
finally Sieve.Free; end;
end;
Output:
The longest sequence of ascending primes
Count = 8
[128981 (2) 128983 (4) 128987 (6) 128993 (8) 129001 (10) 129011 (12) 129023 (14) 129037]
The longest sequence of ascending primes
Count = 8
[322171 (22) 322193 (20) 322213 (16) 322229 (8) 322237 (6) 322243 (4) 322247 (2) 322249]
Elapsed Time: 18.386 ms.

EasyLang

fastfunc nextprim num .
   repeat
      i = 2
      while i <= sqrt num and num mod i <> 0
         i += 1
      .
      until num mod i <> 0
      num += 1
   .
   return num
.
proc getseq dir . maxprim maxcnt .
   maxcnt = 0
   pri = 2
   repeat
      prev = pri
      pri = nextprim (pri + 1)
      until pri > 1000000
      d0 = d
      d = (pri - prev) * dir
      if d > d0
         cnt += 1
      else
         if cnt > maxcnt
            maxcnt = cnt
            maxprim = prim0
         .
         prim0 = prev
         cnt = 1
      .
   .
.
proc outseq pri max . .
   write pri & " "
   for i to max
      pri = nextprim (pri + 1)
      write pri & " "
   .
   print ""
.
getseq 1 pri max
outseq pri max
getseq -1 pri max
outseq pri max

F#

// Longest ascending and decending sequences of difference between consecutive primes: Nigel Galloway. April 5th., 2021
let fN g fW=primes32()|>Seq.takeWhile((>)g)|>Seq.pairwise|>Seq.fold(fun(n,i,g)el->let w=fW el in match w>n with true->(w,el::i,g) |_->(w,[el],if List.length i>List.length g then i else g))(0,[],[])
for i in [1;2;6;12;18;100] do let _,_,g=fN(i*1000000)(fun(n,g)->g-n) in printfn "Longest ascending upto %d000000->%d:" i (g.Length+1); g|>List.rev|>List.iter(fun(n,g)->printf "%d (%d) %d " n (g-n) g); printfn ""
                              let _,_,g=fN(i*1000000)(fun(n,g)->n-g) in printfn "Longest decending upto %d000000->%d:" i (g.Length+1); g|>List.rev|>List.iter(fun(n,g)->printf "%d (%d) %d " n (g-n) g); printfn ""
Output:
Longest ascending upto 1000000->8:
128981 (2) 128983 128983 (4) 128987 128987 (6) 128993 128993 (8) 129001 129001 (10) 129011 129011 (12) 129023 129023 (14) 129037
Longest decending upto 1000000->8:
322171 (22) 322193 322193 (20) 322213 322213 (16) 322229 322229 (8) 322237 322237 (6) 322243 322243 (4) 322247 322247 (2) 322249
Longest ascending upto 2000000->9:
1319407 (4) 1319411 1319411 (8) 1319419 1319419 (10) 1319429 1319429 (14) 1319443 1319443 (16) 1319459 1319459 (18) 1319477 1319477 (32) 1319509 1319509 (34) 1319543
Longest decending upto 2000000->8:
322171 (22) 322193 322193 (20) 322213 322213 (16) 322229 322229 (8) 322237 322237 (6) 322243 322243 (4) 322247 322247 (2) 322249
Longest ascending upto 6000000->9:
1319407 (4) 1319411 1319411 (8) 1319419 1319419 (10) 1319429 1319429 (14) 1319443 1319443 (16) 1319459 1319459 (18) 1319477 1319477 (32) 1319509 1319509 (34) 1319543
Longest decending upto 6000000->9:
5051309 (32) 5051341 5051341 (28) 5051369 5051369 (14) 5051383 5051383 (10) 5051393 5051393 (8) 5051401 5051401 (6) 5051407 5051407 (4) 5051411 5051411 (2) 5051413
Longest ascending upto 12000000->9:
1319407 (4) 1319411 1319411 (8) 1319419 1319419 (10) 1319429 1319429 (14) 1319443 1319443 (16) 1319459 1319459 (18) 1319477 1319477 (32) 1319509 1319509 (34) 1319543
Longest decending upto 12000000->10:
11938793 (60) 11938853 11938853 (38) 11938891 11938891 (28) 11938919 11938919 (14) 11938933 11938933 (10) 11938943 11938943 (8) 11938951 11938951 (6) 11938957 11938957 (4) 11938961 11938961 (2) 11938963
Longest ascending upto 18000000->10:
17797517 (2) 17797519 17797519 (4) 17797523 17797523 (8) 17797531 17797531 (10) 17797541 17797541 (12) 17797553 17797553 (20) 17797573 17797573 (28) 17797601 17797601 (42) 17797643 17797643 (50) 17797693
Longest decending upto 18000000->10:
11938793 (60) 11938853 11938853 (38) 11938891 11938891 (28) 11938919 11938919 (14) 11938933 11938933 (10) 11938943 11938943 (8) 11938951 11938951 (6) 11938957 11938957 (4) 11938961 11938961 (2) 11938963
Longest ascending upto 100000000->11:
94097537 (2) 94097539 94097539 (4) 94097543 94097543 (8) 94097551 94097551 (10) 94097561 94097561 (12) 94097573 94097573 (14) 94097587 94097587 (16) 94097603 94097603 (18) 94097621 94097621 (30) 94097651 94097651 (32) 94097683
Longest decending upto 100000000->10:
11938793 (60) 11938853 11938853 (38) 11938891 11938891 (28) 11938919 11938919 (14) 11938933 11938933 (10) 11938943 11938943 (8) 11938951 11938951 (6) 11938957 11938957 (4) 11938961 11938961 (2) 11938963
Real: 00:00:04.708

Factor

Works with: Factor version 0.99 2021-02-05
USING: arrays assocs formatting grouping io kernel literals math
math.primes math.statistics sequences sequences.extras
tools.memory.private ;

<< CONSTANT: limit 1,000,000 >>

CONSTANT: primes $[ limit primes-upto ]

: run ( n quot -- seq quot )
    [ primes ] [ <clumps> ] [ ] tri*
    '[ differences _ monotonic? ] ; inline

: max-run ( quot -- n )
    1 swap '[ 1 + dup _ run find drop ] loop 1 - ; inline

: runs ( quot -- seq )
    [ max-run ] keep run filter ; inline

: .run ( seq -- )
    dup differences [ [ commas ] map ] bi@
    [ "(" ")" surround ] map 2array round-robin " " join print ;

: .runs ( quot -- )
    [ runs ] keep [ < ] = "rising" "falling" ? limit commas
    "Largest run(s) of %s gaps between primes less than %s:\n"
    printf [ .run ] each ; inline

[ < ] [ > ] [ .runs nl ] bi@
Output:
Largest run(s) of rising gaps between primes less than 1,000,000:
128,981 (2) 128,983 (4) 128,987 (6) 128,993 (8) 129,001 (10) 129,011 (12) 129,023 (14) 129,037
402,581 (2) 402,583 (4) 402,587 (6) 402,593 (8) 402,601 (12) 402,613 (18) 402,631 (60) 402,691
665,111 (2) 665,113 (4) 665,117 (6) 665,123 (8) 665,131 (10) 665,141 (12) 665,153 (24) 665,177

Largest run(s) of falling gaps between primes less than 1,000,000:
322,171 (22) 322,193 (20) 322,213 (16) 322,229 (8) 322,237 (6) 322,243 (4) 322,247 (2) 322,249
752,207 (44) 752,251 (12) 752,263 (10) 752,273 (8) 752,281 (6) 752,287 (4) 752,291 (2) 752,293

FutureBasic

This code builds the Sieve of Eratosthenes using a single bit for each odd number, saving both time and memory. Using FB's XREF arrays, once we have built a list, we can save it by simply swapping pointers.

include "NSLog.incl"
_max  = 1000000
_size = _max/16
uint8 oddIntBits(_size)
xref  list(20) as int : list  = fn calloc(20, 4)
xref  up(20)   as int : up    = fn calloc(20, 4)
xref  dn(20)   as int : dn    = fn calloc(20, 4)

clear local fn ascDecDifs
  int num, np, count=1, umax=3, dmax=3, dif1, dif2, dir, n(2)
  ///////Build Sieve of Eratosthenes////////////////////////////////////
  for num = 3 to _max step 2
    if oddIntBits(num >> 4) & bit((num & 15) >> 1) then continue
    
    np = num * num
    while np < _max
      oddIntBits(np >> 4) |= bit((np & 15) >> 1)
      np += num << 1
    wend
    /////Build lists of ascending and descending prime gaps//////////////
    dif2  = num - n(2)
    if sgn(dif2 - dif1) == dir
      if count then count++ : list(count) = num : exit if   //add to list
      //Start list
      blockmove(@n(0), @list(0), 12)   //Copy primes to list
      list(3) = num : count = 3
    else
      if count > umax then if dir ==  1 then umax = count : swap list, up
      if count > dmax then if dir == -1 then dmax = count : swap list, dn
      count = 0
    end if
    dir = sgn(dif2 - dif1)
    dif1 = dif2
    blockmove(@n(1), @n(0), 8)         //Shift 1 lower in array
    n(2) = num
  next
  ///////Show results///////////////////////////////////////////////////
  CFStringRef s = fn   stringwithformat(@"\n  Ascending:  %d", up(0))
  for num = 1 to umax
    s = fn stringwithformat(@"%@, %d", s, up(num))
  next
  s = fn   stringwithformat(@"%@\n\n  Descending: %d", s, dn(0))
  for num  = 1 to dmax
    s = fn stringwithformat(@"%@, %d", s, dn(num))
  next
  nsLogSetTitle(@"Consecutive primes with ascending or descending differences")
  nslog( s )
end fn

CFTimeInterval t : t = fn CACurrentMediaTime
fn ascDecDifs
nslog(@"\n  %.3f ms.",1000*(fn CACurrentMediaTime - t))

handleevents
Output:

  Ascending:  128981, 128983, 128987, 128993, 129001, 129011, 129023, 129037

  Descending: 322171, 322193, 322213, 322229, 322237, 322243, 322247, 322249

  2.677 ms.

Go

Translation of: Wren
package main

import (
    "fmt"
    "rcu"
)

const LIMIT = 999999

var primes = rcu.Primes(LIMIT)

func longestSeq(dir string) {
    pd := 0
    longSeqs := [][]int{{2}}
    currSeq := []int{2}
    for i := 1; i < len(primes); i++ {
        d := primes[i] - primes[i-1]
        if (dir == "ascending" && d <= pd) || (dir == "descending" && d >= pd) {
            if len(currSeq) > len(longSeqs[0]) {
                longSeqs = [][]int{currSeq}
            } else if len(currSeq) == len(longSeqs[0]) {
                longSeqs = append(longSeqs, currSeq)
            }
            currSeq = []int{primes[i-1], primes[i]}
        } else {
            currSeq = append(currSeq, primes[i])
        }
        pd = d
    }
    if len(currSeq) > len(longSeqs[0]) {
        longSeqs = [][]int{currSeq}
    } else if len(currSeq) == len(longSeqs[0]) {
        longSeqs = append(longSeqs, currSeq)
    }
    fmt.Println("Longest run(s) of primes with", dir, "differences is", len(longSeqs[0]), ":")
    for _, ls := range longSeqs {
        var diffs []int
        for i := 1; i < len(ls); i++ {
            diffs = append(diffs, ls[i]-ls[i-1])
        }
        for i := 0; i < len(ls)-1; i++ {
            fmt.Print(ls[i], " (", diffs[i], ") ")
        }
        fmt.Println(ls[len(ls)-1])
    }
    fmt.Println()
}

func main() {
    fmt.Println("For primes < 1 million:\n")
    for _, dir := range []string{"ascending", "descending"} {
        longestSeq(dir)
    }
}
Output:
For primes < 1 million:

Longest run(s) of primes with ascending differences is 8 :
128981 (2) 128983 (4) 128987 (6) 128993 (8) 129001 (10) 129011 (12) 129023 (14) 129037
402581 (2) 402583 (4) 402587 (6) 402593 (8) 402601 (12) 402613 (18) 402631 (60) 402691
665111 (2) 665113 (4) 665117 (6) 665123 (8) 665131 (10) 665141 (12) 665153 (24) 665177

Longest run(s) of primes with descending differences is 8 :
322171 (22) 322193 (20) 322213 (16) 322229 (8) 322237 (6) 322243 (4) 322247 (2) 322249
752207 (44) 752251 (12) 752263 (10) 752273 (8) 752281 (6) 752287 (4) 752291 (2) 752293

Haskell

import Data.Numbers.Primes (primes)

-- generates consecutive subsequences defined by given equivalence relation
consecutives equiv = filter ((> 1) . length) . go []
  where
    go r [] = [r]
    go [] (h : t) = go [h] t
    go (y : ys) (h : t)
      | y `equiv` h = go (h : y : ys) t
      | otherwise = (y : ys) : go [h] t

-- finds maximal values in a list and returns the first one
maximumBy g (h : t) = foldr f h t
  where
    f r x = if g r < g x then x else r

-- the task implementation
task ord n = reverse $ p + s : p : (fst <$> rest)
  where
    (p, s) : rest =
      maximumBy length $
        consecutives (\(_, a) (_, b) -> a `ord` b) $
          differences $
            takeWhile (< n) primes
    differences l = zip l $ zipWith (-) (tail l) l
Ξ»> reverse <$> consecutives (<) [1,0,1,2,3,4,3,2,3,4,5,6,7,6,5,4,3,4,5]
[[0,1,2,3,4],[2,3,4,5,6,7],[3,4,5]]

Ξ»> task (<) 1000000
[128981,128983,128987,128993,129001,129011,129023,129037]

Ξ»> task (>) 1000000
[322171,322193,322213,322229,322237,322243,322247,322249]

J

   ;{.(\: #@>) tris <@~.@,;._1~ <:/ 2 -/\ |: tris=: 3 ]\ p: i. p:inv 1e6
128981 128983 128987 128993 129001 129011 129023 129037
   ;{.(\: #@>) tris <@~.@,;._1~ >:/ 2 -/\ |: tris=: 3 ]\ p: i. p:inv 1e6
322171 322193 322213 322229 322237 322243 322247 322249


Java

import java.util.ArrayList;
import java.util.BitSet;
import java.util.List;

public final class ConsecutivePrimes {

	public static void main(String[] aArgs) {
		final int limit = 1_000_000;
		List<Integer> primes = listPrimeNumbers(limit);
		
		List<Integer> asc = new ArrayList<Integer>();
		List<Integer> desc = new ArrayList<Integer>();
		List<List<Integer>> maxAsc = new ArrayList<List<Integer>>();
		List<List<Integer>> maxDesc = new ArrayList<List<Integer>>();
	    int maxAscSize = 0;
	    int maxDescSize = 0;
	    
	    for ( int prime : primes ) {
	   	    final int ascSize = asc.size();
	        if ( ascSize > 1 && prime - asc.get(ascSize - 1) <= asc.get(ascSize - 1) - asc.get(ascSize - 2) ) {
	            asc = new ArrayList<Integer>(asc.subList(ascSize - 1, asc.size()));
	        }	        
	        asc.add(prime);
	        
	        if ( asc.size() >= maxAscSize ) {
	            if ( asc.size() > maxAscSize ) {
	                maxAscSize = asc.size();
	                maxAsc.clear();
	            }
	            maxAsc.add( new ArrayList<Integer>(asc) );
	        }
	        
	        final int descSize = desc.size();
	        if ( descSize > 1 && prime - desc.get(descSize - 1) >= desc.get(descSize - 1) - desc.get(descSize - 2) ) {
	            desc = new ArrayList<Integer>(desc.subList(descSize - 1, desc.size()));
	        }
	        desc.add(prime);
	        
	        if ( desc.size() >= maxDescSize ) {
	            if ( desc.size() > maxDescSize ) {
	                maxDescSize = desc.size();
	                maxDesc.clear();
	            }
	            maxDesc.add( new ArrayList<Integer>(desc) );
	        }
	    }
	    
	    System.out.println("Longest run(s) of ascending prime gaps up to " + limit + ":");
	    for ( List<Integer> list : maxAsc ) {
	        displayResult(list);
	    }
	    System.out.println();
	    
	    System.out.println("Longest run(s) of descending prime gaps up to " + limit + ":");
	    for( List<Integer> list : maxDesc ) {
	        displayResult(list);
	    }
	}
	
	private static List<Integer> listPrimeNumbers(int aLimit) {
		BitSet sieve = new BitSet(aLimit + 1);
		sieve.set(2, aLimit + 1);
		for ( int i = 2; i <= Math.sqrt(aLimit); i = sieve.nextSetBit(i + 1) ) {
			for ( int j = i * i; j <= aLimit; j = j + i ) {
				sieve.clear(j);
			}
		}
		
		List<Integer> result = new ArrayList<Integer>(sieve.cardinality());
		for ( int i = 2; i >= 0; i = sieve.nextSetBit(i + 1) ) {
			result.add(i);
		}
		return result;
	}
	
	private static void displayResult(List<Integer> aList) {
		for ( int i = 0; i < aList.size(); i++ ) {
	        if ( i > 0 ) {
	            System.out.print(" (" + ( aList.get(i) - aList.get(i - 1) ) + ") ");
	        }
	        System.out.print(aList.get(i));
	    }
	    System.out.println();
	}

}
Output:
Longest run(s) of ascending prime gaps up to 1000000:
128981 (2) 128983 (4) 128987 (6) 128993 (8) 129001 (10) 129011 (12) 129023 (14) 129037
402581 (2) 402583 (4) 402587 (6) 402593 (8) 402601 (12) 402613 (18) 402631 (60) 402691
665111 (2) 665113 (4) 665117 (6) 665123 (8) 665131 (10) 665141 (12) 665153 (24) 665177

Longest run(s) of descending prime gaps up to 1000000:
322171 (22) 322193 (20) 322213 (16) 322229 (8) 322237 (6) 322243 (4) 322247 (2) 322249
752207 (44) 752251 (12) 752263 (10) 752273 (8) 752281 (6) 752287 (4) 752291 (2) 752293

jq

Adapted from Wren

Works with: jq

Works with gojq, the Go implementation of jq

This entry assumes the availability of `is_prime`, for which a suitable definition can be found at ErdΕ‘s-primes#jq.

Preliminaries

# For streams of strings or of arrays or of numbers:
def add(s): reduce s as $x (null; .+$x);

# Primes less than . // infinite
def primes:
  (. // infinite) as $n
  | if $n < 3 then empty
    else 2, (range(3; $n) | select(is_prime))
    end;

The Task

# Input: null or limit+1
# Output: informative strings
def longestSequences:
  [primes] as $primes
  | def longestSeq(direction):
      { pd: 0,
        longSeqs: [[2]],
        currSeq: [2] }
      | reduce range( 1; $primes|length) as $i (.;
          ($primes[$i] - $primes[$i-1]) as $d
          | if (direction == "ascending" and $d <= .pd) or (direction == "descending" and $d >= .pd)
            then if (.currSeq|length) > (.longSeqs[0]|length)
                 then .longSeqs = [.currSeq]
                 else if (.currSeq|length) == (.longSeqs[0]|length)
                      then .longSeqs += [.currSeq]
                      else .
                      end
                 end
             | .currSeq = [$primes[$i-1], $primes[$i]]
             else .currSeq += [$primes[$i]]
             end
          | .pd = $d
      )
      | if (.currSeq|length) > (.longSeqs[0]|length) 
        then .longSeqs = [.currSeq]
        else if (.currSeq|length) == (.longSeqs[0]|length)
             then .longSeqs = .longSeqs + [.currSeq]
             else .
             end
        end          

      | "Longest run(s) of primes with \(direction) differences is \(.longSeqs[0]|length):",
        (.longSeqs[] as $ls
         | add( range(1; $ls|length) | [$ls[.] - $ls[.-1]]) as $diffs
         | add( range(0; $ls|length-1) | "\($ls[.]) (\($diffs[.])) ") + "\($ls[-1])" );

      longestSeq("ascending"), "", longestSeq("descending");
 
"For primes < 1 million:",
 ( 1E6 | longestSequences )
Output:
For primes < 1 million:
Longest run(s) of primes with ascending differences is 8:
128981 (2) 128983 (4) 128987 (6) 128993 (8) 129001 (10) 129011 (12) 129023 (14) 129037
402581 (2) 402583 (4) 402587 (6) 402593 (8) 402601 (12) 402613 (18) 402631 (60) 402691
665111 (2) 665113 (4) 665117 (6) 665123 (8) 665131 (10) 665141 (12) 665153 (24) 665177

Longest run(s) of primes with descending differences is 8:
322171 (22) 322193 (20) 322213 (16) 322229 (8) 322237 (6) 322243 (4) 322247 (2) 322249
752207 (44) 752251 (12) 752263 (10) 752273 (8) 752281 (6) 752287 (4) 752291 (2) 752293

Julia

using Primes

function primediffseqs(maxnum = 1_000_000)
    mprimes = primes(maxnum)
    diffs = map(p -> mprimes[p[1] + 1] - p[2], enumerate(@view mprimes[begin:end-1]))
    incstart, decstart, bestinclength, bestdeclength = 1, 1, 0, 0
    for i in 1:length(diffs)-1
        foundinc, founddec = false, false
        for j in i+1:length(diffs)
            if !foundinc && diffs[j] <= diffs[j - 1]
                if (runlength = j - i) > bestinclength
                    bestinclength, incstart = runlength, i
                end
                foundinc = true
            end
            if !founddec && diffs[j] >= diffs[j - 1]
                if (runlength = j - i) > bestdeclength
                    bestdeclength, decstart = runlength, i
                end
                founddec = true
            end
            foundinc && founddec && break
        end
    end
    println("Ascending: ", mprimes[incstart:incstart+bestinclength], " Diffs: ", diffs[incstart:incstart+bestinclength-1])
    println("Descending: ", mprimes[decstart:decstart+bestdeclength], " Diffs: ", diffs[decstart:decstart+bestdeclength-1])
end

primediffseqs()
Output:
Ascending: [128981, 128983, 128987, 128993, 129001, 129011, 129023, 129037] Diffs: [2, 4, 6, 8, 10, 12, 14] 
Descending: [322171, 322193, 322213, 322229, 322237, 322243, 322247, 322249] Diffs: [22, 20, 16, 8, 6, 4, 2]

Lua

This task uses primegen from: Extensible_prime_generator#Lua

function findcps(primelist, fcmp)
  local currlist = {primelist[1]}
  local longlist, prevdiff = currlist, 0
  for i = 2, #primelist do
    local diff = primelist[i] - primelist[i-1]
    if fcmp(diff, prevdiff) then
      currlist[#currlist+1] = primelist[i]
      if #currlist > #longlist then
        longlist = currlist
      end
    else
      currlist = {primelist[i-1], primelist[i]}
    end
    prevdiff = diff
  end
  return longlist
end

primegen:generate(nil, 1000000)
cplist = findcps(primegen.primelist, function(a,b) return a>b end)
print("ASC  ("..#cplist.."):  ["..table.concat(cplist, " ").."]")
cplist = findcps(primegen.primelist, function(a,b) return a<b end)
print("DESC ("..#cplist.."):  ["..table.concat(cplist, " ").."]")
Output:
ASC  (8):  [128981 128983 128987 128993 129001 129011 129023 129037]
DESC (8):  [322171 322193 322213 322229 322237 322243 322247 322249]

Mathematica /Wolfram Language

prime = Prime[Range[PrimePi[10^6]]];
s = Split[Differences[prime], Less];
max = Max[Length /@ s];
diffs = Select[s, Length/*EqualTo[max]];
seqs = SequencePosition[Flatten[s], #, 1][[1]] & /@ diffs;
Take[prime, # + {0, 1}] & /@ seqs

s = Split[Differences[prime], Greater];
max = Max[Length /@ s];
diffs = Select[s, Length/*EqualTo[max]];
seqs = SequencePosition[Flatten[s], #, 1][[1]] & /@ diffs;
Take[prime, # + {0, 1}] & /@ seqs
Output:
128981	128983	128987	128993	129001	129011	129023	129037
402581	402583	402587	402593	402601	402613	402631	402691
665111	665113	665117	665123	665131	665141	665153	665177

322171	322193	322213	322229	322237	322243	322247	322249
752207	752251	752263	752273	752281	752287	752291	752293

Nim

import math, strformat, sugar

const N = 1_000_000

####################################################################################################
# Erathostenes sieve.

var composite: array[2..N, bool]    # Initialized to false i.e. prime.

for n in 2..int(sqrt(float(N))):
  if not composite[n]:
    for k in countup(n * n, N, n):
      composite[k] = true

let primes = collect(newSeq):
               for n in 2..N:
                 if not composite[n]: n


####################################################################################################
# Longest sequences.

type Order {.pure.} = enum Ascending, Descending

proc longestSeq(order: Order): seq[int] =
  ## Return the longest sequence for the given order.

  let ascending = order == Ascending
  var
    currseq: seq[int]
    prevPrime = 2
    diff = if ascending: 0 else: N

  for prime in primes:
    let nextDiff = prime - prevPrime
    if nextDiff != diff and nextDiff > diff == ascending:
      currseq.add prime
    else:
      if currseq.len > result.len:
        result = move(currseq)
      currseq = @[prevPrime, prime]
    diff = nextDiff
    prevPrime = prime

  if currseq.len > result.len:
    result = move(currseq)


proc `$`(list: seq[int]): string =
  ## Return the representation of a list of primes with interleaved differences.
  var prevPrime: int
  for i, prime in list:
    if i != 0: result.add &" ({prime - prevPrime}) "
    result.addInt prime
    prevPrime = prime

echo "For primes < 1000000.\n"
echo "First longest sequence of consecutive primes with ascending differences:"
echo longestSeq(Ascending)
echo()
echo "First longest sequence of consecutive primes with descending differences:"
echo longestSeq(Descending)
Output:
For primes < 1000000.

First longest sequence of consecutive primes with ascending differences:
128981 (2) 128983 (4) 128987 (6) 128993 (8) 129001 (10) 129011 (12) 129023 (14) 129037

First longest sequence of consecutive primes with descending differences:
322171 (22) 322193 (20) 322213 (16) 322229 (8) 322237 (6) 322243 (4) 322247 (2) 322249

Pari/GP

Code is pretty reasonable, runs in ~70 ms at 1,000,000. Running under PARI (starting from gp2c translation) could take advantage of the diff structure of the prime table directly for small cases and avoid substantial overhead, gaining at least a factor of 2 in performance.

showPrecPrimes(p, n)=
{
  my(v=vector(n));
  v[n]=p;
  forstep(i=n-1,1,-1,
    v[i]=precprime(v[i+1]-1)
  );
  for(i=1,n, print1(v[i]" "));
}
list(lim)=
{
  my(p=3,asc,dec,ar,dr,arAt=3,drAt=3,last=2);
  forprime(q=5,lim,
    my(g=q-p);
    if(g<last,
      asc=0;
      if(desc++>dr,
        dr=desc;
        drAt=q
      )
    ,g>last,
      desc=0;
      if(asc++>ar,
        ar=asc;
        arAt=q
      )
    ,
      asc=desc=0
    );
    p=q;
    last=g
  );
  print("Descending differences:");
  showPrecPrimes(drAt, dr+2);
  print("\nAscending differences:");
  showPrecPrimes(arAt, ar+2);
}
list(10^6)
Output:
Descending differences:
322171 322193 322213 322229 322237 322243 322247 322249
Ascending differences:
128981 128983 128987 128993 129001 129011 129023 129037

Perl

Translation of: Raku
Library: ntheory
use strict;
use warnings;
use feature 'say';
use ntheory 'primes';
use List::AllUtils <indexes max>;

my $limit  = 1000000;
my @primes = @{primes( $limit )};

sub runs {
    my($op) = @_;
    my @diff = my $diff = my $run = 1;
    push @diff, map {
        my $next = $primes[$_] - $primes[$_ - 1];
        if ($op eq '>') { if ($next > $diff) { ++$run } else { $run = 1 } }
        else            { if ($next < $diff) { ++$run } else { $run = 1 } }
        $diff = $next;
        $run
    } 1 .. $#primes;

    my @prime_run;
    my $max = max @diff;
    for my $r ( indexes { $_ == $max } @diff ) {
        push @prime_run, join ' ', map { $primes[$r - $_] } reverse 0..$max
    }
    @prime_run
}

say   "Longest run(s) of ascending prime gaps up to $limit:\n"  . join "\n", runs('>');
say "\nLongest run(s) of descending prime gaps up to $limit:\n" . join "\n", runs('<');
Output:
Longest run(s) of ascending prime gaps up to 1000000:
128981 128983 128987 128993 129001 129011 129023 129037
402581 402583 402587 402593 402601 402613 402631 402691
665111 665113 665117 665123 665131 665141 665153 665177

Longest run(s) of descending prime gaps up to 1000000:
322171 322193 322213 322229 322237 322243 322247 322249
752207 752251 752263 752273 752281 752287 752291 752293

Phix

integer pn = 1, -- prime numb
        lp = 2, -- last prime
        lg = 0, -- last gap
        pd = 0  -- prev d
sequence cr = {0,0},    -- curr run [a,d]
         mr = {{0},{0}} -- max runs  ""
while true do
    pn += 1
    integer p = get_prime(pn), gap = p-lp,
            d = compare(gap,lg)
    if p>1e6 then exit end if
    if d then
        integer i = (3-d)/2
        cr[i] = iff(d=pd?cr[i]:lp!=2)+1
        if cr[i]>mr[i][1] then mr[i] = {cr[i],pn} end if
    end if
    {pd,lp,lg} = {d,p,gap}
end while

for run=1 to 2 do
    integer {l,e} = mr[run]
    sequence p = apply(tagset(e,e-l),get_prime),
             g = sq_sub(p[2..$],p[1..$-1])
    printf(1,"longest %s run length %d: %v gaps: %v\n",
       {{"ascending","descending"}[run],length(p),p,g})
end for
Output:
longest ascending run length 8: {128981,128983,128987,128993,129001,129011,129023,129037} gaps: {2,4,6,8,10,12,14}
longest descending run length 8: {322171,322193,322213,322229,322237,322243,322247,322249} gaps: {22,20,16,8,6,4,2}

Python

from sympy import sieve

primelist = list(sieve.primerange(2,1000000))

listlen = len(primelist)

# ascending

pindex = 1
old_diff = -1
curr_list=[primelist[0]]
longest_list=[]

while pindex < listlen:

    diff = primelist[pindex] - primelist[pindex-1]
    if diff > old_diff:
        curr_list.append(primelist[pindex])
        if len(curr_list) > len(longest_list):
            longest_list = curr_list
    else:
        curr_list = [primelist[pindex-1],primelist[pindex]]
        
    old_diff = diff
    pindex += 1
    
print(longest_list)

# descending

pindex = 1
old_diff = -1
curr_list=[primelist[0]]
longest_list=[]

while pindex < listlen:

    diff = primelist[pindex] - primelist[pindex-1]
    if diff < old_diff:
        curr_list.append(primelist[pindex])
        if len(curr_list) > len(longest_list):
            longest_list = curr_list
    else:
        curr_list = [primelist[pindex-1],primelist[pindex]]
        
    old_diff = diff
    pindex += 1
    
print(longest_list)
Output:
[128981, 128983, 128987, 128993, 129001, 129011, 129023, 129037]
[322171, 322193, 322213, 322229, 322237, 322243, 322247, 322249]

Raku

use Math::Primesieve;
use Lingua::EN::Numbers;

my $sieve = Math::Primesieve.new;

my $limit = 1000000;

my @primes = $sieve.primes($limit);

sub runs (&op) {
    my $diff = 1;
    my $run = 1;

    my @diff = flat 1, (1..^@primes).map: {
        my $next = @primes[$_] - @primes[$_ - 1];
        if &op($next, $diff) { ++$run } else { $run = 1 }
        $diff = $next;
        $run;
    }

    my $max = max @diff;
    my @runs = @diff.grep: * == $max, :k;

    @runs.map( {
        my @run = (0..$max).reverse.map: -> $r { @primes[$_ - $r] }
        flat roundrobin(@runΒ».&comma, @run.rotor(2 => -1).map({[R-] $_})Β».fmt('(%d)'));
    } ).join: "\n"
}

say "Longest run(s) of ascending prime gaps up to {comma $limit}:\n" ~ runs(&infix:Β«>Β»);

say "\nLongest run(s) of descending prime gaps up to {comma $limit}:\n" ~ runs(&infix:Β«<Β»);
Output:
Longest run(s) of ascending prime gaps up to 1,000,000:
128,981 (2) 128,983 (4) 128,987 (6) 128,993 (8) 129,001 (10) 129,011 (12) 129,023 (14) 129,037
402,581 (2) 402,583 (4) 402,587 (6) 402,593 (8) 402,601 (12) 402,613 (18) 402,631 (60) 402,691
665,111 (2) 665,113 (4) 665,117 (6) 665,123 (8) 665,131 (10) 665,141 (12) 665,153 (24) 665,177

Longest run(s) of descending prime gaps up to 1,000,000:
322,171 (22) 322,193 (20) 322,213 (16) 322,229 (8) 322,237 (6) 322,243 (4) 322,247 (2) 322,249
752,207 (44) 752,251 (12) 752,263 (10) 752,273 (8) 752,281 (6) 752,287 (4) 752,291 (2) 752,293

REXX

Version 1

/*REXX program finds the longest sequence of consecutive primes where the differences   */
/*──────────── between the primes are strictly ascending;  also for strictly descending.*/
parse arg hi cols .                              /*obtain optional argument from the CL.*/
if   hi=='' |   hi==","  then   hi= 1000000      /* "      "         "   "   "     "    */
if cols=='' | cols==","  then cols=      10      /* "      "         "   "   "     "    */
call genP                                        /*build array of semaphores for primes.*/
w= 10                                            /*width of a number in any column.     */
call fRun 1;  call show 1                        /*find runs with ascending prime diffs.*/
call fRun 0;  call show 0                        /*  "    "    " descending   "     "   */
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
commas: parse arg ?;  do jc=length(?)-3  to 1  by -3; ?=insert(',', ?, jc); end;  return ?
/*──────────────────────────────────────────────────────────────────────────────────────*/
fRun: parse arg ?;    mxrun=0;     seq.=         /*max run length;  lists of prime runs.*/
                                                 /*search for consecutive primes  <  HI.*/
        do j=2  for #-2;   cp= @.j;   jn= j+1    /*CP: current prime;  JN:  next j      */
        diff= @.jn - cp                          /*get difference between last 2 primes.*/
        cnt= 1;                       run=       /*initialize the   CNT   and   RUN.    */
               do k= jn+1  to #-2;    km= k-1    /*look for more primes in this run.    */
               if ?  then if @.k-@.km<=diff  then leave  /*Diff. too small? Stop looking*/
                                             else nop
                     else if @.k-@.km>=diff  then leave  /*  "    "  large?   "     "   */
               run= run  @.k;         cnt= cnt+1 /*append a prime to the run; bump count*/
               diff= @.k - @.km                  /*calculate difference for next prime. */
               end   /*k*/
        if cnt<=mxrun  then iterate              /*This run too short? Then keep looking*/
        mxrun= max(mxrun, cnt)                   /*define a new maximum run (seq) length*/
        seq.mxrun= cp  @.jn  run                 /*full populate the sequence (RUN).    */
        end   /*j*/;                   return
/*──────────────────────────────────────────────────────────────────────────────────────*/
genP: @.1=2; @.2=3; @.3=5; @.4=7; @.5=11; @.6=13; @.7=17; @.8=19    /*define low primes.*/
                           #=8;   sq.#= @.# ** 2 /*number of primes so far; prime sqiare*/
                                                 /* [↓]  generate more  primes  ≀  high.*/
        do j=@.#+2  by 2  to hi;  parse var j '' -1 _    /*find odd primes from here on.*/
        if     _==5  then iterate;  if j// 3==0  then iterate   /*J Γ·  5?    J Γ· by  3? */
        if j// 7==0  then iterate;  if j//11==0  then iterate   /*" "  7?    " "  " 11? */
        if j//13==0  then iterate;  if j//17==0  then iterate   /*" " 13?    " " "  17? */
               do k=8  while sq.k<=j             /* [↓]  divide by the known odd primes.*/
               if j // @.k == 0  then iterate j  /*Is  J Γ· X?  Then not prime.     ___  */
               end   /*k*/                       /* [↑]  only process numbers  ≀  √ J   */
        #= #+1;             @.#= j;    sq.#= j*j /*bump # of Ps; assign next P; P square*/
        end          /*j*/;            return
/*──────────────────────────────────────────────────────────────────────────────────────*/
show: parse arg ?;  if ?  then AorD= 'ascending'     /*choose which literal for display.*/
                          else AorD= 'descending'    /*   "     "      "     "     "    */
      title= ' longest run of consecutive primes whose differences between primes are'  ,
                              'strictly'         AorD         "and  < "         commas(hi)
      say;    say;    say
      if cols>0  then say ' index β”‚'center(title,   1 + cols*(w+1)     )
      if cols>0  then say '───────┼'center(""   ,   1 + cols*(w+1), '─')
      found= 0;                idx= 1            /*initialize # of consecutive primes.  */
      $=                                         /*a list of consecutive primes (so far)*/
         do o=1  for words(seq.mxrun)            /*show all consecutive primes in seq.  */
         c= commas( word(seq.mxrun, o) )         /*obtain the next prime in the sequence*/
         found= found + 1                        /*bump the number of consecutive primes*/
         if cols<=0            then iterate      /*build the list  (to be shown later)? */
         $= $  right(c, max(w, length(c) ) )     /*add a nice prime ──► list, allow big#*/
         if found//cols\==0    then iterate      /*have we populated a line of output?  */
         say center(idx, 7)'β”‚'  substr($, 2)     /*display what we have so far  (cols). */
         idx= idx + cols;              $=        /*bump the  index  count for the output*/
         end   /*o*/
      if $\==''  then say center(idx, 7)"β”‚"  substr($, 2)   /*maybe show residual output*/
      if cols>0  then say '───────┴'center(""   ,   1 + cols*(w+1), '─')
      say;            say commas(Cprimes)  ' was the'title;        return
output   when using the default inputs:
 index β”‚  longest run of consecutive primes whose differences between primes are strictly ascending and  <  1,000,000
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   β”‚    128,981    128,983    128,987    128,993    129,001    129,011    129,023    129,037
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────

8  was the longest run of consecutive primes whose differences between primes are strictly ascending and  <  1,000,000



 index β”‚  longest run of consecutive primes whose differences between primes are strictly descending and  <  1,000,000
───────┼───────────────────────────────────────────────────────────────────────────────────────────────────────────────
   1   β”‚    322,171    322,193    322,213    322,229    322,237    322,243    322,247    322,249
───────┴───────────────────────────────────────────────────────────────────────────────────────────────────────────────

8  was the longest run of consecutive primes whose differences between primes are strictly descending and  <  1,000,000
8.729 seconds

Version 2

Libraries: How to use
Library: Sequences
Library: Functions

Version 1 is rather complicated and hard to read. In Version 2 I show how simple it can be, splitting the work in small procedures. Procedure Primes() is in library Sequences, using a sieve. I pay less attention to a fancy output layout, unlike Version 1. Saves a lot of coding and better corresponds with the other entries. And it is much, MUCH faster!

call Time('r')
parse version version; say version
glob. = ''; numeric digits 10; t = 1e7
say 'Consecutive primes - Using REXX libraries'
say
call Primes t
call Deltas
call Sequence 'A',t
call Sequence 'D',t
say Format(Time('e'),,3) 'seconds'
exit

Deltas:
/* Calculate deltas between pairs of primes */
procedure expose prim. delta.
delta. = 0
do i = 2 to prim.0
   h = i-1; delta.i = prim.prime.i-prim.prime.h
end
return

Sequence:
/* Find and show longest strict sequence */
procedure expose delta. glob. prim.
arg ad,t
p = prim.0+1
if ad = 'A' then
   delta.p = 0
else
   delta.p = n
d = 0; f = 1; l = 1; len = 0
do i = 2 to p
   if (ad = 'A' & delta.i > d),
   |  (ad = 'D' & delta.i < d) then do
      d = delta.i; l = i
   end
   else do
      a = l-f+1
      if a > len then do
         first = f; last = l; len = a
      end
      f = i-1; l = i; d = delta.i
   end
end
if ad = 'A' then
   a = 'ascending'
else
   a = 'descending'
say 'For primes <' t', the longest' a 'sequence was' len 'consecutive primes.'
say 'These are (with differences):'
do i = first to last-1
   j = i+1
   call charout ,prim.prime.i '('delta.j') '
end
call charout ,prim.prime.last
say; say
return

include Sequences
include Functions

Task:

REXX-Regina_3.9.6(MT) 5.00 29 Apr 2024
Consecutive primes - Using REXX libraries

For primes < 1E6, the longest ascending sequence was 8 consecutive primes.
The first one (with differences) is:
128981 (2) 128983 (4) 128987 (6) 128993 (8) 129001 (10) 129011 (12) 129023 (14) 129037

For primes < 1E6, the longest descending sequence was 8 consecutive primes.
The first one (with differences) is:
322171 (22) 322193 (20) 322213 (16) 322229 (8) 322237 (6) 322243 (4) 322247 (2) 322249

0.723 seconds

Some higher sequences:

REXX-Regina_3.9.6(MT) 5.00 29 Apr 2024
Consecutive primes - Using REXX libraries

For primes < 10E6, the longest ascending sequence was 9 consecutive primes.
The first one (with differences) is:
1319407 (4) 1319411 (8) 1319419 (10) 1319429 (14) 1319443 (16) 1319459 (18) 1319477 (32) 1319509 (34) 1319543

For primes < 10E6, the longest descending sequence was 9 consecutive primes.
The first one (with differences) is:
5051309 (32) 5051341 (28) 5051369 (14) 5051383 (10) 5051393 (8) 5051401 (6) 5051407 (4) 5051411 (2) 5051413

8.179 seconds

REXX-Regina_3.9.6(MT) 5.00 29 Apr 2024
Consecutive primes - Using REXX libraries

For primes < 100E6, the longest ascending sequence was 11 consecutive primes.
The first one (with differences) is:
94097537 (2) 94097539 (4) 94097543 (8) 94097551 (10) 94097561 (12) 94097573 (14) 94097587 (16) 94097603 (18) 94097621 (30) 94097651 (32) 94097683

For primes < 100E6, the longest descending sequence was 10 consecutive primes.
The first one (with differences) is:
11938793 (60) 11938853 (38) 11938891 (28) 11938919 (14) 11938933 (10) 11938943 (8) 11938951 (6) 11938957 (4) 11938961 (2) 11938963

205.584 seconds

Ruby

require "prime"
limit = 1_000_000

puts "First found longest run of ascending prime gaps up to #{limit}:"
p  Prime.each(limit).each_cons(2).chunk_while{|(i1,i2), (j1,j2)| j1-i1 < j2-i2 }.max_by(&:size).flatten.uniq
puts  "\nFirst found longest run of descending prime gaps up to #{limit}:"
p  Prime.each(limit).each_cons(2).chunk_while{|(i1,i2), (j1,j2)| j1-i1 > j2-i2 }.max_by(&:size).flatten.uniq
Output:
First found longest run of ascending prime gaps up to 1000000:
[128981, 128983, 128987, 128993, 129001, 129011, 129023, 129037]

First found longest run of descending prime gaps up to 1000000:
[322171, 322193, 322213, 322229, 322237, 322243, 322247, 322249]

Rust

// [dependencies]
// primal = "0.3"

fn print_diffs(vec: &[usize]) {
    for i in 0..vec.len() {
        if i > 0 {
            print!(" ({}) ", vec[i] - vec[i - 1]);
        }
        print!("{}", vec[i]);
    }
    println!();
}

fn main() {
    let limit = 1000000;
    let mut asc = Vec::new();
    let mut desc = Vec::new();
    let mut max_asc = Vec::new();
    let mut max_desc = Vec::new();
    let mut max_asc_len = 0;
    let mut max_desc_len = 0;
    for p in primal::Sieve::new(limit)
        .primes_from(2)
        .take_while(|x| *x < limit)
    {
        let alen = asc.len();
        if alen > 1 && p - asc[alen - 1] <= asc[alen - 1] - asc[alen - 2] {
            asc = asc.split_off(alen - 1);
        }
        asc.push(p);
        if asc.len() >= max_asc_len {
            if asc.len() > max_asc_len {
                max_asc_len = asc.len();
                max_asc.clear();
            }
            max_asc.push(asc.clone());
        }
        let dlen = desc.len();
        if dlen > 1 && p - desc[dlen - 1] >= desc[dlen - 1] - desc[dlen - 2] {
            desc = desc.split_off(dlen - 1);
        }
        desc.push(p);
        if desc.len() >= max_desc_len {
            if desc.len() > max_desc_len {
                max_desc_len = desc.len();
                max_desc.clear();
            }
            max_desc.push(desc.clone());
        }
    }
    println!("Longest run(s) of ascending prime gaps up to {}:", limit);
    for v in max_asc {
        print_diffs(&v);
    }
    println!("\nLongest run(s) of descending prime gaps up to {}:", limit);
    for v in max_desc {
        print_diffs(&v);
    }
}
Output:
Longest run(s) of ascending prime gaps up to 1000000:
128981 (2) 128983 (4) 128987 (6) 128993 (8) 129001 (10) 129011 (12) 129023 (14) 129037
402581 (2) 402583 (4) 402587 (6) 402593 (8) 402601 (12) 402613 (18) 402631 (60) 402691
665111 (2) 665113 (4) 665117 (6) 665123 (8) 665131 (10) 665141 (12) 665153 (24) 665177

Longest run(s) of descending prime gaps up to 1000000:
322171 (22) 322193 (20) 322213 (16) 322229 (8) 322237 (6) 322243 (4) 322247 (2) 322249
752207 (44) 752251 (12) 752263 (10) 752273 (8) 752281 (6) 752287 (4) 752291 (2) 752293

Sidef

Translation of: Raku
func runs(f, arr) {

    var run = 0
    var diff = 0
    var diffs = []

    arr.each_cons(2, {|p1,p2|
        var curr_diff = (p2 - p1)
        f(curr_diff, diff) ? ++run : (run = 1)
        diff = curr_diff
        diffs << run
    })

    var max  = diffs.max
    var runs = []

    diffs.indices_by { _ == max }.each {|i|
        runs << arr.slice(i - max + 1, i + 1)
    }

    return runs
}

var limit = 1e6
var primes = limit.primes

say "Longest run(s) of ascending prime gaps up to #{limit.commify}:"
say runs({|a,b| a > b }, primes).join("\n")

say "\nLongest run(s) of descending prime gaps up to #{limit.commify}:"
say runs({|a,b| a < b }, primes).join("\n")
Output:
Longest run(s) of ascending prime gaps up to 1,000,000:
[128981, 128983, 128987, 128993, 129001, 129011, 129023, 129037]
[402581, 402583, 402587, 402593, 402601, 402613, 402631, 402691]
[665111, 665113, 665117, 665123, 665131, 665141, 665153, 665177]

Longest run(s) of descending prime gaps up to 1,000,000:
[322171, 322193, 322213, 322229, 322237, 322243, 322247, 322249]
[752207, 752251, 752263, 752273, 752281, 752287, 752291, 752293]

Wren

Library: Wren-math
import "./math" for Int

var LIMIT = 999999
var primes = Int.primeSieve(LIMIT)

var longestSeq = Fn.new { |dir|
    var pd = 0
    var longSeqs = [[2]]
    var currSeq = [2]
    for (i in 1...primes.count) {
        var d = primes[i] - primes[i-1]
        if ((dir == "ascending" && d <= pd) || (dir == "descending" && d >= pd)) {
            if (currSeq.count > longSeqs[0].count) {
                longSeqs = [currSeq]
            } else if (currSeq.count == longSeqs[0].count) longSeqs.add(currSeq)
            currSeq = [primes[i-1], primes[i]]
        } else {
            currSeq.add(primes[i])
        }
        pd = d
    }
    if (currSeq.count > longSeqs[0].count) {
        longSeqs = [currSeq]
    } else if (currSeq.count == longSeqs[0].count) longSeqs.add(currSeq)
    System.print("Longest run(s) of primes with %(dir) differences is %(longSeqs[0].count):")
    for (ls in longSeqs) {
        var diffs = []
        for (i in 1...ls.count) diffs.add(ls[i] - ls[i-1])
        for (i in 0...ls.count-1) System.write("%(ls[i]) (%(diffs[i])) ")
        System.print(ls[-1])
    }
    System.print()
}

System.print("For primes < 1 million:\n")
for (dir in ["ascending", "descending"]) longestSeq.call(dir)
Output:
For primes < 1 million:

Longest run(s) of primes with ascending differences is 8:
128981 (2) 128983 (4) 128987 (6) 128993 (8) 129001 (10) 129011 (12) 129023 (14) 129037
402581 (2) 402583 (4) 402587 (6) 402593 (8) 402601 (12) 402613 (18) 402631 (60) 402691
665111 (2) 665113 (4) 665117 (6) 665123 (8) 665131 (10) 665141 (12) 665153 (24) 665177

Longest run(s) of primes with descending differences is 8:
322171 (22) 322193 (20) 322213 (16) 322229 (8) 322237 (6) 322243 (4) 322247 (2) 322249
752207 (44) 752251 (12) 752263 (10) 752273 (8) 752281 (6) 752287 (4) 752291 (2) 752293

XPL0

func IsPrime(N);        \Return 'true' if N > 2 is a prime number
int  N, I;
[if (N&1) = 0 \even number\ then return false;
for I:= 3 to sqrt(N) do
    [if rem(N/I) = 0 then return false;
    I:= I+1;
    ];
return true;
];

proc ShowSeq(Dir, Str); \Show longest sequence of distances between primes
int  Dir, Str;
int  Count, MaxCount, N, P, P0, D, D0, I, AP(1000), MaxAP(1000);
[Count:= 0;  MaxCount:= 0;
P0:= 2;  D0:= 0;                \preceding prime and distance
AP(Count):= P0;  Count:= Count+1;
for N:= 3 to 1_000_000-1 do
    if IsPrime(N) then
        [P:= N;                 \got a prime number
        D:= P - P0;             \distance from preceding prime
        if D*Dir > D0*Dir then
            [AP(Count):= P;  Count:= Count+1;
            if Count > MaxCount then        \save best sequence
                [MaxCount:= Count;
                for I:= 0 to MaxCount-1 do
                    MaxAP(I):= AP(I);
                ];
            ]
        else
            [Count:= 0;     \restart sequence
            AP(Count):= P0;  Count:= Count+1; \possible beginning
            AP(Count):= P;   Count:= Count+1;
            ];
        P0:= P;  D0:= D;
        ];
Text(0, "Longest sequence of ");  Text(0, Str);
Text(0, " distances between primes: ");  IntOut(0, MaxCount);  CrLf(0);
for I:= 0 to MaxCount-2 do
    [IntOut(0, MaxAP(I));
    Text(0, " (");
    IntOut(0, MaxAP(I+1) - MaxAP(I));
    Text(0, ") ");
    ];
IntOut(0, MaxAP(I));  CrLf(0);
];

[ShowSeq(+1,  "ascending");     \main
 ShowSeq(-1, "descending");
]
Output:
Longest sequence of ascending distances between primes: 8
128981 (2) 128983 (4) 128987 (6) 128993 (8) 129001 (10) 129011 (12) 129023 (14) 129037
Longest sequence of descending distances between primes: 8
322171 (22) 322193 (20) 322213 (16) 322229 (8) 322237 (6) 322243 (4) 322247 (2) 322249
Cookies help us deliver our services. By using our services, you agree to our use of cookies.