Double Twin Primes

From Rosetta Code
Double Twin 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.

Definition
Let (p1,p2) and (p3,p4) be twin primes where p3 - p2 = 4.
Such primes called Double Twin Primes

Example
[5,7,11,13]
Task
Find and show here all Double Twin Primes under 1000.

See also



ALGOL 68

BEGIN # find some sequences of primes where the gaps between the elements #
      # are 2, 4, 2 - i.e., n, n+2, n+6 and n+8 are all prime             #
    PR read "primes.incl.a68" PR                # include prime utilities #
    []BOOL prime  = PRIMESIEVE 1 000;
    INT    count := 0;
    INT    p     := 3;        # 2 cannot be a twin prime, so start with 3 #
    WHILE p <= UPB prime - 8 DO
        BOOL is double twin := FALSE;
        IF prime[ p ] THEN
            IF prime[ p + 2 ] THEN
                IF prime[ p + 6 ] THEN
                    IF prime[ p + 8 ] THEN
                        count         +:= 1;
                        is double twin := TRUE;
                        print( ( "["
                               , whole( p,     -4 ), whole( p + 2, -4 )
                               , whole( p + 6, -4 ), whole( p + 8, -4 )
                               , " ]"
                               , newline
                               )
                             )
                    FI
                FI
            FI
        FI;
        p +:= IF is double twin THEN 6 ELSE 2 FI
    OD;
    print( ( "Found ", whole( count, 0 ), " double twin primes below ", whole( UPB prime, 0 ), newline ) )
END
Output:
[   5   7  11  13 ]
[  11  13  17  19 ]
[ 101 103 107 109 ]
[ 191 193 197 199 ]
[ 821 823 827 829 ]
Found 5 double twin primes beflow 1000

Arturo

r: range .step: 2 1 1000
r | map 'x -> @[x x+2 x+6 x+8]
  | select => [every? & => prime?]
  | loop => print
Output:
5 7 11 13
11 13 17 19
101 103 107 109
191 193 197 199
821 823 827 829

BASIC

BASIC256

Translation of: FreeBASIC
#include "isPrime.kbs"

num = 3
while num < 992
	if isPrime(num) then
		if isPrime(num+2) then
			if isPrime(num+6) then
				if isPrime(num+8) then print num; " "; num+2; " "; num+6; " "; num+8
			end if
		end if
	end if
	num += 2
end while
end
Output:
Same as FreeBASIC entry.

Gambas

Translation of: FreeBASIC
Public Sub Main() 

  Dim num As Integer = 3 
  Do 
    If isPrime(num) Then 
      If isPrime(num + 2) Then 
        If isPrime(num + 6) Then 
          If isPrime(num + 8) Then Print num; " "; num + 2; " "; num + 6; " "; num + 8 
        End If 
      End If 
    End If 
    num += 2 
  Loop Until num > 992

End 

Public Sub isPrime(ValorEval As Long) As Boolean   
  
  If ValorEval < 2 Then Return False   
  If ValorEval Mod 2 = 0 Then Return ValorEval = 2   
  If ValorEval Mod 3 = 0 Then Return ValorEval = 3   
  Dim d As Long = 5   
  While d * d <= ValorEval   
    If ValorEval Mod d = 0 Then Return False Else d += 2   
  Wend    
  Return True   
  
End Function
Output:
Same as FreeBASIC entry.

PureBasic

Translation of: FreeBASIC
Procedure.b 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

OpenConsole()
num.I = 3
While num < 992
  If isPrime(num):
    If isPrime(num+2):
      If isPrime(num+6):
        If isPrime(num+8):
          PrintN(Str(num) + " " + Str(num+2) + " " + Str(num+6) + " " + Str(num+8))
        EndIf
      EndIf
    EndIf
  EndIf
  num + 2
Wend

Input()
CloseConsole();
Output:
Same as FreeBASIC entry.

Run BASIC

Translation of: FreeBASIC
function isPrime(n)
if n < 2       then isPrime = 0 : goto [exit]
if n = 2       then isPrime = 1 : goto [exit]
if n mod 2 = 0 then isPrime = 0 : goto [exit]
isPrime = 1
for i = 3 to int(n^.5) step 2
  if n mod i = 0 then isPrime = 0 : goto [exit]
next i
[exit]
end function

num = 3
while num < 992
    if isPrime(num) then
        if isPrime(num+2) then
            if isPrime(num+6) then
                if isPrime(num+8) then print num; " "; num+2; " "; num+6; " "; num+8
            end if
        end if
    end if
    num = num + 2
