Task: Circular primes


C++: #include <cstdint>
#include <algorithm>
#include <iostream>
#include <sstream>
#include <gmpxx.h>

typedef mpz_class integer;

bool is_prime(const integer& n, int reps = 50) {
    return mpz_probab_prime_p(n.get_mpz_t(), reps);
}

std::string to_string(const integer& n) {
    std::ostringstream out;
    out << n;
    return out.str();
}

bool is_circular_prime(const integer& p) {
    if (!is_prime(p))
        return false;
    std::string str(to_string(p));
    for (size_t i = 0, n = str.size(); i + 1 < n; ++i) {
        std::rotate(str.begin(), str.begin() + 1, str.end());
        integer p2(str, 10);
        if (p2 < p || !is_prime(p2))
            return false;
    }
    return true;
}

integer next_repunit(const integer& n) {
    integer p = 1;
    while (p < n)
        p = 10 * p + 1;
    return p;
}

integer repunit(int digits) {
    std::string str(digits, '1');
    integer p(str);
    return p;
}

void test_repunit(int digits) {
    if (is_prime(repunit(digits), 10))
        std::cout << "R(" << digits << ") is probably prime\n";
    else
        std::cout << "R(" << digits << ") is not prime\n";
}

int main() {
    integer p = 2;
    std::cout << "First 19 circular primes:\n";
    for (int count = 0; count < 19; ++p) {
        if (is_circular_prime(p)) {
            if (count > 0)
                std::cout << ", ";
            std::cout << p;
            ++count;
        }
    }
    std::cout << '\n';
    std::cout << "Next 4 circular primes:\n";
    p = next_repunit(p);
    std::string str(to_string(p));
    int digits = str.size();
    for (int count = 0; count < 4; ) {
        if (is_prime(p, 15)) {
            if (count > 0)
                std::cout << ", ";
            std::cout << "R(" << digits << ")";
            ++count;
        }
        p = repunit(++digits);
    }
    std::cout << '\n';
    test_repunit(5003);
    test_repunit(9887);
    test_repunit(15073);
    test_repunit(25031);
    test_repunit(35317);
    test_repunit(49081);
    return 0;
}



Go: package main

import (
    "fmt"
    big "github.com/ncw/gmp"
    "strings"
)


func isPrime(n int) bool {
    switch {
    case n < 2:
        return false
    case n%2 == 0:
        return n == 2
    case n%3 == 0:
        return n == 3
    default:
        d := 5
        for d*d <= n {
            if n%d == 0 {
                return false
            }
            d += 2
            if n%d == 0 {
                return false
            }
            d += 4
        }
        return true
    }
}

func repunit(n int) *big.Int {
    ones := strings.Repeat("1", n)
    b, _ := new(big.Int).SetString(ones, 10)
    return b
}

var circs = []int{}


func alreadyFound(n int) bool {
    for _, i := range circs {
        if i == n {
            return true
        }
    }
    return false
}

func isCircular(n int) bool {
    nn := n
    pow := 1 
    for nn > 0 {
        pow *= 10
        nn /= 10
    }
    nn = n
    for {
        nn *= 10
        f := nn / pow 
        nn += f * (1 - pow)
        if alreadyFound(nn) {
            return false
        }
        if nn == n {
            break
        }
        if !isPrime(nn) {
            return false
        }
    }
    return true
}

func main() {
    fmt.Println("The first 19 circular primes are:")
    digits := [4]int{1, 3, 7, 9}
    q := []int{1, 2, 3, 5, 7, 9}  
    fq := []int{1, 2, 3, 5, 7, 9} 
    count := 0
    for {
        f := q[0]   
        fd := fq[0] 
        if isPrime(f) && isCircular(f) {
            circs = append(circs, f)
            count++
            if count == 19 {
                break
            }
        }
        copy(q, q[1:])   
        q = q[:len(q)-1] 
        copy(fq, fq[1:]) 
        fq = fq[:len(fq)-1]
        if f == 2 || f == 5 { 
            continue
        }
        
        
        for _, d := range digits {
            if d >= fd {
                q = append(q, f*10+d)
                fq = append(fq, fd)
            }
        }
    }
    fmt.Println(circs)
    fmt.Println("\nThe next 4 circular primes, in repunit format, are:")
    count = 0
    var rus []string
    for i := 7; count < 4; i++ {
        if repunit(i).ProbablyPrime(10) {
            count++
            rus = append(rus, fmt.Sprintf("R(%d)", i))
        }
    }
    fmt.Println(rus)
    fmt.Println("\nThe following repunits are probably circular primes:")
    for _, i := range []int{5003, 9887, 15073, 25031, 35317, 49081} {
        fmt.Printf("R(%-5d) : %t\n", i, repunit(i).ProbablyPrime(10))
    }
}