Blum integer

Takes about 30 seconds:

func blum_integers(upto) {

    var L = []
    var P = idiv(upto, 3).primes.grep{ .is_congruent(3, 4) }

    for i in (1..P.end) {
        var p = P[i]
        for j in (^i) {
            var t = p*P[j]
            break if (t > upto)
            L << t
        }
    }

    L.sort
}

func blum_first(n) {
    var upto = int(4.5*n*log(n) / log(log(n)))
    loop {
        var B = blum_integers(upto)
        if (B.len >= n) {
            return B.first(n)
        }
        upto *= 2
    }
}

with (50) {|n|
    say "The first #{n} Blum integers:"
    blum_first(n).slices(10).each { .map{ "%4s" % _ }.join.say }
}

say ''

for n in (26828, 1e5, 2e5, 3e5, 4e5) {
    var B = blum_first(n)
    say "#{n.commify}th Blum integer: #{B.last}"

    if (n == 4e5) {
        say ''
        for k in (1,3,7,9) {
            var T = B.grep { .is_congruent(k, 10) }
            say "#{k}: #{'%6s' % T.len} (#{T.len / B.len * 100}%)"
        }
    }
}

Output:

Last updated

Was this helpful?