Powerful numbers: Difference between revisions

Content added Content deleted
Line 412: Line 412:
9-powerful numbers <= 10ⁿ (where n == 0 through 18): 1, 1, 1, 2, 6, 11, 16, 24, 38, 59, 94, 145, 217, 317, 453, 644, 919, 1308, 1868
9-powerful numbers <= 10ⁿ (where n == 0 through 18): 1, 1, 1, 2, 6, 11, 16, 24, 38, 59, 94, 145, 217, 317, 453, 644, 919, 1308, 1868
10-powerful numbers <= 10ⁿ (where n == 0 through 19): 1, 1, 1, 1, 5, 9, 14, 21, 28, 43, 68, 104, 155, 227, 322, 447, 621, 858, 1192, 1651</pre>
10-powerful numbers <= 10ⁿ (where n == 0 through 19): 1, 1, 1, 1, 5, 9, 14, 21, 28, 43, 68, 104, 155, 227, 322, 447, 621, 858, 1192, 1651</pre>

=={{header|Phix}}==
{{libheader|mpfr}}
===priority queue===
Tried a slightly different approach, but it gets 7/10 at best on performance.
<lang Phix>include mpfr.e

integer pq = NULL -- data is the prime powers, eg {2,2} for 2^2*3^2
-- priority is the mpz of that, eg/ie 36

procedure padd(mpz n, np, sequence s)
if pq=NULL then
pq = pq_new(MIN_HEAP,routine_id("mpz_cmp"))
end if
if mpz_cmp(np,n)<=0 then
pq_add({s,mpz_init_set(np)},pq)
end if
end procedure

procedure add_next(integer k, mpz n, p, sequence s)
mpz np = mpz_init()
integer l = length(s)
for i=1 to l do
integer ki = iff(s[i]=0?k:1)
mpz_ui_pow_ui(np,get_prime(i),ki)
mpz_mul(np,np,p)
s[i] += ki
padd(n,np,s)
s[i] -= ki
end for
mpz_ui_pow_ui(np,get_prime(l+1),k)
if l>0 and s[l]=k and s[1..l-1]==repeat(0,l-1) then
padd(n,np,0&s)
elsif s={} then
mpz_mul(np,np,p)
padd(n,np,s&k)
end if
end procedure

function powerful(integer k, mpz n)
mpz prevp = mpz_init(1)
sequence res = {prevp}
add_next(k,n,prevp,{})
while pq_size(pq) do
{sequence s, mpz p} = pq_pop(pq)
if mpz_cmp(p,prevp)!=0 then
res &= p
add_next(k,n,p,s)
prevp = p
end if
end while
return res
end function
mpz p = mpz_init(10)
for k=2 to 10 do
mpz_mul_si(p,p,10)
sequence s = powerful(k,p)
integer l = length(s)
for i=1 to 5 do
s[i] = mpz_get_str(s[i])
s[-i] = mpz_get_str(s[-i])
end for
s[6..-6] = {"..."}
s = join(s,",")
printf(1,"%d %2d-powerful numbers <= 10^%-2d : %s\n",{l,k,k,s})
end for

