1
$\begingroup$

I am attempting to write a general function that can take any number and back calculate to see if it is the factorial of a smaller number. The easiest and quickest way to do this is to take the initial, larger number and divide by consecutive integers starting at 2, until the dividend is equal to the divisor (so the quotient is 1). E.g.

120/2 = 60;
60/3 = 20;
20/4 = 5;
5/5 = 1;

Therefore, 5! = 120

I attempted to use Table, but then realized Table will just iterate thru without altering the value of the dividend. I need both my divisor and dividend to change: I need the dividend to take the value of the previous quotient, and I need the divisor to increase by one after each evaluation. I am not really sure how to fix this, here's my most recent attempt:

Clear@inverseFactorial
inverseFactorial[num_Integer, c_] := Block[{list},

list = NestWhileList[(#/c) &, num, {# == c} &];

Length@list+1(*since we started at 2 the length of the list will be one off the actual value to be 'factorialized'*)]

However, it's not working the way I want to, but it's also not showing me any errors when it evaluates. Like most Mathematica users, I do functional programming and these problems which clearly involve some kind of loop are particularly difficult when doing things like this. I'm just interested if there is in fact a way, because this is the way I actually think about the problem.

$\endgroup$
3
$\begingroup$

Try to use

InverseFunction[Gamma]

(Gamma^(-1))[24]

5

Remembering that $n!=\Gamma[n+1]$ you have inverse factorial of $24$ as $5-1=4$

$\endgroup$
  • $\begingroup$ Yes, I thought about using the Gamma function, but felt like that would've been cheating in some sense, based on what I was looking to get out of this exercise $\endgroup$ – Lame-Ov2.0 Jun 28 '17 at 17:54
3
$\begingroup$

You can use Reduce`FactorialInverse:

Reduce`FactorialInverse[6001!]

{6001}

$\endgroup$
  • $\begingroup$ I've never used these context tick marks before. What is its purpose? The documentation isn't clear $\endgroup$ – Lame-Ov2.0 Jun 28 '17 at 17:57
  • 1
    $\begingroup$ @Lame, these are undocumented functions. Because of that, there are no guarantees that they will keep on working in future versions. $\endgroup$ – J. M. will be back soon Jul 27 '17 at 7:23
1
$\begingroup$

Maybe this is what you want

n = 5;
FoldList[Divide, n!, Range[2, n - 1]]

{120, 60, 20, 5}

 n = 6;
 FoldList[Divide, n!, Range[2, n - 1]]

{720, 360, 120, 30, 6}

$\endgroup$
0
$\begingroup$

You are not incrementing your c and the condition # == c is wrong for two reasons, NestWhile loops while the conditions is true, so it would stop immediately, and if you change it on # != c it would loop infinetely at non factorial numbers. And actually it wouldn't be off by one if you start with c = 2, quite the opposite. Hear:

inverseFactorial[num_Integer,c_:2]:=
 Length@NestWhileList[Apply[{#1/#2,#2+1}&],{num,c},Apply[GreaterEqual]]
$\endgroup$
  • $\begingroup$ Nice, except I think inverseFactorial[123] should return an error. Perhaps With[{res = NestWhile[Apply[{#1/#2, #2 + 1} &], {num, c}, Apply[GreaterEqual]]}, res[[2]] - 1 /; res[[1]] == 1]? $\endgroup$ – Michael E2 Jun 28 '17 at 15:38
0
$\begingroup$

With what's available, I would do the following one-liner:

inverseFactorial[n_] :=
 Module[{i = 1, res}, res = NestWhile[#/++i &, n, # > 1 &]; 
  If[res == 1, i, False]]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.