RosettaCodeData/Task/Weird-numbers/YAMLScript/weird-numbers.ys

49 lines
1.1 KiB
Plaintext

!YS-v0
defn main(max=16500):
weird =: sieve(max)
numbers =:
filter \(nth weird _): range(2 max 2)
say: |
The first $(numbers.#) weird numbers:
$(numbers:joins)
defn sieve(limit):
weirds =: into([] repeat(limit true))
loop i 2, weirds weirds:
if i < limit:
recur (i + 2):
or _ weirds:
when weirds.$i:
divs =: divisors(i)
if abundant(i divs):
when semiperfect(i divs):
loop j i, weirds weirds:
if j < limit:
recur (j + i):
weirds.assoc(j false)
else: weirds
weirds: .assoc(i false)
else: weirds
defn divisors(number):
divisors =:
mapcat _ range(1 sqrt(number)):
fn(n):
when 0 == (number % n):
V+: n (number / n)
divisors: .distinct().sort(gt _):rest
defn abundant(n divs):
sum(divs) > n
defn semiperfect(n divs):
when divs.# > 0:
div *divs =: divs
if n < div:
semiperfect: n divs
or:
n ==: div
semiperfect: (n - div) divs
semiperfect: n divs