wend
end
Output:
Same as FreeBASIC entry.

Tiny BASIC

REM Rosetta Code problem: https://rosettacode.org/wiki/Double_Twin_Primes
REM by Jjuanhdez, 03/2023

    LET I = 3
 10 LET X = I
    GOSUB 100
	IF Z = 1 THEN LET X = I + 2
	IF Z = 1 THEN GOSUB 100
	IF Z = 1 THEN LET X = I + 6
	IF Z = 1 THEN GOSUB 100	
	IF Z = 1 THEN LET X = I + 8
	IF Z = 1 THEN GOSUB 100
	IF Z = 1 THEN PRINT I, " ", I + 2, " ", I + 6, " ", I + 8 
    LET I = I + 2
	IF I > 992 THEN GOTO 20
	GOTO 10
 20 END

100 REM is X a prime? Z=1 for yes, 0 for no
    LET Z = 1
    IF X = 3 THEN RETURN
    IF X = 2 THEN RETURN    
    LET A = 1
110 LET A = A + 1
    IF (X / A) * A = X THEN GOTO 120
    IF A * A <= X THEN GOTO 110
    RETURN
120 LET Z = 0
    RETURN
Same as FreeBASIC entry.

XBasic

Translation of: BASIC256
Works with: Windows XBasic
PROGRAM  "DoubleTwinPrimes"
VERSION  "0.0000"

DECLARE FUNCTION Entry ()
INTERNAL FUNCTION ISPrime(n%%)

FUNCTION  Entry ()
num%% = 3
DO
  IF ISPrime(num%%) THEN
    IF ISPrime(num%%+2) THEN
      IF ISPrime(num%%+6) THEN
        IF ISPrime(num%%+8) THEN
          PRINT num%%; num%%+2; num%%+6; num%%+8
        ENDIF
      ENDIF
    ENDIF
  ENDIF
  num%% = num%% + 2
LOOP UNTIL num%% > 992
END FUNCTION

FUNCTION ISPrime(n%%)
  IF n%% < 2 THEN RETURN $$FALSE
  IF n%% MOD 2 = 0 THEN RETURN n%% = 2
  IF n%% MOD 3 = 0 THEN RETURN n%% = 3
  d%% = 5
  DO WHILE d%% * d%% <= n%%
      IF n%% MOD d%% = 0 THEN RETURN $$FALSE ELSE d%% = d%% + 2
  LOOP
  RETURN $$TRUE
END FUNCTION
END PROGRAM
Output:
Same as BASIC256 entry.

Yabasic

Translation of: FreeBASIC
//import isPrime

num = 3
repeat
    if isPrime(num) if isPrime(num+2) if isPrime(num+6) if isPrime(num+8) print num, " ", num+2, " ", num+6, " ", num+8
    num = num + 2
until num > 992
end
Output:
Same as FreeBASIC entry.

C

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

bool isPrime(int n) {
    if (n < 2) return false;
    if (n%2 == 0) return n == 2;
    if (n%3 == 0) return n == 3;
    int d = 5;
    while (d*d <= n) {
        if (n%d == 0) return false;
        d += 2;
        if (n%d == 0) return false;
        d += 4;
    }
    return true;
}

int main() {
    printf("Double twin primes under 1,000:\n");
    for (int i = 3; i < 992; i+=2) {
        if (isPrime(i) && isPrime(i+2) && isPrime(i+6) && isPrime(i+8)) {
            printf("%4d %4d %4d %4d\n", i, i+2, i+6, i+8);
        }
    }    
    return 0;
}
Output:
Double twin primes under 1,000:
   5    7   11   13
  11   13   17   19
 101  103  107  109
 191  193  197  199
 821  823  827  829

Dart

import 'dart:math';

void main() {
  for (int num = 3; num < 992; num += 2) {
    if (isPrime(num) &&
        isPrime(num + 2) &&
        isPrime(num + 6) &&
        isPrime(num + 8)) {
      print("$num ${num + 2} ${num + 6} ${num + 8}");
    }
  }
}

bool isPrime(int n) {
  if (n <= 1) return false;
  if (n == 2) return true;
  for (int i = 2; i <= sqrt(n); ++i) {
    if (n % i == 0) return false;
  }
  return true;
}
Output:
Same as FreeBASIC entry.

Delphi

Works with: Delphi version 6.0

