Sum of two adjacent numbers are primes


Show on this page the first 20 prime sums of two consecutive integers.

Sum of two adjacent numbers are primes is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Task
Extra credit

Show the ten millionth such prime sum.

Action!

;;; Find numbers n such that n + n+1 is prime
;;; Library: Action! Sieve of Eratosthenes
INCLUDE "H6:SIEVE.ACT"

PROC Main()
  DEFINE MAX_PRIME = "255"

  BYTE ARRAY primes(MAX_PRIME)
  CARD n, n1, count
 
  Sieve(primes,MAX_PRIME)

  count = 0;
  n1 = 1
  WHILE count < 20 DO
    n = n1
    n1 ==+ 1
    IF primes( n + n1 ) THEN
      count ==+ 1
      PrintF( "%2U: %2U + %2U = %2U%E", count, n, n1, n + n1 )
    FI
  OD

RETURN
Output:
 1:  1 +  2 =  3
 2:  2 +  3 =  5
 3:  3 +  4 =  7
 4:  5 +  6 = 11
 5:  6 +  7 = 13
 6:  8 +  9 = 17
 7:  9 + 10 = 19
 8: 11 + 12 = 23
 9: 14 + 15 = 29
10: 15 + 16 = 31
11: 18 + 19 = 37
12: 20 + 21 = 41
13: 21 + 22 = 43
14: 23 + 24 = 47
15: 26 + 27 = 53
16: 29 + 30 = 59
17: 30 + 31 = 61
18: 33 + 34 = 67
19: 35 + 36 = 71
20: 36 + 37 = 73

ALGOL 68

Using Pete Lomax's observation that all odd primes are n + n+1 for some n - see #Phix

BEGIN # find the first 20 primes which are n + ( n + 1 ) for some n  #
    PR read "primes.incl.a68" PR           # include prime utilities #
    []BOOL prime = PRIMESIEVE 200;         # should be enough primes #
    INT p count := 0;
    FOR p FROM 3 BY 2 WHILE p count < 20 DO
        IF prime[ p ] THEN
            INT n  = p OVER 2;
            INT n1 = n + 1;
            p count +:= 1;
            print( ( whole( n, -2 ), " + ", whole( n1, -2 ), " = ", whole( p, -3 ), newline ) )
        FI
    OD
END
Output:
 1 +  2 =   3
 2 +  3 =   5
 3 +  4 =   7
 5 +  6 =  11
 6 +  7 =  13
 8 +  9 =  17
 9 + 10 =  19
11 + 12 =  23
14 + 15 =  29
15 + 16 =  31
18 + 19 =  37
20 + 21 =  41
21 + 22 =  43
23 + 24 =  47
26 + 27 =  53
29 + 30 =  59
30 + 31 =  61
33 + 34 =  67
35 + 36 =  71
36 + 37 =  73

ALGOL W

begin % find numbers n such that n + n+1 is prime                            %

    % sets s to a sieve of primes, using the sieve of Eratosthenes           %
    procedure sieve( logical array s ( * ); integer value n ) ;
    begin
        % start with everything flagged as prime                             % 
        for i := 1 until n do s( i ) := true;
        % sieve out the non-primes                                           %
        s( 1 ) := false;
        for i := 2 until truncate( sqrt( n ) )
        do begin
            if s( i )
            then begin
                for p := i * i step i until n do s( p ) := false
            end if_s_i
        end for_i ;
    end sieve ;

    integer sieveMax;
    sieveMax := 200;
    begin
        logical array prime ( 1 :: sieveMax );
        integer count, n, n1;
        i_w := 2; % set output integer field width                           %
        s_w := 1; % and output separator width                               %

        % find and display the numbers                                       %
        sieve( prime, sieveMax );
        count := 0;
        n1    := 1;
        while count < 20 do begin
            n  := n1;
            n1 := n1 + 1;
            if prime( n + n1 ) then begin
                count := count + 1;
                write( count, ": ", n, " + ", n1, " = ", n + n1 )
            end if_prime__n_plus_n1
        end while_count_lt_20
    end

end.
Output:
 1 :  1  +  2  =  3
 2 :  2  +  3  =  5
 3 :  3  +  4  =  7
 4 :  5  +  6  = 11
 5 :  6  +  7  = 13
 6 :  8  +  9  = 17
 7 :  9  + 10  = 19
 8 : 11  + 12  = 23
 9 : 14  + 15  = 29
10 : 15  + 16  = 31
11 : 18  + 19  = 37
12 : 20  + 21  = 41
13 : 21  + 22  = 43
14 : 23  + 24  = 47
15 : 26  + 27  = 53
16 : 29  + 30  = 59
17 : 30  + 31  = 61
18 : 33  + 34  = 67
19 : 35  + 36  = 71
20 : 36  + 37  = 73

Arturo

loop.with:'i 
    select.first:20 1..∞ 'x -> prime? x + x+1
    'x -> print [
            (pad to :string i+1 2)++":"
            (pad to :string x 2) "+" (pad.right to :string x+1 2) "=" x + x+1
        ]
Output:
 1:  1 + 2  = 3 
 2:  2 + 3  = 5 
 3:  3 + 4  = 7 
 4:  5 + 6  = 11 
 5:  6 + 7  = 13 
 6:  8 + 9  = 17 
 7:  9 + 10 = 19 
 8: 11 + 12 = 23 
 9: 14 + 15 = 29 
