Special factorials: Difference between revisions

From Rosetta Code
Content added Content deleted
(julia example)
Line 109: Line 109:
</pre>
</pre>


==((header|Julia}}==
=={{header|Julia}}==
No recursion.
No recursion.
<lang julia># No recursion.
<lang julia># No recursion.

Revision as of 11:24, 16 March 2021

Special factorials is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.

This task is an aggregation of lesser-known factorials that nevertheless have some mathematical use.

Special factorials
Name Formula Example calculation Links
Superfactorial                 n
sf(n) = ∏ k!
              k=1
sf(4) = 1! × 2! × 3! × 4! = 288
Hyperfactorial                 n
H(n) = ∏ kk
              k=1
H(4) = 11 × 22 × 33 × 44 = 27,648
Alternating factorial                 n
af(n) = ∑ (-1)n-ii!
              i=1
af(3) = -12×1! + -11×2! + -10×3! = 5
Exponential factorial n$ = n(n-1)(n-2)... 4$ = 4321 = 262,144


Task
  • Write a function/procedure/routine for each of the factorials in the table above.
  • Show   sf(n),   H(n),   and   af(n)   where   0 ≤ n ≤ 9.   Only show as many numbers as the data types in your language can handle. Bignums are welcome, but not required.
  • Show   0$,   1$,   2$,   3$,   and   4$.
  • Show the number of digits in   5$.   (Optional)
  • Write a function/procedure/routine to find the inverse factorial (sometimes called reverse factorial). That is, if   5! = 120,   then   rf(120) = 5.   This function is simply undefined for most inputs.
  • Use the inverse factorial function to show the inverse factorials of 1, 2, 6, 24, 120, 720, 5040, 40320, 362880, and 3628800.
  • Show   rf(119).   The result should be undefined.


See also



Factor

Works with: Factor version 0.99 2021-02-05

<lang factor>USING: formatting io kernel math math.factorials math.functions math.parser math.ranges prettyprint sequences sequences.extras ;

sf ( n -- m ) [1..b] [ n! ] map-product ;
(H) ( n -- m ) [1..b] [ dup ^ ] map-product ;
H ( n -- m ) [ 1 ] [ (H) ] if-zero ;
af ( n -- m ) n [1..b] [| i | -1 n i - ^ i n! * ] map-sum ;
$ ( n -- m ) [1..b] [ ] [ swap ^ ] map-reduce ;
rf ( n -- m )
   [ 1 1 ] dip [ dup reach > ]
   [ [ 1 + [ * ] keep ] dip ] while swapd = swap and ;
.show ( n quot -- )
   [ pprint bl ] compose each-integer nl ; inline

"First 10 superfactorials:" print 10 [ sf ] .show nl

"First 10 hyperfactorials:" print 10 [ H ] .show nl

"First 10 alternating factorials:" print 10 [ af ] .show nl

"First 5 exponential factorials:" print 5 [ $ ] .show nl

"Number of digits in $5:" print 5 $ number>string length . nl

{ 1 2 6 24 120 720 5040 40320 362880 3628800 119 } [ dup rf "rf(%d) = %u\n" printf ] each nl</lang>

Output:
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:
0 1 2 9 262144 

Number of digits in $5:
183231

rf(1) = 1
rf(2) = 2
rf(6) = 3
rf(24) = 4
rf(120) = 5
rf(720) = 6
rf(5040) = 7
rf(40320) = 8
rf(362880) = 9
rf(3628800) = 10
rf(119) = f

Julia

No recursion. <lang julia># No recursion.

superfactorial(n) = n < 1 ? 1 : mapreduce(factorial, *, 1:n) sf(n) = superfactorial(n)

hyperfactorial(n) = n < 1 ? 1 : mapreduce(i -> i^i, *, 1:n) H(n) = hyperfactorial(n)

alternating_factorial(n) = n < 1 ? -1 : mapreduce(i -> (-1)^(n - i) * factorial(i), +, 1:n) af(n) = alternating_factorial(n)

exponential_factorial(n) = n < 1 ? 1 : foldl((x, y) -> y^x, 1:n) n$(n) = exponential_factorial(n)