puts(1,"\n")
--Not really fast enough, so only doing to k+5..k+8 for the first 4, but k+9 for last 5
for k=2 to 10 do
sequence counts = {}
integer lim = k+min(k+3,9)
mpz_set_si(p,1)
for j=0 to lim do
printf(1,"counting (%d/%d)...\r",{j,lim})
counts &= length(powerful(k,p))
mpz_mul_si(p,p,10)
end for
printf(1,"Counts of %2d-powerful numbers <= 10^(0..%d) : %v\n",{k,lim,counts})
end for</lang>
{{out}}
<pre>
14 2-powerful numbers <= 10^2 : 1,4,8,9,16,...,49,64,72,81,100
20 3-powerful numbers <= 10^3 : 1,8,16,27,32,...,625,648,729,864,1000
25 4-powerful numbers <= 10^4 : 1,16,32,64,81,...,5184,6561,7776,8192,10000
32 5-powerful numbers <= 10^5 : 1,32,64,128,243,...,65536,69984,78125,93312,100000
38 6-powerful numbers <= 10^6 : 1,64,128,256,512,...,559872,746496,823543,839808,1000000
46 7-powerful numbers <= 10^7 : 1,128,256,512,1024,...,7558272,8388608,8957952,9765625,10000000
52 8-powerful numbers <= 10^8 : 1,256,512,1024,2048,...,60466176,67108864,80621568,90699264,100000000
59 9-powerful numbers <= 10^9 : 1,512,1024,2048,4096,...,644972544,725594112,816293376,967458816,1000000000
68 10-powerful numbers <= 10^10 : 1,1024,2048,4096,8192,...,7739670528,8589934592,8707129344,9795520512,10000000000

Counts of 2-powerful numbers <= 10^(0..7) : {1,4,14,54,185,619,2027,6553}
Counts of 3-powerful numbers <= 10^(0..9) : {1,2,7,20,51,129,307,713,1645,3721}
Counts of 4-powerful numbers <= 10^(0..11) : {1,1,5,11,25,57,117,235,464,906,1741,3312}
Counts of 5-powerful numbers <= 10^(0..13) : {1,1,3,8,16,32,63,117,211,375,659,1153,2000,3402}
Counts of 6-powerful numbers <= 10^(0..15) : {1,1,2,6,12,21,38,70,121,206,335,551,900,1451,2326,3706}
Counts of 7-powerful numbers <= 10^(0..16) : {1,1,1,4,10,16,26,46,77,129,204,318,495,761,1172,1799,2740}
Counts of 8-powerful numbers <= 10^(0..17) : {1,1,1,3,8,13,19,32,52,85,135,211,315,467,689,1016,1496,2191}
Counts of 9-powerful numbers <= 10^(0..18) : {1,1,1,2,6,11,16,24,38,59,94,145,217,317,453,644,919,1308,1868}
Counts of 10-powerful numbers <= 10^(0..19) : {1,1,1,1,5,9,14,21,28,43,68,104,155,227,322,447,621,858,1192,1651}
</pre>
===translation===
{{trans|Go}} {{trans|Sidef}}
Significantly faster. The last few counts were wrong when using native ints/atoms, so I went gmp, which means it also works on 32-bit.
<lang Phix>include mpfr.e
function powerful(mpz n, integer k, sequence res={}, mpz m=NULL, integer r=0)
if m=NULL then
m = mpz_init(1)
r = 2*k-1
end if
if r<k then
res = append(res,iff(mpz_fits_atom(m)?mpz_get_atom(m):mpz_get_str(m)))
else
mpz t = mpz_init()
mpz_fdiv_q(t, n, m) -- t := floor(n/m)
{} = mpz_root(t,t,r) -- t = floor(rth root of t)
if not mpz_fits_integer(t) then ?9/0 end if
integer lim = mpz_get_integer(t)
for v=1 to lim do
if r<=k
or (square_free(v) and mpz_gcd_ui(NULL,m,v)=1) then
mpz_ui_pow_ui(t,v,r) -- t:= v^r
mpz_mul(t,t,m) -- t*= m
res = powerful(n, k, res, t, r-1)
end if
end for
end if
return res
end function