10: 15 + 16 = 31 
11: 18 + 19 = 37 
12: 20 + 21 = 41 
13: 21 + 22 = 43 
14: 23 + 24 = 47 
15: 26 + 27 = 53 
16: 29 + 30 = 59 
17: 30 + 31 = 61 
18: 33 + 34 = 67 
19: 35 + 36 = 71 
20: 36 + 37 = 73

AWK

# syntax: GAWK -f SUM_OF_TWO_ADJACENT_NUMBERS_ARE_PRIMES.AWK
BEGIN {
    n = 1
    stop = 20
    printf("The first %d pairs of numbers whose sum is prime:\n",stop)
    while (count < stop) {
      if (is_prime(2*n + 1)) {
        printf("%2d + %2d = %2d\n",n,n+1,2*n+1)
        count++
      }
      n++
    }
    exit(0)
}
function is_prime(n,  d) {
    d = 5
    if (n < 2) { return(0) }
    if (n % 2 == 0) { return(n == 2) }
    if (n % 3 == 0) { return(n == 3) }
    while (d*d <= n) {
      if (n % d == 0) { return(0) }
      d += 2
      if (n % d == 0) { return(0) }
      d += 4
    }
    return(1)
}
Output:
The first 20 pairs of numbers whose sum is prime:
 1 +  2 =  3
 2 +  3 =  5
 3 +  4 =  7
 5 +  6 = 11
 6 +  7 = 13
 8 +  9 = 17
 9 + 10 = 19
11 + 12 = 23
14 + 15 = 29
15 + 16 = 31
18 + 19 = 37
20 + 21 = 41
21 + 22 = 43
23 + 24 = 47
26 + 27 = 53
29 + 30 = 59
30 + 31 = 61
33 + 34 = 67
35 + 36 = 71
36 + 37 = 73

BASIC

BASIC256

Translation of: FreeBASIC
function isPrime(v)
	if v < 2 then return False
	if v mod 2 = 0 then return v = 2
	if v mod 3 = 0 then return v = 3
	d = 5
	while d * d <= v
		if v mod d = 0 then return False else d += 2
	end while
	return True
end function

n = 0
num = 0

print "The first 20 pairs of numbers whose sum is prime:"
while True
	n += 1
	suma = 2*n+1
	if isPrime(suma) then
		num += 1
		if num < 21 then
			print n; " + "; (n+1); " = "; suma
		else
			exit while
		end if
	end if
end while
end
Output:
Igual que la entrada de FreeBASIC.

FreeBASIC

Function isPrime(Byval ValorEval As Integer) As Boolean
    If ValorEval <= 1 Then Return False
    For i As Integer = 2 To Int(Sqr(ValorEval))
        If ValorEval Mod i = 0 Then Return False
    Next i
    Return True
End Function

Dim As Integer n = 0, num = 0, suma
print "The first 20 pairs of numbers whose sum is prime:"
Do
    n += 1
    suma = 2*n+1
    If isPrime(suma) Then
        num += 1
        If num < 21 Then
            Print using "## + ## = ##"; n; (n+1); suma
        Else
            Exit Do
        End If
    End If
Loop
Sleep
Output:
The first 20 pairs of numbers whose sum is prime:
 1 +  2 =  3
 2 +  3 =  5
 3 +  4 =  7
 5 +  6 = 11
 6 +  7 = 13
 8 +  9 = 17
 9 + 10 = 19
11 + 12 = 23
14 + 15 = 29
15 + 16 = 31
18 + 19 = 37
20 + 21 = 41
21 + 22 = 43
23 + 24 = 47
26 + 27 = 53
29 + 30 = 59
30 + 31 = 61
33 + 34 = 67
35 + 36 = 71
36 + 37 = 73

PureBasic

