-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathexponential_divisors.sf
74 lines (58 loc) · 1.56 KB
/
exponential_divisors.sf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#!/usr/bin/ruby
# Generate the exponential divisors (or e-divisors) of n.
# See also:
# https://oeis.org/A051377
# https://oeis.org/A322791
func exponential_divisors(n) {
return [1] if (n == 1)
var f = n.factor_exp
var D = f.map {.tail.divisors}
var L = []
D.map {|d| ^d }.cartesian {|*a|
L << f.prod_kv {|j,pp|
pp[0]**D[j][a[j]]
}
}
return L.sort
}
func exponential_divisors_2(n) { # faster algorithm
var d = [1]
for p,e in (n.factor_exp) {
d = gather {
for k in (e.divisors) {
take(with(p**k){|r| d.map {|u| u*r }... })
}
}
}
return d.sort
}
for n in (1..20) {
say "e-divisors of #{n} = #{exponential_divisors(n)}"
assert_eq(exponential_divisors(n).len, n.esigma0)
assert_eq(exponential_divisors(n).sum, n.esigma)
assert_eq(exponential_divisors(n), n.edivisors)
assert_eq(exponential_divisors_2(n).len, n.esigma0)
assert_eq(exponential_divisors_2(n).sum, n.esigma)
assert_eq(exponential_divisors_2(n), n.edivisors)
}
__END__
e-divisors of 1 = [1]
e-divisors of 2 = [2]
e-divisors of 3 = [3]
e-divisors of 4 = [2, 4]
e-divisors of 5 = [5]
e-divisors of 6 = [6]
e-divisors of 7 = [7]
e-divisors of 8 = [2, 8]
e-divisors of 9 = [3, 9]
e-divisors of 10 = [10]
e-divisors of 11 = [11]
e-divisors of 12 = [6, 12]
e-divisors of 13 = [13]
e-divisors of 14 = [14]
e-divisors of 15 = [15]
e-divisors of 16 = [2, 4, 16]
e-divisors of 17 = [17]
e-divisors of 18 = [6, 18]
e-divisors of 19 = [19]
e-divisors of 20 = [10, 20]