Skip to content

Commit 8391f98

Browse files
committed
new file: Math/nth_prime_power.sf
1 parent 6355194 commit 8391f98

File tree

3 files changed

+105
-1
lines changed

3 files changed

+105
-1
lines changed

Math/nth_k-powerfree.sf

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ for k in (2..5) {
5757
var s = nth_powerfree(10**n, k)
5858
assert(s.is_powerfree(k))
5959
assert_eq(k.powerfree_count(s), 10**n)
60-
#assert_eq(10**n -> nth_powerfree(k), s)
60+
assert_eq(10**n -> nth_powerfree(k), s)
6161
say "S(10^#{n}, #{k}) = #{s}"
6262
}
6363
say ''

Math/nth_prime_power.sf

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
#!/usr/bin/ruby
2+
3+
# Daniel "Trizen" Șuteu
4+
# Date: 07 July 2022
5+
# https://github.com/trizen
6+
7+
# Compute the n-th prime power, using binary search and the prime-power counting function.
8+
9+
# See also:
10+
# https://oeis.org/A143039
11+
12+
func prime_power_count_lower(n) {
13+
sum(1..n.ilog2, {|k|
14+
prime_count_lower(n.iroot(k))
15+
})
16+
}
17+
18+
func prime_power_count_upper(n) {
19+
sum(1..n.ilog2, {|k|
20+
prime_count_upper(n.iroot(k))
21+
})
22+
}
23+
24+
func nth_prime_power_lower(n) {
25+
bsearch_min(n, n.nth_prime_upper, {|k|
26+
prime_power_count_upper(k) <=> n
27+
})
28+
}
29+
30+
func nth_prime_power_upper(n) {
31+
bsearch_max(n, n.nth_prime_upper, {|k|
32+
prime_power_count_lower(k) <=> n
33+
})
34+
}
35+
36+
func nth_prime_power(n) {
37+
38+
n == 0 && return 1 # not a prime power, but...
39+
n <= 0 && return NaN
40+
n == 1 && return 2
41+
42+
var min = nth_prime_power_lower(n)
43+
var max = nth_prime_power_upper(n)
44+
45+
var k = 0
46+
var c = 0
47+
48+
loop {
49+
50+
k = (min + max)>>1
51+
c = prime_power_count(k)
52+
53+
if (abs(c - n) <= n.iroot(3)) {
54+
break
55+
}
56+
57+
given (c <=> n) {
58+
when (+1) { max = k-1 }
59+
when (-1) { min = k+1 }
60+
else { break }
61+
}
62+
}
63+
64+
while (!k.is_prime_power) {
65+
--k
66+
}
67+
68+
while (c != n) {
69+
var j = (n <=> c)
70+
k += j
71+
c += j
72+
k += j while !k.is_prime_power
73+
}
74+
75+
return k
76+
}
77+
78+
for n in (1..10) {
79+
var p = nth_prime_power(10**n)
80+
assert(p.is_prime_power)
81+
assert_eq(p.prime_power_count, 10**n)
82+
#assert_eq(10**n -> nth_prime_power, p)
83+
say "P(10^#{n}) = #{p}"
84+
}
85+
86+
assert_eq(
87+
nth_prime_power.map(1..100),
88+
100.by { .is_prime_power }
89+
)
90+
91+
__END__
92+
P(10^1) = 16
93+
P(10^2) = 419
94+
P(10^3) = 7517
95+
P(10^4) = 103511
96+
P(10^5) = 1295953
97+
P(10^6) = 15474787
98+
P(10^7) = 179390821
99+
P(10^8) = 2037968761
100+
P(10^9) = 22801415981
101+
P(10^10) = 252096675073
102+
P(10^11) = 2760723662941
103+
P(10^12) = 29996212395727

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,7 @@ A nice collection of day-to-day Sidef scripts.
424424
* [Nth composite](./Math/nth_composite.sf)
425425
* [Nth k-powerfree](./Math/nth_k-powerfree.sf)
426426
* [Nth prime](./Math/nth_prime.sf)
427+
* [Nth prime power](./Math/nth_prime_power.sf)
427428
* [Nth root good rational approximations](./Math/nth_root_good_rational_approximations.sf)
428429
* [Nth smooth number](./Math/nth_smooth_number.sf)
429430
* [Nth squarefree](./Math/nth_squarefree.sf)

0 commit comments

Comments
 (0)