#!/usr/bin/ruby
#
## https://rosettacode.org/wiki/Ludic_numbers
#
func ludics_upto(nmax=100000) {
Enumerator({ |collect|
collect(1)
var arr = @(2..nmax)
while (arr) {
collect(var n = arr[0])
arr.range.by(n).each {|i| arr[i] = nil}
arr.compact!
}
})
}
func ludics_first(n) {
ludics_upto(n * n.log2).first(n)
}
var l_f25 = ludics_first(25)
var l_c1000 = ludics_upto(1000).len
var l_2000_05 = ludics_first(2005).last(6)
say("First 25 Ludic numbers: ", l_f25.join(' '))
say("Ludics below 1000: ", l_c1000)
say("Ludic numbers 2000 to 2005: ", l_2000_05.join(' '))
assert_eq(l_f25, [1, 2, 3, 5, 7, 11, 13, 17, 23, 25, 29, 37, 41, 43, 47, 53, 61, 67, 71, 77, 83, 89, 91, 97, 107]);
assert_eq(l_c1000, 142);
assert_eq(l_2000_05, [21475, 21481, 21487, 21493, 21503, 21511]);
var a = ludics_upto(250).to_a
var l_triples = a.grep{|x| a.contains_all([x+2, x+6]) } \
.map {|x| '(' + [x, x+2, x+6].join(' ') + ')' }
say("Ludic triples below 250: ", l_triples.join(' '))
assert_eq(l_triples, [
"(1 3 7)",
"(5 7 11)",
"(11 13 17)",
"(23 25 29)",
"(41 43 47)",
"(173 175 179)",
"(221 223 227)",
"(233 235 239)"
])