Procedure isPrime(v.i)
  If     v <= 1    : ProcedureReturn #False
  ElseIf v < 4     : ProcedureReturn #True
  ElseIf v % 2 = 0 : ProcedureReturn #False
  ElseIf v < 9     : ProcedureReturn #True
  ElseIf v % 3 = 0 : ProcedureReturn #False
  Else
    Protected r = Round(Sqr(v), #PB_Round_Down)
    Protected f = 5
    While f <= r
      If v % f = 0 Or v % (f + 2) = 0
        ProcedureReturn #False
      EndIf
      f + 6
    Wend
  EndIf
  ProcedureReturn #True
EndProcedure

If OpenConsole()
	Define n.i = 0, num.i = 0, suma.i
	
	PrintN("The first 20 pairs of numbers whose sum is prime:")
	Repeat
		n + 1
		suma = 2*n+1
		If isPrime(suma)
			num + 1
			If num < 21
			  PrintN(Str(n) + " + " + Str(n+1) + " = " + Str(suma))
			Else
			  Break
			EndIf
		EndIf
	ForEver
	CloseConsole()
EndIf
Output:
Igual que la entrada de FreeBASIC.

QBasic

Works with: QBasic version 1.1
Works with: QuickBasic version 4.5
Translation of: FreeBASIC
FUNCTION isPrime (ValorEval)
    IF ValorEval <= 1 THEN isPrime = 0
    FOR i = 2 TO INT(SQR(ValorEval))
        IF ValorEval MOD i = 0 THEN isPrime = 0
    NEXT i
    isPrime = 1
END FUNCTION

n = 0
num = 0
PRINT "The first 20 pairs of numbers whose sum is prime:"
DO
    n = n + 1
    suma = 2 * n + 1
    IF isPrime(suma) THEN
        num = num + 1
        IF num < 21 THEN
            PRINT USING "## + ## = ##"; n; (n + 1); suma
        ELSE
            EXIT DO
        END IF
    END IF
LOOP
END
Output:
Igual que la entrada de FreeBASIC.

True BASIC

FUNCTION isPrime (ValorEval)
    IF ValorEval <= 1 THEN LET isPrime = 0
    FOR i = 2 TO INT(SQR(ValorEval))
        IF MOD(ValorEval, i) = 0 THEN LET isPrime = 0
    NEXT i
    LET isPrime = 1
END FUNCTION

LET n = 0
LET num = 0
PRINT "The first 20 pairs of numbers whose sum is prime:"
DO
   LET n = n + 1
   LET suma = 2 * n + 1
   IF isPrime(suma) = 1 THEN
      LET num = num + 1
      IF num < 21 THEN
         PRINT USING "##": n;
         PRINT " + ";
         PRINT USING "##": n+1;
         PRINT " = ";
         PRINT USING "##": suma
      ELSE
         EXIT DO
      END IF
   END IF
LOOP
END
Output:
Igual que la entrada de FreeBASIC.

Yabasic

sub isPrime(v)
    if v < 2 then return False : fi
    if mod(v, 2) = 0 then return v = 2 : fi
    if mod(v, 3) = 0 then return v = 3 : fi
    d = 5
    while d * d <= v
        if mod(v, d) = 0 then return False else d = d + 2 : fi
    wend
    return True
end sub

n = 0
num = 0
print "The first 20 pairs of numbers whose sum is prime:"
do
    n = n + 1
    suma = 2*n+1
    if isPrime(suma) then
        num = num + 1
        if num < 21 then
            print n using "##", " + ", (n+1) using "##", " = ", suma using "##"
        else
            break
        end if
    end if
loop
end
Output:
Igual que la entrada de FreeBASIC.


C

Translation of: Go
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define TRUE 1
#define FALSE 0

typedef int bool;

void primeSieve(int *c, int limit, bool processEven, bool primesOnly) {
    int i, ix, p, p2;
    limit++;
    c[0] = TRUE;
    c[1] = TRUE;
    if (processEven) {
        for (i = 4; i < limit; i +=2) c[i] = TRUE;
    }
    p = 3;
    while (TRUE) {
        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;
        }
    }
    if (primesOnly) {
        /* move the actual primes to the front of the array */
        c[0] = 2;
        for (i = 3, ix = 1; i < limit; i += 2) {
            if (!c[i]) c[ix++] = i;
        }
    }
}

int main() {
    int i, p, hp, n = 10000000;
    int limit = (int)(log(n) * (double)n * 1.2);  /* should be more than enough */
    int *primes = (int *)calloc(limit, sizeof(int));
    primeSieve(primes, limit-1, FALSE, TRUE);
    printf("The first 20 pairs of natural numbers whose sum is prime are:\n");
    for (i = 1; i <= 20; ++i) {
        p = primes[i];
        hp = p / 2;
        printf("%2d + %2d = %2d\n", hp, hp+1, p);
    }
    printf("\nThe 10 millionth such pair is:\n");
    p = primes[n];
    hp = p / 2;
    printf("%2d + %2d = %2d\n", hp, hp+1, p);
    free(primes);
    return 0;
}
Output:
The first 20 pairs of natural numbers whose sum is prime are:
 1 +  2 =  3
 2 +  3 =  5
 3 +  4 =  7
 5 +  6 = 11
 6 +  7 = 13
 8 +  9 = 17
 9 + 10 = 19
11 + 12 = 23
14 + 15 = 29
15 + 16 = 31
18 + 19 = 37
20 + 21 = 41
21 + 22 = 43
23 + 24 = 47
26 + 27 = 53
29 + 30 = 59
30 + 31 = 61
33 + 34 = 67
35 + 36 = 71
36 + 37 = 73

The 10 millionth such pair is:
89712345 + 89712346 = 179424691

Delphi

Works with: Delphi version 6.0


procedure AdjacentPrimeSums(Memo: TMemo);
var I,Sum,Cnt: integer;
var S: string;
begin
Cnt:=0;
S:='';
for I:=0 to High(I) do
 if IsPrime(I+I+1) then
	begin
	Inc(Cnt);
	Memo.Lines.Add(Format('%3d %3d+%3d=%4d',[Cnt,I,I+1,I+I+1]));
	if Cnt>=20 then break
	end;
end;
Output:
 1:  1 +  2 =  3
 2:  2 +  3 =  5
 3:  3 +  4 =  7
 4:  5 +  6 = 11
 5:  6 +  7 = 13
 6:  8 +  9 = 17
 7:  9 + 10 = 19
 8: 11 + 12 = 23
 9: 14 + 15 = 29
10: 15 + 16 = 31
11: 18 + 19 = 37
12: 20 + 21 = 41
13: 21 + 22 = 43
14: 23 + 24 = 47
15: 26 + 27 = 53
16: 29 + 30 = 59
17: 30 + 31 = 61
18: 33 + 34 = 67
19: 35 + 36 = 71
20: 36 + 37 = 73

Elapsed Time: 25.093 ms.


EasyLang

Translation of: BASIC256
fastfunc isprim num .
   i = 2
   while i <= sqrt num
      if num mod i = 0
         return 0
      .
      i += 1
   .
   return 1
.
print "The first 20 pairs of numbers whose sum is prime:"
repeat
   n += 1
   sum = 2 * n + 1
   if isprim sum = 1
      print n & " + " & n + 1 & " = " & sum
      cnt += 1
   .
   until cnt = 20
.

F#

