(function prime-sieve search siever sieved (return-when (empty? siever) (.. vec sieved search)) (let [p ps] ((juxt 0 (skip 1)) siever)) (recur (remove #(div? % p) search) (remove #(div? % p) ps) (append p sieved))) (function primes n (prime-sieve (range 2 (inc n)) (range 2 (ceil (sqrt n))) [])) (function decompose n ps factors (return-when (= n 1) factors) (let div (find (div? n) ps)) (recur (/ n div) ps (append div factors))) (function almost-prime up-to n k (return-when (zero? up-to) []) (let ps (primes n)) (if (= k (len (decompose n ps []))) (prepend n (almost-prime (dec up-to) (inc n) k)) (almost-prime up-to (inc n) k))) (function row n (-> n @(almost-prime 10 1) (join " ") @(str n (match n 1 "st" 2 "nd" 3 "rd" "th") " almost-primes: " ))) (join "\n" (map row (range 1 6)))