Special factorials: Difference between revisions

 
(6 intermediate revisions by 6 users not shown)
Line 318:
rf(3628800) = 10
rf(119) = null</pre>
 
=={{header|Bruijn}}==
 
Implementation for numbers encoded in balanced ternary using Mixfix syntax defined in the Math module:
 
<syntaxhighlight lang="bruijn">
:import std/Combinator .
:import std/List .
:import std/Math .
 
factorial [∏ (+1) → 0 | [0]]
 
superfactorial [∏ (+1) → 0 | factorial]
 
hyperfactorial [∏ (+1) → 0 | [0 ** 0]]
 
alternating-factorial y [[=?0 0 ((factorial 0) - (1 --0))]]
 
exponential-factorial y [[=?0 0 (0 ** (1 --0))]]
 
:test ((factorial (+4)) =? (+24)) ([[1]])
:test ((superfactorial (+4)) =? (+288)) ([[1]])
:test ((hyperfactorial (+4)) =? (+27648)) ([[1]])
:test ((alternating-factorial (+3)) =? (+5)) ([[1]])
:test ((exponential-factorial (+4)) =? (+262144)) ([[1]])
 
invfac y [[[compare-case 1 (2 ++1 0) (-1) 0 (∏ (+0) → --1 | ++‣)]]] (+0)
 
:test ((invfac (+1)) =? (+0)) ([[1]])
:test ((invfac (+2)) =? (+2)) ([[1]])
:test ((invfac (+6)) =? (+3)) ([[1]])
:test ((invfac (+24)) =? (+4)) ([[1]])
:test ((invfac (+120)) =? (+5)) ([[1]])
:test ((invfac (+720)) =? (+6)) ([[1]])
:test ((invfac (+5040)) =? (+7)) ([[1]])
:test ((invfac (+40320)) =? (+8)) ([[1]])
:test ((invfac (+362880)) =? (+9)) ([[1]])
:test ((invfac (+3628800)) =? (+10)) ([[1]])
:test ((invfac (+119)) =? (-1)) ([[1]])
 
seq-a [((superfactorial 0) : ((hyperfactorial 0) : {}(alternating-factorial 0)))] <$> (iterate ++‣ (+0))
 
seq-b exponential-factorial <$> (iterate ++‣ (+0))
 
# return first 10/4 elements of both sequences
main [(take (+10) seq-a) : {}(take (+5) seq-b)]
</syntaxhighlight>
 
=={{header|C}}==
Line 1,585 ⟶ 1,632:
Reverse factorials: 0 2 3 4 5 6 7 8 9 10 undefined
</pre>
 
=={{header|PureBasic}}==
{{trans|FreeBASIC}}
<syntaxhighlight lang="purebasic">Procedure.q factorial(n.i)
If n < 2
ProcedureReturn 1
Else
ProcedureReturn n * Factorial(n - 1)
EndIf
EndProcedure
 
Procedure.q sf(n.i)
p.i = 1
For k.i = 1 To n
p = p * factorial(k)
Next k
ProcedureReturn p
EndProcedure
 
Procedure.q H(n.i)
p.i = 1
For k.i = 1 To n
p = p * Pow(k, k)
Next k
ProcedureReturn p
EndProcedure
 
Procedure.q af(n.i)
s.i = 0
For i.i = 1 To n
s = s + Pow((-1), (n-i)) * factorial(i)
Next i
ProcedureReturn s
EndProcedure
 
Procedure.q ef(n.i)
If n < 2
ProcedureReturn 1
Else
ProcedureReturn Pow(n, ef(n-1))
EndIf
EndProcedure
 
Procedure.i rf(n.i)
r.i = 0
While #True
rr.i = factorial(r)
If rr > n : ProcedureReturn -1 : EndIf
If rr = n : ProcedureReturn r : EndIf
r + 1
Wend
EndProcedure
 
OpenConsole()
PrintN("First 8 ...")
PrintN(" superfactorials hyperfactorials alternating factorials")
For n.i = 0 To 7 ;con 8 o más necesitaríamos BigInt
PrintN(RSet(Str(sf(n)),16) + " " + RSet(Str(H(n)),19) + " " + RSet(Str(af(n)),19))
Next n
 
