Task: Find largest left truncatable prime in a given base




Go: package main

import (
    "fmt"
    "math/big"
)

var smallPrimes = [...]int{2, 3, 5, 7, 11, 13, 17, 19, 23, 29}

const maxStack = 128

var (
    tens, values    [maxStack]big.Int
    bigTemp, answer = new(big.Int), new(big.Int)
    base, seenDepth int
)

func addDigit(i int) {
    for d := 1; d < base; d++ {
        values[i].Set(&values[i-1])
        bigTemp.SetUint64(uint64(d))
        bigTemp.Mul(bigTemp, &tens[i])
        values[i].Add(&values[i], bigTemp)
        if !values[i].ProbablyPrime(0) {
            continue
        }
        if i > seenDepth || (i == seenDepth && values[i].Cmp(answer) == 1) {
            if !values[i].ProbablyPrime(0) {
                continue
            }
            answer.Set(&values[i])
            seenDepth = i
        }
        addDigit(i + 1)
    }
}

func doBase() {
    answer.SetUint64(0)
    tens[0].SetUint64(1)
    bigTemp.SetUint64(uint64(base))
    seenDepth = 0
    for i := 1; i < maxStack; i++ {
        tens[i].Mul(&tens[i-1], bigTemp)
    }
    for i := 0; smallPrimes[i] < base; i++ {
        values[0].SetUint64(uint64(smallPrimes[i]))
        addDigit(1)
    }
    fmt.Printf("%2d: %s\n", base, answer.String())
}

func main() {
    for base = 3; base <= 17; base++ {
        doBase()
    }
}


Java: import java.math.BigInteger;
import java.util.*;

class LeftTruncatablePrime
{
  private static List<BigInteger> getNextLeftTruncatablePrimes(BigInteger n, int radix, int millerRabinCertainty)
  {
    List<BigInteger> probablePrimes = new ArrayList<BigInteger>();
    String baseString = n.equals(BigInteger.ZERO) ? "" : n.toString(radix);
    for (int i = 1; i < radix; i++)
    {
      BigInteger p = new BigInteger(Integer.toString(i, radix) + baseString, radix);
      if (p.isProbablePrime(millerRabinCertainty))
        probablePrimes.add(p);
    }
    return probablePrimes;
  }
  
  public static BigInteger getLargestLeftTruncatablePrime(int radix, int millerRabinCertainty)
  {
    List<BigInteger> lastList = null;
    List<BigInteger> list = getNextLeftTruncatablePrimes(BigInteger.ZERO, radix, millerRabinCertainty);
    while (!list.isEmpty())
    {
      lastList = list;
      list = new ArrayList<BigInteger>();
      for (BigInteger n : lastList)
        list.addAll(getNextLeftTruncatablePrimes(n, radix, millerRabinCertainty));
    }
    if (lastList == null)
      return null;
    Collections.sort(lastList);
    return lastList.get(lastList.size() - 1);
  }
  
  public static void main(String[] args)
  {
    if (args.length != 2) {
      System.err.println("There must be exactly two command line arguments.");
      return;
    }
    int maxRadix;
    try {
      maxRadix = Integer.parseInt(args[0]);
      if (maxRadix < 3) throw new NumberFormatException(); 
    } catch (NumberFormatException e) {
      System.err.println("Radix must be an integer greater than 2.");
      return;
    }
    int millerRabinCertainty;
    try {
      millerRabinCertainty = Integer.parseInt(args[1]);
    } catch (NumberFormatException e) {
      System.err.println("Miiller-Rabin Certainty must be an integer.");
      return;
    }  
    for (int radix = 3; radix <= maxRadix; radix++)
    {
      BigInteger largest = getLargestLeftTruncatablePrime(radix, millerRabinCertainty);
      System.out.print("n=" + radix + ": ");
      if (largest == null)
        System.out.println("No left-truncatable prime");
      else
        System.out.println(largest + " (in base " + radix + "): " + largest.toString(radix));
    }
  }
  
}