function reverse_factorial(n)

   for i in 1:100000
       fac = factorial(typeof(n)(i))
       fac == n && return i
       fac > n && break
   end
   return nothing

end rf(n) = reverse_factorial(n)

println("N Superfactorial Hyperfactorial Alternating Factorial Exponential Factorial\n", "-"^88) for n in 0:9

   print(n, "  ")
   for f in [sf, H, af, n$]
       if n < 5 || f != n$
           print(rpad((f(n)), 25))
       end
   end
   println()

end

println("\nThe number of digits in n$(5) is ", length(string(n$(BigInt(5)))))

println("\n\nN Reverse Factorial\n", "-"^25) for n in [1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 119]

   println(rpad(n, 10), rf(n))

end

</lang>

Output:
N  Superfactorial     Hyperfactorial       Alternating Factorial   Exponential Factorial
----------------------------------------------------------------------------------------
0  1                        1                        -1                       1
1  1                        1                        1                        1
2  2                        4                        1                        2
3  12                       108                      5                        9
4  288                      27648                    19                       262144
5  34560                    86400000                 101
6  24883200                 4031078400000            619
7  125411328000             3319766398771200000      4421
8  5056584744960000         -907465429310504960      35899
9  8705808953839190016      2649120435010011136      326981

The number of digits in n$(5) is 183231


N  Reverse Factorial
-------------------------
1         1
2         2
6         3
24        4
120       5
720       6
5040      7
40320     8
362880    9
3628800   10
119       nothing

Wren

Library: Wren-big
Library: Wren-fmt

We've little choice but to use BigInt here as Wren can only deal natively with integers up to 2^53. <lang ecmascript>import "/big" for BigInt import "/fmt" for Fmt

var f = Fn.new { |n|

   if (n < 2) return BigInt.one
   var fact = BigInt.one
   for (i in 2..n) fact = fact * i
   return fact

}

var sf = Fn.new { |n|

   if (n < 2) return BigInt.one
   var sfact = BigInt.one
   for (i in 2..n) sfact = sfact * f.call(i)
   return sfact

}

var H = Fn.new { |n|

   if (n < 2) return BigInt.one
   var hfact = BigInt.one
   for (i in 2..n) hfact = hfact * BigInt.new(i).pow(i)
   return hfact

}

var af = Fn.new { |n|

   if (n < 1) return BigInt.zero
   var afact = BigInt.zero
   var sign  = (n%2 == 0) ? -1 : 1
   for (i in 1..n) {
       afact = afact + f.call(i) * sign
       sign = -sign
   }
   return afact

}

var ef // recursive ef = Fn.new { |n|

   if (n < 1) return BigInt.one
   return BigInt.new(n).pow(ef.call(n-1))

}

var rf = Fn.new { |n|

   var i = 0
   while (true) {
       var fact = f.call(i)
       if (fact == n) return i
       if (fact > n)  return "none"
       i = i + 1
   }

}

System.print("First 10 superfactorials:") for (i in 0..9) System.print(sf.call(i))

System.print("\nFirst 10 hyperfactorials:") for (i in 0..9) System.print(H.call(i))

System.print("\nFirst 10 alternating factorials:") for (i in 0..9) System.write("%(af.call(i)) ")

System.print("\n\nFirst 5 exponential factorials:") for (i in 0..4) System.write("%(ef.call(i)) ") System.print()

Fmt.print("\nThe number of digits in 5$$ is $,d\n", ef.call(5).toString.count)

System.print("Reverse factorials:") var facts = [1, 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 119] for (fact in facts) Fmt.print("$4s <- rf($d)", rf.call(fact), fact)</lang>

Output:
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 

The number of digits in 5$ is 183,231

Reverse factorials:
   0 <- rf(1)
   2 <- rf(2)
   3 <- rf(6)
   4 <- rf(24)
   5 <- rf(120)
   6 <- rf(720)
   7 <- rf(5040)
   8 <- rf(40320)
   9 <- rf(362880)
  10 <- rf(3628800)
none <- rf(119)