This task uses Extensible Prime Generator (F#)

// 2n+1 is prime. Nigel Galloway: Januuary 22nd., 2022
primes32()|>Seq.skip 1|>Seq.take 20|>Seq.map(fun n->n/2)|>Seq.iteri(fun n g->printfn "%2d: %2d + %2d=%d" (n+1) g (g+1) (g+g+1))
Output:
 1:  1 +  2=3
 2:  2 +  3=5
 3:  3 +  4=7
 4:  5 +  6=11
 5:  6 +  7=13
 6:  8 +  9=17
 7:  9 + 10=19
 8: 11 + 12=23
 9: 14 + 15=29
10: 15 + 16=31
11: 18 + 19=37
12: 20 + 21=41
13: 21 + 22=43
14: 23 + 24=47
15: 26 + 27=53
16: 29 + 30=59
17: 30 + 31=61
18: 33 + 34=67
19: 35 + 36=71
20: 36 + 37=73

Factor

Works with: Factor version 0.99 2021-06-02
USING: arrays formatting kernel lists lists.lazy math
math.primes.lists sequences ;

20 lprimes cdr [ 2/ dup 1 + 2array ] lmap-lazy ltake
[ dup sum suffix "%d + %d = %d\n" vprintf ] leach
Output:
1 + 2 = 3
2 + 3 = 5
3 + 4 = 7
5 + 6 = 11
6 + 7 = 13
8 + 9 = 17
9 + 10 = 19
11 + 12 = 23
14 + 15 = 29
15 + 16 = 31
18 + 19 = 37
20 + 21 = 41
21 + 22 = 43
23 + 24 = 47
26 + 27 = 53
29 + 30 = 59
30 + 31 = 61
33 + 34 = 67
35 + 36 = 71
36 + 37 = 73

Go

Library: Go-rcu
package main

import (
    "fmt"
    "math"
    "rcu"
)

func main() {
    limit := int(math.Log(1e7) * 1e7 * 1.2) // should be more than enough
    primes := rcu.Primes(limit)
    fmt.Println("The first 20 pairs of natural numbers whose sum is prime are:")
    for i := 1; i <= 20; i++ {
        p := primes[i]
        hp := p / 2
        fmt.Printf("%2d + %2d = %2d\n", hp, hp+1, p)
    }
    fmt.Println("\nThe 10 millionth such pair is:")
    p := primes[1e7]
    hp := p / 2
    fmt.Printf("%2d + %2d = %2d\n", hp, hp+1, p)
}
Output:
The first 20 pairs of natural numbers whose sum is prime are:
 1 +  2 =  3
 2 +  3 =  5
 3 +  4 =  7
 5 +  6 = 11
 6 +  7 = 13
 8 +  9 = 17
 9 + 10 = 19
11 + 12 = 23
14 + 15 = 29
15 + 16 = 31
18 + 19 = 37
20 + 21 = 41
21 + 22 = 43
23 + 24 = 47
26 + 27 = 53
29 + 30 = 59
30 + 31 = 61
33 + 34 = 67
35 + 36 = 71
36 + 37 = 73

The 10 millionth such pair is:
89712345 + 89712346 = 179424691

Haskell

import Data.Numbers.Primes

primeSumsOfConsecutiveNumbers :: Integral a => [(a, (a, a))]
primeSumsOfConsecutiveNumbers =
  let go a b = [(n, (a, b)) | let n = a + b, isPrime n]
   in concat $ zipWith go [1 ..] [2 ..]

main :: IO ()
main = mapM_ print $ take 20 primeSumsOfConsecutiveNumbers
Output:
(3,(1,2))
(5,(2,3))
(7,(3,4))
(11,(5,6))
(13,(6,7))
(17,(8,9))
(19,(9,10))
(23,(11,12))
(29,(14,15))
(31,(15,16))
(37,(18,19))
(41,(20,21))
(43,(21,22))
(47,(23,24))
(53,(26,27))
(59,(29,30))
(61,(30,31))
(67,(33,34))
(71,(35,36))
(73,(36,37))

J

Here, we generate the first 20 odd primes, divide by 2, drop the fractional part and add 0 and 1 to that value. Then we format that pair of numbers with their sum and with decorations indicating the relevant arithmetic:

   (+/,&":'=',{.,&":'+',&":{:)"#. 0 1+/~<.-: p:1+i.20
3=1+2   
5=2+3   
7=3+4   
11=5+6  
13=6+7  
17=8+9  
19=9+10 
23=11+12
29=14+15
31=15+16
37=18+19
41=20+21
43=21+22
47=23+24
53=26+27
59=29+30
61=30+31
67=33+34
71=35+36
73=36+37

jq

Works with: jq

Works with gojq, the Go implementation of jq

This entry uses a memory-less approach to computing `is_prime`, and so a naive approach to computing the first 20 numbers satisfying the condition is appropriate.

def is_prime:
  . as $n
  | if ($n < 2)         then false
    elif ($n % 2 == 0)  then $n == 2
    elif ($n % 3 == 0)  then $n == 3
    else 5
    | until( . <= 0;
        if .*. > $n then -1
	elif ($n % . == 0) then 0
        else . + 2
        |  if ($n % . == 0) then 0
           else . + 4
           end
        end)
    | . == -1
    end;

def naive:
  limit(20;
    range(0; infinite) as $i
    | (2*$i + 1) as $q
    | select($q | is_prime)
    | "\($i) + \($i + 1) = \($q)" );

naive
Output:
1 + 2 = 3
2 + 3 = 5
3 + 4 = 7
5 + 6 = 11
6 + 7 = 13
8 + 9 = 17
9 + 10 = 19
11 + 12 = 23
14 + 15 = 29
15 + 16 = 31
18 + 19 = 37
20 + 21 = 41
21 + 22 = 43
23 + 24 = 47
26 + 27 = 53
29 + 30 = 59
30 + 31 = 61
33 + 34 = 67
35 + 36 = 71
36 + 37 = 73

Julia

using Lazy
using Primes

seq = @>> Lazy.range() filter(n -> isprime(2n + 1))
for n in take(20, seq)
    println("$n + $(n + 1) = $(n + n + 1)")
end

let
    i, cnt = 0, 0
    while cnt < 10_000_000
        i += 1
        if isprime(2i + 1)
            cnt += 1
        end
    end
    println("Ten millionth: $i + $(i + 1) = $(i + i + 1)")
end
Output:
1 + 2 = 3
2 + 3 = 5
3 + 4 = 7
5 + 6 = 11
6 + 7 = 13
8 + 9 = 17
9 + 10 = 19
11 + 12 = 23
14 + 15 = 29
15 + 16 = 31
18 + 19 = 37
20 + 21 = 41
21 + 22 = 43
23 + 24 = 47
26 + 27 = 53
29 + 30 = 59
30 + 31 = 61
33 + 34 = 67
35 + 36 = 71
36 + 37 = 73
Ten millionth: 89712345 + 89712346 = 179424691

Mathematica/Wolfram Language

Column[Row[{Floor[#/2], " + ", Ceiling[#/2], " = ", #}] & /@ Prime[1 + Range[20]]]
Row[{Floor[#/2], " + ", Ceiling[#/2], " = ", #}] &[Prime[10^7 + 1]]
Output:
1 + 2 = 3
2 + 3 = 5
3 + 4 = 7
5 + 6 = 11
6 + 7 = 13
8 + 9 = 17
9 + 10 = 19
11 + 12 = 23
14 + 15 = 29
15 + 16 = 31
18 + 19 = 37
20 + 21 = 41
21 + 22 = 43
23 + 24 = 47
26 + 27 = 53
29 + 30 = 59
30 + 31 = 61
33 + 34 = 67
35 + 36 = 71
36 + 37 = 73
89712345 + 89712346 = 179424691

Nim

import std/[bitops, math, strformat, strutils]

type Sieve = object
  data: seq[byte]

func `[]`(sieve: Sieve; idx: Positive): bool =
  ## Return value of element at index "idx".
  let idx = idx shr 1
  let iByte = idx shr 3
  let iBit = idx and 7
  result = sieve.data[iByte].testBit(iBit)

func `[]=`(sieve: var Sieve; idx: Positive; val: bool) =
  ## Set value of element at index "idx".
  let idx = idx shr 1
  let iByte = idx shr 3
  let iBit = idx and 7
  if val: sieve.data[iByte].setBit(iBit)
  else: sieve.data[iByte].clearBit(iBit)

func newSieve(lim: Positive): Sieve =
  ## Create a sieve with given maximal index.
  result.data = newSeq[byte]((lim + 16) shr 4)

func initPrimes(lim: Positive): seq[Natural] =
  ## Initialize the list of primes from 3 to "lim".
  var composite = newSieve(lim)
  composite[1] = true
  for n in countup(3, sqrt(lim.toFloat).int, 2):
    if not composite[n]:
      for k in countup(n * n, lim, 2 * n):
        composite[k] = true
  for n in countup(3, lim, 2):
    if not composite[n]:
      result.add n

let primes = initPrimes(200_000_000)

echo "The first 20 pairs of natural numbers whose sum is prime are:"
var count = 0
for p in primes:
  inc count
  if count <= 20:
    echo &"{(p-1) div 2} + {(p+1) div 2} = {p}"
    if count == 20: echo()
  elif count == 10_000_000:
    echo "The 10 millionth such pair is:"
    echo &"{(p-1) div 2} + {(p+1) div 2} = {p}"
    break
Output:
The first 20 pairs of natural numbers whose sum is prime are:
1 + 2 = 3
2 + 3 = 5
3 + 4 = 7
5 + 6 = 11
6 + 7 = 13
8 + 9 = 17
9 + 10 = 19
11 + 12 = 23
14 + 15 = 29
15 + 16 = 31
18 + 19 = 37
20 + 21 = 41
21 + 22 = 43
23 + 24 = 47
26 + 27 = 53
29 + 30 = 59
30 + 31 = 61
33 + 34 = 67
35 + 36 = 71
36 + 37 = 73

The 10 millionth such pair is:
89712345 + 89712346 = 179424691

Perl

Library: ntheory
use strict;
use warnings;
use ntheory 'is_prime';

my($n,$c);
while () { is_prime(1 + 2*++$n) and printf "%2d + %2d = %2d\n", $n, $n+1, 1+2*$n and ++$c == 20 and last }
Output:
 1 +  2 =  3
 2 +  3 =  5
 3 +  4 =  7
 5 +  6 = 11
 6 +  7 = 13
 8 +  9 = 17
 9 + 10 = 19
11 + 12 = 23
14 + 15 = 29
15 + 16 = 31
18 + 19 = 37
20 + 21 = 41
21 + 22 = 43
23 + 24 = 47
26 + 27 = 53
29 + 30 = 59
30 + 31 = 61
33 + 34 = 67
35 + 36 = 71
36 + 37 = 73

Phix

Every prime p greater than 2 is odd, hence p/2 is k.5 and the adjacent numbers needed are k and k+1. DOH.

with javascript_semantics
procedure doh(integer p)
    printf(1,"%d + %d = %d\n",{floor(p/2),ceil(p/2),p})
end procedure
papply(get_primes(-21)[2..$],doh)
doh(get_prime(1e7+1))
Output:
1 + 2 = 3
2 + 3 = 5
3 + 4 = 7
5 + 6 = 11
6 + 7 = 13
8 + 9 = 17
9 + 10 = 19
11 + 12 = 23
14 + 15 = 29
15 + 16 = 31
18 + 19 = 37
20 + 21 = 41
21 + 22 = 43
23 + 24 = 47
26 + 27 = 53
29 + 30 = 59
30 + 31 = 61
33 + 34 = 67
35 + 36 = 71
36 + 37 = 73
89712345 + 89712346 = 179424691


PL/M

Works with: 8080 PL/M Compiler
... under CP/M (or an emulator)
100H: /* FIND NUMBERS N SUCH THAT N + N + 1 IS PRIME                         */

   /* CP/M SYSTEM CALL AND I/O ROUTINES                                      */
   BDOS:      PROCEDURE( FN, ARG ); DECLARE FN BYTE, ARG ADDRESS; GOTO 5; END;
   PR$CHAR:   PROCEDURE( C ); DECLARE C BYTE;    CALL BDOS( 2, C );  END;
   PR$STRING: PROCEDURE( S ); DECLARE S ADDRESS; CALL BDOS( 9, S );  END;
   PR$NL:     PROCEDURE;   CALL PR$CHAR( 0DH ); CALL PR$CHAR( 0AH ); END;
   PR$NUMBER: PROCEDURE( N ); /* PRINTS A NUMBER IN THE MINIMUN FIELD WIDTH  */
      DECLARE N ADDRESS;
      DECLARE V ADDRESS, N$STR ( 6 )BYTE, W BYTE;
      V = N;
      W = LAST( N$STR );
      N$STR( W ) = '$';
      N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
      DO WHILE( ( V := V / 10 ) > 0 );
         N$STR( W := W - 1 ) = '0' + ( V MOD 10 );
      END;
      CALL PR$STRING( .N$STR( W ) );
   END PR$NUMBER;

   PR$NUMBER2: PROCEDURE( N ); /* PRINT A NUMBER IN AT LEAST 2 POSITIONS     */
      DECLARE N ADDRESS;
      IF N < 10 THEN CALL PR$CHAR( ' ' );
      CALL PR$NUMBER( N );
   END PR$NUMBER2;

   /* TASK                                                                   */
   /* ASSUMING THE FIRST 20 SUCH NUMBERS WILL BE < 255                       */

   DECLARE MAX$NUMBER LITERALLY '255'
         , FALSE      LITERALLY '0'
         , TRUE       LITERALLY '0FFH'
         ;

   DECLARE PRIME ( MAX$NUMBER )BYTE;   /* SIEVE THE PRIMES TO MAX$NUMBER - 1 */
   DECLARE I ADDRESS;
   PRIME( 0 ), PRIME( 1 ) = FALSE;
   PRIME( 2 ) = TRUE;
   DO I = 3 TO LAST( PRIME ) BY 2; PRIME( I ) = TRUE;  END;
   DO I = 4 TO LAST( PRIME ) BY 2; PRIME( I ) = FALSE; END;
   DO I = 3 TO LAST( PRIME ) BY 2;
      IF PRIME( I ) THEN DO;
         DECLARE S ADDRESS;
         DO S = I + I TO LAST( PRIME ) BY I;
            PRIME( S ) = FALSE;
         END;
      END;
   END;

   /* FIND THE NUMBERS                                                       */
   DECLARE ( N, N1, COUNT ) BYTE;
   COUNT = 0;
   N1    = 1;
   DO WHILE COUNT < 20;
      N  = N1;
      N1 = N1 + 1;
      IF PRIME( N + N1 ) THEN DO;
          COUNT = COUNT + 1;
          CALL PR$NUMBER2( COUNT );
          CALL PR$STRING( .': $' );
          CALL PR$NUMBER2( N );
          CALL PR$STRING( .' + $' );
          CALL PR$NUMBER2( N1 );
          CALL PR$STRING( .' = $' );
          CALL PR$NUMBER2( N + N1 );
          CALL PR$NL;
      END;
   END;

EOF
Output:
 1:  1 +  2 =  3
 2:  2 +  3 =  5
 3:  3 +  4 =  7
 4:  5 +  6 = 11
 5:  6 +  7 = 13
 6:  8 +  9 = 17
 7:  9 + 10 = 19
 8: 11 + 12 = 23
 9: 14 + 15 = 29
10: 15 + 16 = 31
11: 18 + 19 = 37
12: 20 + 21 = 41
13: 21 + 22 = 43
14: 23 + 24 = 47
15: 26 + 27 = 53
16: 29 + 30 = 59
17: 30 + 31 = 61
18: 33 + 34 = 67
19: 35 + 36 = 71
20: 36 + 37 = 73

Python

Procedural

#!/usr/bin/python

def isPrime(n):
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False        
    return True

if __name__ == "__main__":
    n = 0
    num = 0

    print('The first 20 pairs of numbers whose sum is prime:') 
    while True:
        n += 1
        suma = 2*n+1
        if isPrime(suma):
            num += 1
            if num < 21:
                print('{:2}'.format(n), "+", '{:2}'.format(n+1), "=", '{:2}'.format(suma))
            else:
                break
Output:
The first 20 pairs of numbers whose sum is prime:
 1 +  2 =  3
 2 +  3 =  5
 3 +  4 =  7
 5 +  6 = 11
 6 +  7 = 13
 8 +  9 = 17
 9 + 10 = 19
11 + 12 = 23
14 + 15 = 29
15 + 16 = 31
18 + 19 = 37
20 + 21 = 41
21 + 22 = 43
23 + 24 = 47
26 + 27 = 53
29 + 30 = 59
30 + 31 = 61
33 + 34 = 67
35 + 36 = 71
36 + 37 = 73

Functional

'''Prime sums of two consecutive integers'''

from itertools import chain, count, islice


# primeSumsOfTwoConsecutiveIntegers :: [Int]
def primeSumsOfTwoConsecutiveIntegers():
    '''Infinite series of prime sums of
       two consecutive integers.
    '''
    def go(a, b):
        n = a + b
        return [(n, (a, b))] if isPrime(n) else []

    return chain.from_iterable(
        map(go, count(1), count(2))
    )


# ------------------------- TEST -------------------------
# main :: IO ()
def main():
    '''First 20 prime sums of two consecutive integers.'''
    print(
        '\n'.join([
          f'{n} = {a} + {b}'  for n, (a, b) in islice(
                primeSumsOfTwoConsecutiveIntegers(),
                20
            )
        ])
    )


# ----------------------- GENERIC ------------------------

# isPrime :: Int -> Bool
def isPrime(n):
    '''True if n is prime.'''
    if n in (2, 3):
        return True
    if 2 > n or 0 == n % 2:
        return False
    if 9 > n:
        return True
    if 0 == n % 3:
        return False

    def p(x):
        return 0 == n % x or 0 == n % (2 + x)

    return not any(map(p, range(5, 1 + int(n ** 0.5), 6)))


# MAIN ---
if __name__ == '__main__':
    main()


or as a list comprehension (the walrus operator requires Python 3.8+)

'''Prime sums of two consecutive integers'''

from itertools import count, islice


# primeSumsOfTwoConsecutiveIntegers :: [Int]
def primeSumsOfTwoConsecutiveIntegers():
    '''As a list comprehension.'''
    return (
        (n, (a, b))
        for a in count(1)
        if isPrime(n := a + (b := 1 + a))
    )


# ------------------------- TEST -------------------------
# main :: IO ()
def main():
    '''First 20 prime sums of two consecutive integers.'''
    print(
        '\n'.join([
            f'{n} = {a} + {b}' for n, (a, b) in islice(
                primeSumsOfTwoConsecutiveIntegers(),
                20
            )
        ])
    )


# ----------------------- GENERIC ------------------------

# isPrime :: Int -> Bool
def isPrime(n):
    '''True if n is prime.'''
    if n in (2, 3):
        return True
    if 2 > n or 0 == n % 2:
        return False
    if 9 > n:
        return True
    if 0 == n % 3:
        return False

    def p(x):
        return 0 == n % x or 0 == n % (2 + x)

    return not any(map(p, range(5, 1 + int(n ** 0.5), 6)))


# MAIN ---
if __name__ == '__main__':
    main()
Output:
3 = 1 + 2
5 = 2 + 3
7 = 3 + 4
11 = 5 + 6
13 = 6 + 7
17 = 8 + 9
19 = 9 + 10
23 = 11 + 12
29 = 14 + 15
31 = 15 + 16
37 = 18 + 19
41 = 20 + 21
43 = 21 + 22
47 = 23 + 24
53 = 26 + 27
59 = 29 + 30
61 = 30 + 31
67 = 33 + 34
71 = 35 + 36
73 = 36 + 37

Quackery

Every odd number is the sum of two adjacent numbers, so this task is "the first twenty odd primes" or "the first twenty primes after 2".

isprime is defined at Primality by trial division#Quackery.

  [ 1 [] rot
    [ over size
      over != while
      dip
        [ over isprime if
            [ over join ]
          dip [ 2 + ] ]
      again ]
     drop nip ]           is oddprimes ( n --> [ )

  [ oddprimes
    witheach
      [ dup 2 /
        dup echo
        say " + "
        1+ echo
        say " = "
        echo cr ] ]       is task       ( n -->   )

20 task
Output:
1 + 2 = 3
2 + 3 = 5
3 + 4 = 7
5 + 6 = 11
6 + 7 = 13
8 + 9 = 17
9 + 10 = 19
11 + 12 = 23
14 + 15 = 29
15 + 16 = 31
18 + 19 = 37
20 + 21 = 41
21 + 22 = 43
23 + 24 = 47
26 + 27 = 53
29 + 30 = 59
30 + 31 = 61
33 + 34 = 67
35 + 36 = 71
36 + 37 = 73

Raku

my @n-n1-triangular = map { $_, $_ + 1, $_ + ($_ + 1) }, ^Inf;

my @wanted = @n-n1-triangular.grep: *.[2].is-prime;

printf "%2d + %2d = %2d\n", |.list for @wanted.head(20);
Output:
 1 +  2 =  3
 2 +  3 =  5
 3 +  4 =  7
 5 +  6 = 11
 6 +  7 = 13
 8 +  9 = 17
 9 + 10 = 19
11 + 12 = 23
14 + 15 = 29
15 + 16 = 31
18 + 19 = 37
20 + 21 = 41
21 + 22 = 43
23 + 24 = 47
26 + 27 = 53
29 + 30 = 59
30 + 31 = 61
33 + 34 = 67
35 + 36 = 71
36 + 37 = 73

Ring

load "stdlibcore.ring"
see "working..." + nl
n = 0
num = 0

while true
     n++
     sum = 2*n+1
     if isprime(sum)
        num++
        if num < 21
          ? "" + n + " + " + (n+1) + " = " + sum
        else
          exit
        ok
      ok
end

see "done..." + nl
Output:
working...
1 + 2 = 3
2 + 3 = 5
3 + 4 = 7
5 + 6 = 11
6 + 7 = 13
8 + 9 = 17
9 + 10 = 19
11 + 12 = 23
14 + 15 = 29
15 + 16 = 31
18 + 19 = 37
20 + 21 = 41
21 + 22 = 43
23 + 24 = 47
26 + 27 = 53
29 + 30 = 59
30 + 31 = 61
33 + 34 = 67
35 + 36 = 71
36 + 37 = 73
done...

RPL

Works with: HP version 49
≪ { } 2
   WHILE OVER SIZE 20 < REPEAT
     NEXTPRIME 
     DUP 2 IQUOT →STR 
     LASTARG SWAP "+" + SWAP 1 + + "=" + OVER +
     ROT SWAP + SWAP 
  END DROP
≫ 'TASK' STO
Output:
1: {"1+2=3" "2+3=5" "3+4=7" "5+6=11" "6+7=13" "8+9=17" "9+10=19" "11+12=23" "14+15=29" "15+16=31" "18+19=37" "20+21=41" "21+22=43" "23+24=47" "26+27=53" "29+30=59" "30+31=61" "33+34=67" "35+36=71" "36+37=73"}

Ruby

require 'prime'

primes = Prime.each
primes.next # skip 2
primes.first(20).each{|pr| puts "%3d + %3d = %3d" % [pr/2, pr/2+1, pr]}
Output:
  1 +   2 =   3
  2 +   3 =   5
  3 +   4 =   7
  5 +   6 =  11
  6 +   7 =  13
  8 +   9 =  17
  9 +  10 =  19
 11 +  12 =  23
 14 +  15 =  29
 15 +  16 =  31
 18 +  19 =  37
 20 +  21 =  41
 21 +  22 =  43
 23 +  24 =  47
 26 +  27 =  53
 29 +  30 =  59
 30 +  31 =  61
 33 +  34 =  67
 35 +  36 =  71
 36 +  37 =  73

Sidef

var wanted = (1..Inf -> lazy.map  {|n| [n, n+1, n+(n+1)] }\
                            .grep { .tail.is_prime })

wanted.first(20).each_2d {|a,b,c|
    printf("%2d + %2d = %2d\n", a,b,c)
}
Output:
 1 +  2 =  3
 2 +  3 =  5
 3 +  4 =  7
 5 +  6 = 11
 6 +  7 = 13
 8 +  9 = 17
 9 + 10 = 19
11 + 12 = 23
14 + 15 = 29
15 + 16 = 31
18 + 19 = 37
20 + 21 = 41
21 + 22 = 43
23 + 24 = 47
26 + 27 = 53
29 + 30 = 59
30 + 31 = 61
33 + 34 = 67
35 + 36 = 71
36 + 37 = 73

Wren

Translation of: Go
Library: Wren-math
Library: Wren-fmt
import "./math" for Int
import "./fmt" for Fmt

var limit = (1e7.log * 1e7 * 1.2).floor  // should be more than enough
var primes = Int.primeSieve(limit)
System.print("The first 20 pairs of natural numbers whose sum is prime are:")
for (i in 1..20) {
    var p = primes[i]
    var hp = (p/2).floor
    Fmt.print("$2d + $2d = $2d", hp, hp + 1, p)
}
System.print("\nThe 10 millionth such pair is:")
var p = primes[1e7]
var hp = (p/2).floor
Fmt.print("$2d + $2d = $2d", hp, hp + 1, p)
Output:
The first 20 pairs of natural numbers whose sum is prime are:
 1 +  2 =  3
 2 +  3 =  5
 3 +  4 =  7
 5 +  6 = 11
 6 +  7 = 13
 8 +  9 = 17
 9 + 10 = 19
11 + 12 = 23
14 + 15 = 29
15 + 16 = 31
18 + 19 = 37
20 + 21 = 41
21 + 22 = 43
23 + 24 = 47
26 + 27 = 53
29 + 30 = 59
30 + 31 = 61
33 + 34 = 67
35 + 36 = 71
36 + 37 = 73

The 10 millionth such pair is:
89712345 + 89712346 = 179424691

XPL0

Translation of: Ring
include xpllib;
int N, Num, Sum;
[Text(0, "Working...^M^J");
N:= 0;
Num:= 0;
loop
    [N:= N+1;
    Sum:= 2*N + 1;
    if IsPrime(Sum) then
        [Num:= Num+1;
        if Num < 21 then
          [Text(0,"N = "); IntOut(0,N); Text(0,"  Sum = "); IntOut(0,Sum); CrLf(0)]
        else
          quit
        ]
    ];
Text(0, "Done...^M^J");
]
Output:
Working...
N = 1  Sum = 3
N = 2  Sum = 5
N = 3  Sum = 7
N = 5  Sum = 11
N = 6  Sum = 13
N = 8  Sum = 17
N = 9  Sum = 19
N = 11  Sum = 23
N = 14  Sum = 29
N = 15  Sum = 31
N = 18  Sum = 37
N = 20  Sum = 41
N = 21  Sum = 43
N = 23  Sum = 47
N = 26  Sum = 53
N = 29  Sum = 59
N = 30  Sum = 61
N = 33  Sum = 67
N = 35  Sum = 71
N = 36  Sum = 73
Done...