PrintN(#CRLF$ + #CRLF$ + "First 5 exponential factorials:")
For n.i = 0 To 4
Print(Str(ef(n)) + " ")
Next n
 
PrintN(#CRLF$ + #CRLF$ + "Reverse factorials:")
For n.i = 1 To 10
PrintN(RSet(Str(rf(factorial(n))),2) + " <- rf(" + Str(factorial(n)) + ")")
Next n
PrintN(RSet(Str(rf(factorial(119))),2) + " <- rf(119)")
 
PrintN(#CRLF$ + "Press ENTER to exit"): Input()
CloseConsole()</syntaxhighlight>
 
=={{header|Python}}==
Line 1,661 ⟶ 1,781:
rf(119) : undefined
</pre>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="Quackery">
[ 1 & ] is odd ( n --> b )
 
[ 1 swap
[ 10 / dup 0 > while
dip 1+ again ]
drop ] is digitcount ( n --> n )
 
[ 1 1 rot times
[ i^ 1+ *
tuck * swap ]
drop ] is s! ( n --> n )
 
[ 1 swap times
[ i^ 1+ dup ** * ] ] is h! ( n --> n )
 
[ 0 1 rot times
[ i^ 1+ * tuck
i odd iff - else +
swap ]
drop ] is a! ( n --> n )
 
[ dup 0 = if done
dup 1 - recurse ** ] is **! ( n --> n )
 
[ this ] is undefined ( --> t )
 
[ dup 1 = iff
[ drop 0 ] done
1 swap
[ over /mod 0 != iff
[ drop undefined
swap ]
done
dip 1+
dup 1 = until
dip [ 1 - ] ]
drop ] is i! ( n --> n )
 
 
say "Superfactorials:" sp
10 times [ i^ s! echo sp ]
cr cr
say "Hyperfactorials:" sp
10 times [ i^ h! echo sp ]
cr cr
say "Alternating factorials: "
10 times [ i^ a! echo sp ]
cr cr
say "Exponential factorials: "
5 times [ i^ **! echo sp ]
cr cr
say "Number of digits in $5: "
5 **! digitcount echo
cr cr
say "Inverse factorials: "
' [ 1 2 6 24 119 120 720 5040
40320 362880 3628800 ]
witheach [ i! echo sp ]</syntaxhighlight>
 
{{out}}
 
<pre>Superfactorials: 1 1 2 12 288 34560 24883200 125411328000 5056584744960000 1834933472251084800000
 
Hyperfactorials: 1 1 4 108 27648 86400000 4031078400000 3319766398771200000 55696437941726556979200000 21577941222941856209168026828800000
 
Alternating factorials: 0 1 1 5 19 101 619 4421 35899 326981
 
Exponential factorials: 0 1 2 9 262144
 
Number of digits in $5: 183231
 
Inverse factorials: 0 2 3 4 undefined 5 6 7 8 9 10
</pre>
 
=={{header|Raku}}==
<syntaxhighlight lang="raku" line>sub postfix:<!> ($n) { [*] 1 .. $n }
Line 1,693 ⟶ 1,891:
 
=={{header|REXX}}==
<syntaxhighlight lang="rexx">/*REXX program to compute some special factorials: superfactorials, hyperfactorials,*/
/* REXX program to calculate Special factorials */
/*───────────────────────────────────── alternating factorials, exponential factorials.*/
numeric digits 1000 /*allows humongous results to be shown.*/
call hdr 'super'; do j=0 to 9; $= $ sf(j); end; call tell
call hdr 'hyper'; do j=0 to 9; $= $ hf(j); end; call tell
call hdr 'alternating '; do j=0 to 9; $= $ af(j); end; call tell
call hdr 'exponential '; do j=0 to 5; $= $ ef(j); end; call tell
@= 'the number of decimal digits in the exponential factorial of '
say @ 5 " is:"; $= ' 'commas( efn( ef(5) ) ); call tell
@= 'the inverse factorial of'
do j=1 for 10; say @ right(!(j), 8) " is: " rf(!(j))
end /*j*/
say @ right(119, 8) " is: " rf(119)
exit 0 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
!: procedure; parse arg x; != 1; do #=2 to x; != ! * #; end; return !
af: procedure; parse arg x; if x==0 then return 0; prev= 0; call af!; return !
af!: do #=1 for x; != !(#) - prev; prev= !; end; return !
commas: parse arg ?; do jc=length(?)-3 to 1 by -3; ?=insert(',', ?, jc); end; return ?
ef: procedure; parse arg x; if x==0 | x==1 then return 1; return x**ef(x-1)
efn: procedure; parse arg x; numeric digits 9; x= x; parse var x 'E' d; return d+1
sf: procedure; parse arg x; != 1; do #=2 to x; != ! * !(#); end; return !
hf: procedure; parse arg x; != 1; do #=2 to x; != ! * #**#; end; return !
rf: procedure; parse arg x; do #=0 until f>=x; f=!(#); end; return rfr()
rfr: if x==f then return #; ?= 'undefined'; return ?
hdr: parse arg ?,,$; say 'the first ten '?"factorials:"; return
tell: say substr($, 2); say; $=; return</syntaxhighlight>
{{out|output|text=&nbsp; when using the internal default input:}}
<pre>
the first 10 superfactorials:
1 1 2 12 288 34560 24883200 125411328000 5056584744960000 1834933472251084800000
 
numeric digits 35
the first 10 hyperfactorials:
1 1 4 108 27648 86400000 4031078400000 3319766398771200000 55696437941726556979200000 21577941222941856209168026828800000
 
line = "superfactorials 0-9: "
the first 10 alternating factorials:
do n = 0 to 9
0 1 1 5 19 101 619 4421 35899 326981
line = line superfactorial(n)
end
say line
 
line = "hyperfactorials 0-9: "
the first 5 exponential factorials:
1do 1n 2= 90 262144to 9
line = line hyperfactorial(n)
end
say line
 
line = "alternating factorials 0-9:"
the number of decimal digits in the exponential factorial of 5 is:
do n = 0 to 9
183,231
line = line alternatingfactorial(n)
end
say line
 
line = "exponential factorials 0-4:"
the inverse factorial of 1 is: 0
do n = 0 to 4
the inverse factorial of 2 is: 2
line = line exponentialfactorial(n)
the inverse factorial of 6 is: 3
end
the inverse factorial of 24 is: 4
say line
the inverse factorial of 120 is: 5
 
the inverse factorial of 720 is: 6
thesay inverse"exponential factorial of5: 5040 is: 7",
length(format(exponentialfactorial(5), , , 0)) "digits"
the inverse factorial of 40320 is: 8
 
the inverse factorial of 362880 is: 9
theline = "inverse factorialfactorials: of 3628800 is: 10"
numbers = "1 2 6 24 120 720 5040 40320 362880 3628800 119"
the inverse factorial of 119 is: undefined
do i = 1 to words(numbers)
line = line inversefactorial(word(numbers,i))
end
say line
 
return
 
 
superfactorial: procedure
parse arg n
sf = 1
f = 1
do k = 1 to n
f = f * k
sf = sf * f
end
return sf
 
hyperfactorial: procedure
parse arg n
hf = 1
do k = 1 to n
hf = hf * k ** k
end
return hf
 
alternatingfactorial: procedure
parse arg n
af = 0
f = 1
do i = 1 to n
f = f * i
af = af + (-1) ** (n - i) * f
end
return af
 
exponentialfactorial: procedure
parse arg n
ef = 1
do i = 1 to n
ef = i ** ef
end
return ef
 
inversefactorial: procedure
parse arg f
n = 1
do i = 2 while n < f
n = n * i
end
if n = f then
if i > 2 then
return i - 1
else
return 0
else
return "undefined"
</syntaxhighlight>
{{out}}
<pre>
superfactorials 0-9: 1 1 2 12 288 34560 24883200 125411328000 5056584744960000 1834933472251084800000
hyperfactorials 0-9: 1 1 4 108 27648 86400000 4031078400000 3319766398771200000 55696437941726556979200000 21577941222941856209168026828800000
alternating factorials 0-9: 0 1 1 5 19 101 619 4421 35899 326981
exponential factorials 0-4: 1 1 2 9 262144
exponential factorial 5: 183231 digits
inverse factorials: 0 2 3 4 5 6 7 8 9 10 undefined
</pre>
 
=={{header|RPL}}==
Super factorial:
≪ 1 1 ROT '''FOR''' j j FACT * '''NEXT'''
≫ '<span style="color:blue">SFACT</span>' STO
Hyper factorial:
≪ 1 1 ROT '''FOR''' j j DUP ^ * '''NEXT'''
≫ '<span style="color:blue">HFACT</span>' STO
Alternating factorial:
≪ → n
≪ 0 '''IF''' n '''THEN'''
1 n '''FOR''' j -1 n j - ^ j FACT * + '''NEXT'''
≫ ≫ '<span style="color:blue">AFACT</span>' STO
Exponential factorial:
≪ '''IF''' DUP '''THEN'''
DUP 1 - 1 '''FOR''' j j ^ -1 '''STEP'''
'''ELSE''' NOT '''END'''
≫ '<span style="color:blue">EFACT</span>' STO
Inverse factorial - this function actually inverses Gamma(x+1), so its result is always defined:
≪ 'FACT(x)' OVER - 'x' ROT LN ROOT 'x' PURGE
≫ '<span style="color:blue">IFACT</span>' STO
 
≪ { } 0 9 FOR j j <span style="color:blue">SFACT</span> + NEXT ≫ EVAL
≪ { } 0 9 FOR j j <span style="color:blue">HFACT</span> + NEXT ≫ EVAL
≪ { } 0 9 FOR j j <span style="color:blue">AFACT</span> + NEXT ≫ EVAL
≪ { } 0 4 FOR j j <span style="color:blue">EFACT</span> + NEXT ≫ EVAL
3628800 <span style="color:blue">IFACT</span>
119 <span style="color:blue">IFACT</span>
{{out}}
<pre>
6: { 1 1 2 12 288 34560 24883200 125411328000 5.05658474496E+15 1.83493347225E+21 }
5: { 1 1 4 108 27648 86400000 4.0310784E+12 3.31976639877E+18 5.56964379417E+25 2.15779412229E+34 }
4: { 0 1 1 5 19 101 619 4421 35899 326981 }
3: { 0 1 2 9 262144 }
2: 10
1: 4.99509387149
</pre>
 
Line 1,942 ⟶ 2,222:
{{libheader|Wren-fmt}}
We've little choice but to use BigInt here as Wren can only deal natively with integers up to 2^53.
<syntaxhighlight lang="ecmascriptwren">import "./big" for BigInt
import "./fmt" for Fmt
 
var sf = Fn.new { |n|
55

edits