1

I am trying to list the first 87 twin primes. I'm using the Eratosthenes approach. Here is what I've worked on so far

Eratosthenes <- function(n) {
  # Return all prime numbers up to n (based on the sieve of Eratosthenes)
  if (n >= 2) {
    sieve <- seq(2, n) # initialize sieve
    primes <- c() # initialize primes vector
    for (i in seq(2, n)) {
      if (any(sieve == i)) { # check if i is in the sieve
        primes <- c(primes, i) # if so, add i to primes
        sieve <- sieve[(sieve %% i) != 0] # remove multiples of i from sieve
      }
    }
    return(primes)
  } else {
    stop("Input value of n should be at least 2.")
  }
}

Era <- c(Eratosthenes(87))
i <- 2:86

for (i in Era){
  if (Era[i]+2 == Era[i+1]){
    print(c(Era[i], Era[i+1]))
  }
}

First thing I dont understand is this error:

Error in if (Era[i] + 2 == Era[i + 1]) { : 
  missing value where TRUE/FALSE needed

Second thing is in the list there are missing twin primes so for example (29,31)

  • 2
    print `i` for each iteration, I think you will see the problem, also you need to do one fewer iteration than the length of `Era`, that is causing your error – rawr Oct 21 '20 at 03:12
  • 1
    Except for [3, 5] all twin prime pairs are of the form [6n-1, 6n+1]. That might speed up your search. – rossum Oct 21 '20 at 07:42

3 Answers3

0

Firstly, (23,29) is not twin prime.

Secondly, your answer may be found in here

Edit: I've tried your code, I found that length of Era is 23.

Maybe when running if (Era[i] + 2 == Era[i+1]), it reaches to 24 and causes the problem.

0

for (i in Era) will set i to 2, then 3, then 5 etc which is not what you intended. Use for (i in seq_len(length(Era) - 1)).

for (i in seq_len(length(Era) - 1)){
  if (Era[i] + 2 == Era[i + 1]){
    print(c(Era[i], Era[i + 1]))
  }
}
#> [1] 3 5
#> [1] 5 7
#> [1] 11 13
#> [1] 17 19
#> [1] 29 31
#> [1] 41 43
#> [1] 59 61
#> [1] 71 73
Paul
  • 8,734
  • 1
  • 26
  • 36
0

Within your for loop, i is not index any more but the element in Era. In this case, you can try using (i+2) %in% Era to judge if i+2 is the twin

for (i in Era){
  if ((i+2) %in% Era){
    print(c(i,i+2))
  }
}

which gives

[1] 3 5
[1] 5 7
[1] 11 13
[1] 17 19
[1] 29 31
[1] 41 43
[1] 59 61
[1] 71 73

A simpler way might be using diff, e.g.,

i <- Era[c(diff(Era)==2,FALSE)]
print(cbind(i,j = i+2))

which gives

> print(cbind(i,j = i+2))
      i  j
[1,]  3  5
[2,]  5  7
[3,] 11 13
[4,] 17 19
[5,] 29 31
[6,] 41 43
[7,] 59 61
[8,] 71 73
ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81