Brilliant numbers are a subset of semiprime numbers. Specifically, they are numbers that are the product of exactly two prime numbers that both have the same number of digits when expressed in base 10.

Brilliant numbers are useful in cryptography and when testing prime factoring algorithms.



E.G.
 3 × 3 (9) is a brilliant number. 
 2 × 7 (14) is a brilliant number.
 113 × 691 (78083) is a brilliant number.
 2 × 31 (62) is semiprime, but is not a brilliant number (different number of digits in the two factors).


Task
 Find and display the first 100 brilliant numbers.
 For the orders of magnitude 1 through 6, find and show the first brilliant number greater than or equal to the order of magnitude, and, its position in the series (or the count of brilliant numbers up to that point).


Stretch
 Continue for larger orders of magnitude.


See also
 Numbers Aplenty - Brilliant numbers
 OEIS:A078972 - Brilliant numbers: semiprimes whose prime factors have the same number of decimal digits


import "./math" for Int
import "./seq" for Lst
import "./fmt" for Fmt
 
var primes = Int.primeSieve(1e7-1)
 
var getBrilliant = Fn.new { |digits, limit, countOnly|
    var brilliant = []
    var count = 0
    var pow = 1
    var next = Num.maxSafeInteger
    for (k in 1..digits) {
        var s = primes.where { |p| p > pow && p < pow * 10 }.toList
        for (i in 0...s.count) {
            for (j in i...s.count) {
                var prod = s[i] * s[j]
                if (prod < limit) {
                    if (countOnly) {
                        count = count + 1
                    } else {
                        brilliant.add(prod)
                    }
                } else {
                    next = next.min(prod)
                    break
                }
            }
        }
        pow = pow * 10
    }
    return countOnly ? [count, next] : [brilliant, next]
}
 
System.print("First 100 brilliant numbers:")
var brilliant = getBrilliant.call(2, 10000, false)[0]
brilliant.sort()
brilliant = brilliant[0..99]
for (chunk in Lst.chunks(brilliant, 10)) Fmt.print("$4d", chunk)
System.print()
for (k in 1..12) {
    var limit = 10.pow(k)
    var res = getBrilliant.call(k, limit, true)
    var total = res[0]
    var next = res[1]
    Fmt.print("First >= $,17d is $,15r in the series: $,17d", limit, total + 1, next)
}