function powercount(mpz n, integer k, mpz m=NULL, integer r=0)
atom res = 0
if m=NULL then
m = mpz_init(1)
r = 2*k-1
end if
mpz t = mpz_init()
mpz_fdiv_q(t, n, m) -- t := floor(n/m)
{} = mpz_root(t,t,r) -- t = floor(rth root of t)
if not mpz_fits_integer(t) then ?9/0 end if
integer lim = mpz_get_integer(t)
if r<=k then
res += lim
else
for v=1 to lim do
if square_free(v) and mpz_gcd_ui(NULL,m,v)=1 then
mpz_ui_pow_ui(t,v,r) -- t:= v^r
mpz_mul(t,t,m) -- t*= m
res += powercount(n, k, t, r-1)
end if
end for
end if
return res
end function
atom t0 = time()
mpz p = mpz_init(10)
for k=2 to 10 do
mpz_mul_si(p,p,10)
sequence s = sort(powerful(p, k))
integer l = length(s)
s[6..-6] = {"..."}
s = ppf(s,{pp_FltFmt,"%d",pp_StrFmt,-1,pp_IntCh,false,pp_Maxlen,100})
printf(1,"%d %2d-powerful numbers <= 10^%-2d : %s\n",{l,k,k,s})
end for
puts(1,"\n")
for k=2 to 10 do
mpz_set_si(p,1)
sequence counts = {}
for j=0 to k+9 do
counts = append(counts, powercount(p, k))
mpz_mul_si(p,p,10)
end for
printf(1,"Counts of %2d-powerful numbers <= 10^(0..%d) : %v\n",{k,k+9,counts})
end for
?elapsed(time()-t0)</lang>
{{out}}
<pre>
14 2-powerful numbers <= 10^2 : {1,4,8,9,16, ..., 49,64,72,81,100}
20 3-powerful numbers <= 10^3 : {1,8,16,27,32, ..., 625,648,729,864,1000}
25 4-powerful numbers <= 10^4 : {1,16,32,64,81, ..., 5184,6561,7776,8192,10000}
32 5-powerful numbers <= 10^5 : {1,32,64,128,243, ..., 65536,69984,78125,93312,100000}
38 6-powerful numbers <= 10^6 : {1,64,128,256,512, ..., 559872,746496,823543,839808,1000000}
46 7-powerful numbers <= 10^7 : {1,128,256,512,1024, ..., 7558272,8388608,8957952,9765625,10000000}
52 8-powerful numbers <= 10^8 : {1,256,512,1024,2048, ..., 60466176,67108864,80621568,90699264,100000000}
59 9-powerful numbers <= 10^9 : {1,512,1024,2048,4096, ..., 644972544,725594112,816293376,967458816,1000000000}
68 10-powerful numbers <= 10^10 : {1,1024,2048,4096,8192, ..., 7739670528,8589934592,8707129344,9795520512,10000000000}

Counts of 2-powerful numbers <= 10^(0..11) : {1,4,14,54,185,619,2027,6553,21044,67231,214122,680330}
Counts of 3-powerful numbers <= 10^(0..12) : {1,2,7,20,51,129,307,713,1645,3721,8348,18589,41136}
Counts of 4-powerful numbers <= 10^(0..13) : {1,1,5,11,25,57,117,235,464,906,1741,3312,6236,11654}
Counts of 5-powerful numbers <= 10^(0..14) : {1,1,3,8,16,32,63,117,211,375,659,1153,2000,3402,5770}
Counts of 6-powerful numbers <= 10^(0..15) : {1,1,2,6,12,21,38,70,121,206,335,551,900,1451,2326,3706}
Counts of 7-powerful numbers <= 10^(0..16) : {1,1,1,4,10,16,26,46,77,129,204,318,495,761,1172,1799,2740}
Counts of 8-powerful numbers <= 10^(0..17) : {1,1,1,3,8,13,19,32,52,85,135,211,315,467,689,1016,1496,2191}
Counts of 9-powerful numbers <= 10^(0..18) : {1,1,1,2,6,11,16,24,38,59,94,145,217,317,453,644,919,1308,1868}
Counts of 10-powerful numbers <= 10^(0..19) : {1,1,1,1,5,9,14,21,28,43,68,104,155,227,322,447,621,858,1192,1651}
"0.8s"
</pre>


=={{header|Sidef}}==
=={{header|Sidef}}==