Uses standard TList as FIFO to hold and test groups of four sequentail prime numbers.

function IsPrime(N: integer): boolean;
{Fast, optimised prime test}
var I,Stop: integer;
begin
if (N = 2) or (N=3) then Result:=true
else if (n <= 1) or ((n mod 2) = 0) or ((n mod 3) = 0) then Result:= false
else
     begin
     I:=5;
     Stop:=Trunc(sqrt(N));
     Result:=False;
     while I<=Stop do
           begin
           if ((N mod I) = 0) or ((N mod (I + 2)) = 0) then exit;
           Inc(I,6);
           end;
     Result:=True;
     end;
end;


function GetNextPrime(var Start: integer): integer;
{Get the next prime number after Start}
{Start is passed by "reference," so the
{original variable is incremented}
begin
repeat Inc(Start)
until IsPrime(Start);
Result:=Start;
end;

procedure ShowDoubleTwinPrimes(Memo: TMemo);
{Find sets of four primes P1,P2,P3,P4, where}
{P2-P1=2 P4-P3=2 and P3-P2=4 }
{Use TList as FIFO to test all four-prime combinations}
var LS: TList;
var Start: integer;
begin
LS:=TList.Create;
try
Start:=0;
while true do
	begin
	{Put four primes in the list}
	repeat LS.Add(Pointer(GetNextPrime(Start)))
	until LS.Count=4;
	if Integer(LS[3])>=1000 then break;
	{Test if they are double twin prime}
	if (Integer(LS[1])-Integer(LS[0])=2) and
	   (Integer(LS[3])-Integer(LS[2])=2) and
	   (Integer(LS[2])-Integer(LS[1])=4) then
	   	begin
	   	{Display the result}
	   	Memo.Lines.Add(IntToStr(Integer(LS[0]))+' '+
			IntToStr(Integer(LS[1]))+' '+
			IntToStr(Integer(LS[2]))+' '+
			IntToStr(Integer(LS[3])));
		end;
	{Delete the first prime}
	LS.Delete(0);
	end;
finally LS.Free; end;
end;
Output:
5 7 11 13
11 13 17 19
101 103 107 109
191 193 197 199
821 823 827 829


FreeBASIC

#include "isprime.bas"

Dim As Uinteger num = 3
Do
    If isPrime(num) Then
        If isPrime(num+2) Then
            If isPrime(num+6) Then
                If isPrime(num+8) Then Print num; " "; num+2; " "; num+6; " "; num+8
            End If
        End If
    End If
    num += 2
Loop Until num > 992

Sleep
Output:
5 7 11 13
11 13 17 19
101 103 107 109
191 193 197 199
821 823 827 829

FutureBasic

local fn IsPrime( n as long ) as BOOL
  long i
  BOOL result = YES
  
  if ( n < 2 ) then result = NO : exit fn
  for i = 2 to n + 1
    if ( i * i <= n ) and ( n mod i == 0 )
      result = NO : exit fn
    end if
  next
end fn = result

local fn DoubleTwinPrimes( limit as long )
  NSUInteger num = 3
  printf @"Double twin primes < %ld:", limit
  do
    if fn IsPrime( num )
      if fn IsPrime( num + 2 )
        if fn IsPrime( num + 6 )
          if fn IsPrime( num + 8 ) then printf @"%4lu%7lu%7lu%7lu", num, num + 2, num + 6, num + 8
        end if
      end if
    end if
    num += 2
  until ( num > limit )
end fn

fn DoubleTwinPrimes( 2000 )

HandleEvents
Output:
Double twin primes < 2000:
   5      7     11     13
  11     13     17     19
 101    103    107    109
 191    193    197    199
 821    823    827    829
1481   1483   1487   1489
1871   1873   1877   1879


Go

Translation of: Wren
Library: Go-rcu
package main

import (
    "fmt"
    "rcu"
)

func main() {
    p := rcu.Primes(1000)
    fmt.Println("Double twin primes under 1,000:")
    for i := 1; i < len(p)-3; i++ {
        if p[i+1]-p[i] == 2 && p[i+2]-p[i+1] == 4 && p[i+3]-p[i+2] == 2 {
            fmt.Printf("%4d\n", p[i:i+4])
        }
    }
}
Output:
Double twin primes under 1,000:
[   5    7   11   13]
[  11   13   17   19]
[ 101  103  107  109]
[ 191  193  197  199]
[ 821  823  827  829]

J

   _6 _4 0 2+/~(#~ 0,4=2-~/\])p:~.,0 1+/~/I.2=2 -~/\ i.&.(p:inv) 1000
  5   7  11  13
 11  13  17  19
101 103 107 109
191 193 197 199
821 823 827 829

Breaking this down:

   primes=: i.&.(p:inv) 1000
   twinprimes=:  p:~.,0 1+/~/I.2=2 -~/\ primes
   doubletwinprimes=: _6 _4 0 2+/~(#~ 0,4=2-~/\])

The first two expressions rely on the primitive p: which translates between the index of a prime number and the prime itself. The final expression instead filters the remaining primes (because the sequence of primes which was its argument had already been filtered enough to have made indices into that sequence into relevant information which was not worth recalculating).

jq

Works with: jq

Also works with gojq, the Go implementation of jq

# Input:  a positive integer
# Output: an array, $a, of length .+1 such that
#         $a[$i] is $i if $i is prime, and false otherwise.
def primeSieve:
  # erase(i) sets .[i*j] to false for integral j > 1
  def erase(i):
    if .[i] then 
      reduce (range(2*i; length; i)) as $j (.; .[$j] = false) 
    else .
    end;
  (. + 1) as $n
  | (($n|sqrt) / 2) as $s
  | [null, null, range(2; $n)]
  | reduce (2, 1 + (2 * range(1; $s))) as $i (.; erase($i)) ;

def double_twin_primes($n):
  [$n|primeSieve|range(0;length) as $i | select(.[$i]) | $i] as $p
  | range(1; $p|length-3) as $i
  | select( ($p[$i+1] - $p[$i]) == 2 and ($p[$i+2] - $p[$i+1]) == 4 and ($p[$i+3] - $p[$i+2]) == 2 )
  | [$p[$i, $i+1, $i+2, $i+3]] ;


"Double twin primes under 1,000:",
 double_twin_primes(1000)
Output:
Double twin primes under 1,000:
[5,7,11,13]
[11,13,17,19]
[101,103,107,109]
[191,193,197,199]
[821,823,827,829]

Julia

Translation of: C
using Primes
using Printf

function printdt(N)
    @printf("Double twin primes under 1,000:\n")
    for i in 3:2:N-8
        if isprime(i) && isprime(i+2) && isprime(i+6) && isprime(i+8)
            @printf("%4d %4d %4d %4d\n", i, i+2, i+6, i+8)
        end
    end
end

printdt(1000)
Output:

Same as C example.

Nim

import std/strformat

func isPrime(n: Positive): bool =
  if n < 2: return false
  if (n and 1) == 0: return n == 2
  if n mod 3 == 0: return n == 3
  var k = 5
  var delta = 2
  while k * k <= n:
    if n mod k == 0: return false
    inc k, delta
    delta = 6 - delta
  result = true

echo "Double twin primes under 1000:"
for n in countup(3, 991, 2):
  if isPrime(n) and isPrime(n + 2) and isPrime(n + 6) and isPrime(n + 8):
    echo &"({n:>3}, {n+2:>3}, {n+6:>3}, {n+8:>3})"
Output:
(  5,   7,  11,  13)
( 11,  13,  17,  19)
(101, 103, 107, 109)
(191, 193, 197, 199)
(821, 823, 827, 829)

Perl

Library: ntheory
use v5.36;
use ntheory 'is_prime';

sub dt ($p) { map { $p + $_ } <0 2 6 8> }
for my $n (1..1000) { say "@{[dt $n]}" if 4 == +(grep { is_prime $_ } dt $n) }
Output:
5 7 11 13
11 13 17 19
101 103 107 109
191 193 197 199
821 823 827 829

Phix

with javascript_semantics
sequence p = get_primes_le(1000)
for i=1 to length(p)-3 do
    if p[i+3]-p[i]=8 and p[i+2]-p[i]!=4 then
        printf(1,"%s\n",join(p[i..i+3],fmt:="%4d"))
    end if
end for
Output:
   5    7   11   13
  11   13   17   19
 101  103  107  109
 191  193  197  199
 821  823  827  829

Python

#!/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__":
    num = 3
    while num <= 1000:
        if isPrime(num):
            if isPrime(num+2):
                if isPrime(num+6):
                    if isPrime(num+8):
                        print(num, num+2, num+6, num+8, sep="\t")
        num += 2
Output:
5	7	11	13
11	13	17	19
101	103	107	109
191	193	197	199
821	823	827	829

Raku

Cousin twin primes:

sub dt { $^p, $p+2, $p+6, $p+8 }
.&dt.say for (^1000).grep: { all .&dt».is-prime };
Output:
(5 7 11 13)
(11 13 17 19)
(101 103 107 109)
(191 193 197 199)
(821 823 827 829)

Ring

see "working..." + nl
P = []

limit = 1000
for n =1 to limit
    if isP(n)
       add(P,n)
    ok
next
lenP = len(P)-3
for m = 1 to lenP
    if isP(P[m]) AND isP(P[m+1]) AND isP(P[m+2]) AND isP(P[m+3])
       if (P[m+1] - P[m] = 2) AND (P[m+2] - P[m+1] = 4) AND (P[m+3] - P[m+2] = 2)
          see " " + P[m]+ " " + P[m+1] + " " + P[m+2] + " " + P[m+3] + nl
       ok
    ok
next

see "done..." + nl

func isP num
     if (num <= 1) return 0 ok
     if (num % 2 = 0 AND num != 2) return 0 ok     
     for i = 3 to floor(num / 2) -1 step 2
         if (num % i = 0) return 0 ok
     next
return 1
Output:
works...
 5 7 11 13
 11 13 17 19
 101 103 107 109
 191 193 197 199
 821 823 827 829
done...

Ruby

require 'prime'

res = Prime.each(1000).each_cons(4).select do |p1, p2, p3, p4| 
  p1+2 == p2 && p2+4 == p3 && p3+2 == p4
end

res.each{|slice| puts slice.join(", ")}
Output:
5, 7, 11, 13
11, 13, 17, 19
101, 103, 107, 109
191, 193, 197, 199
821, 823, 827, 829

Sidef

1000.primes.each_cons(4, {|*a|
    if (a.diffs == [2, 4, 2]) {
        say a
    }
})
Output:
[5, 7, 11, 13]
[11, 13, 17, 19]
[101, 103, 107, 109]
[191, 193, 197, 199]
[821, 823, 827, 829]

V (Vlang)

Translation of: Ring
import math

fn main() {
	limit := 1000
	mut parr := []int{}
	for n in 1..limit {
		if is_prime(n) {parr << n}
	}
	for m in 1..parr.len - 3 {
		if is_prime(parr[m]) && is_prime(parr[m + 1]) && is_prime(parr[m + 2]) && is_prime(parr[m + 3]) {
		   if parr[m + 1] - parr[m] == 2 && parr[m + 2] - parr[m + 1] == 4 && parr[m + 3] - parr[m + 2] == 2 {
			  println("${parr[m]} ${parr[m + 1]} ${parr[m + 2]} ${parr[m + 3]}")
		   }
		}
	}
}

fn is_prime(num i64) bool {
     if num <= 1 {return false}
     if num % 2 == 0 && num != 2 {return false}
	 for idx := 3; idx <= math.floor(num / 2) - 1; idx += 2 {
         if num % idx == 0 {return false}
     }
     return true
}
Output:
5 7 11 13
11 13 17 19
101 103 107 109
191 193 197 199
821 823 827 829

Wren

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

var p = Int.primeSieve(1000)
System.print("Double twin primes under 1,000:")
for (i in 1...p.count-3) {
    if (p[i+1] - p[i] == 2 && p[i+2] - p[i+1] == 4 && p[i+3] - p[i+2] == 2) {
        Fmt.aprint(p[i..i+3], 4, 0, "")
    }
}
Output:
Double twin primes under 1,000:
   5    7   11   13
  11   13   17   19
 101  103  107  109
 191  193  197  199
 821  823  827  829

XPL0

func IsPrime(N);        \Return 'true' if odd N is prime
int  N, D;
[for D:= 3 to sqrt(N) do
    [if rem(N/D) = 0 then return false;
    D:= D+1;
    ];
return true;
];

int N;
[N:= 3;
repeat  if IsPrime(N) then
          if IsPrime(N+2) then
            if IsPrime(N+6) then
              if IsPrime(N+8) then
                [IntOut(0, N);   ChOut(0, ^ );
                 IntOut(0, N+2); ChOut(0, ^ );
                 IntOut(0, N+6); ChOut(0, ^ );
                 IntOut(0, N+8); CrLf(0);
                ];
        N:= N+2;
until N >= 1000-8;
]
Output:
5 7 11 13
11 13 17 19
101 103 107 109
191 193 197 199
821 823 827 829