Definitions

   A   safe prime   is a prime   p   and where   (p-1)/2   is also prime.
   The corresponding prime  (p-1)/2   is known as a   Sophie Germain   prime.
   An   unsafe prime   is a prime   p   and where   (p-1)/2   isn't   a prime.
   An   unsafe prime   is a prime that   isn't   a   safe   prime.


Task

   Find and display (on one line) the first   35   safe primes.
   Find and display the   count   of the safe primes below   1,000,000.
   Find and display the   count   of the safe primes below 10,000,000.
   Find and display (on one line) the first   40   unsafe primes.
   Find and display the   count   of the unsafe primes below   1,000,000.
   Find and display the   count   of the unsafe primes below 10,000,000.
   (Optional)   display the   counts   and   "below numbers"   with commas.
Show all output here.



Related Task

   strong and weak primes.


Also see

   The OEIS article:     safe   primes.
   The OEIS article:   unsafe primes.


#!/usr/local/bin/shale
 
// Safe and unsafe primes.
//
// Safe prime p: (p - 1) / 2 is prime
// Unsafe prime: any prime that is not a safe prime
 
primes library
 
init dup var {
  pl sieve type primes::()
  10000000 0 pl generate primes::()
} =
 
isSafe dup var {
  1 - 2 / pl isprime primes::()
} =
 
comma dup var {
  n dup var swap =
  t dup var n 1000 / =
  b dup var n 1000 % =
 
  t 0 == {
    b print
  } {
    t.value comma() b ",%03d" printf
  } if
} =
 
go dup var {
  n var
  c1 var
  c10 var
  i var
  p var
 
  "The first 35 safe primes are:" print
  n 0 =
  c1 0 =
  c10 0 =
  i 0 =
  { i count pl:: < } {
    p i pl get primes::() =
    p isSafe() {
      n 35 < {
        p " %d" printf
        n++
        n 35 == { "" println } ifthen
      } ifthen
 
      p 1000000 < { c1++ } ifthen
 
      c10++
    } ifthen
 
    i++
  } while
  "Number of safe primes below  1,000,000 is " print c1.value comma() "" println
  "Number of safe primes below 10,000,000 is " print c10.value comma() "" println
 
  "The first 40 unsafe primes are:" print
  n 0 =
  c1 0 =
  c10 0 =
  i 0 =
  { i count pl:: < } {
    p i pl get primes::() =
    p isSafe() not {
      n 40 < {
        p " %d" printf
        n++
        n 40 == { "" println } ifthen
      } ifthen
 
      p 1000000 < { c1++ } ifthen
 
      c10++
    } ifthen
 
    i++
  } while
  "Number of unsafe primes below  1,000,000 is " print c1.value comma() "" println
  "Number of unsafe primes below 10,000,000 is " print c10.value comma() "" println
} =
 
init()
go()
 