Problem 37 もういっかい

isPrime <- function(n){
  if(n == 1) return(FALSE)
  if(n < 4) return(TRUE)
  if(n%%2==0) return(FALSE)
  if(n < 9) return(TRUE)
  if(n%%3==0) return(FALSE)
  r <- floor(sqrt(n))
  f <- 5
  while(f <= r){
    if(n%%f == 0) return(FALSE)
    if(n%%(f+2) == 0) return(FALSE)
    f <- f + 6
  }
  return(TRUE)
}

Rcut <- function(n) floor(n/10)
Lcut <- function(n) n%%10^floor(log(n,10))

isTractable <- function(n){
  if(!isPrime(n)) return(FALSE)
  Rc <- Lc <- n
  while(Rc > 10){
    Rc <- Rcut(Rc)
    Lc <- Lcut(Lc)
    if(!(isPrime(Rc) && isPrime(Lc))){
      return(FALSE)
    }
  }
  return(TRUE)
}

head <- rep(c(2, 3, 5, 7),2)
tail <- rep(c(3, 7),c(4,4))
odds <- seq(1,9,2)

count <- 0
tr.nums <- numeric(11)
insert <- 0
while(count < 11){
  candidates <- rep(head, 5^insert)*10
  if(insert){
    for(i in seq(1, insert, length=insert)){
      candidates <- 10*(candidates +
                        rep(rep(odds,5^(i-1)),
                            rep(length(candidates)/(5^i),
                              5^i)))
    }
  }
  candidates <- candidates + rep(tail, 5^insert)
  for(i in 1:length(candidates)){
    if(isTractable(candidates[i])){
      count <- count+1
      tr.nums[count] <- candidates[i]
    }
  }
  insert <- insert + 1
}

素数の頭と尾っぽの間に奇数を挿入して判定かける感じ。
2秒ちょいで終わるようになったけど、repとか入れ子にしてて大変見難い。