Special factorials: Difference between revisions

Line 191:
3628800 10
119 nothing
</pre>
 
=={{header|Phix}}==
{{libheader|mpfr}}
Rather than leave this as four somewhat disjoint tasks with quite a bit of repetition, I commoned-up init/loop/print into test(),
which means sf/H/af/ef aren't usable independently as-is, but reconstitution should be easy enough
(along with somewhat saner and thread-safe routine-local vars).
<lang Phix>include mpfr.e
 
mpz {r,fn} = mpz_inits(2) -- res, scratch var
 
procedure sf(integer i)
mpz_fac_ui(fn, i)
mpz_mul(r,r,fn)
end procedure
procedure H(integer i)
mpz_ui_pow_ui(fn, i, i)
mpz_mul(r,r,fn)
end procedure
 
integer sgn = 0
procedure af(integer i)
mpz_fac_ui(fn, i)
mpz_mul_si(fn,fn,sgn)
sgn *= -1
mpz_add(r,r,fn)
end procedure
 
procedure ef(integer i)
integer e = mpz_get_integer(r)
mpz_set_si(r,i)
mpz_pow_ui(r, r, e)
end procedure
 
procedure test(string fmt, integer fn, init=1, m=9)
sequence res = {}
for n=0 to m do
mpz_set_si(r,init)
sgn = iff(and_bits(n,1)?1:-1) -- (af only)
for i=1 to n do
fn(i) -- or papply(tagset(n),fn)
end for
res = append(res,mpz_get_str(r))
end for
printf(1,fmt,{join(res)})
end procedure
test("First 10 superfactorials: %s\n",sf)
test("First 10 hyperfactorials: %s\n",H)
test("First 10 alternating factorials: %s\n",af,0)
test("First 5 exponential factorials: %s\n",ef,1,4)
ef(5) -- (nb now only works because ef(4) was just called)
printf(1,"Number of digits in 5$: %,d\n",mpz_sizeinbase(r,10))
 
function rf(integer n)
if n=1 then return "0" end if
integer fac = 1, i = 1
while fac<n do
fac *= i
if fac=n then return sprint(i) end if
i += 1
end while
return "undefined"
end function
printf(1,"Reverse factorials: %s\n",{join(apply({1,2,6,24,120,720,5040,40320,362880,3628800,119},rf))})</lang>
{{out}}
<pre>
First 10 superfactorials: 1 1 2 12 288 34560 24883200 125411328000 5056584744960000 1834933472251084800000
First 10 hyperfactorials: 1 1 4 108 27648 86400000 4031078400000 3319766398771200000 55696437941726556979200000 21577941222941856209168026828800000
First 10 alternating factorials: 0 1 1 5 19 101 619 4421 35899 326981
First 5 exponential factorials: 1 1 2 9 262144
Number of digits in 5$: 183,231
Reverse factorials: 0 2 3 4 5 6 7 8 9 10 undefined
</pre>
 
7,794

edits