Golfed Inverse Ackermann Function
I know that you're supposed to create the slowest-growing function possible, but that doesn't mean you necessarily need to make your function the slowest possible (LoL!).

As far as I can determine, your code for the Ackermann is mathematically correct - according to both Wikipedia and my (admittedly poor) sense of mathematical intuition.

&lt;BoringMaths&gt;

However, the inverse Ackermann as defined by Wikipedia is supposed to be a two-parameter function, and as such you cannot imitate it using a one-parameter function.

Also, you want a do-while loop here, so that the loop runs at least once even if the constraining condition is false at the start, as well be for my suggestion below. I don't think the return should be i - 1 instead of i either, as you can potentially return 0 if it remains as-is, which is not a legal value.

What you could try, as the ending paragraph of the relevant section of the Wikipedia article mentions, is setting the parameter m to a constant - not n, and especially not making \$n=m\$ - although that works too.

Here, I'd suggest choosing \$m=0\$. Such a choice helps with golf-ability - you can get rid of the division and the Math.floor in one fell swoop - \$\lfloor\frac{m}{n}\rfloor\$ is always \$0\$, regardless of \$n\$ (assuming that NaN, when converted to integral type, is 0, as it is in Java). So the loop condition basically becomes \$Ack(i, 0) &lt; log_2(n)\$. Note the less-than (\$\lt\$), not less-than-or-equal-to (\$\le\$): this is the proper negation of the condition greater-than-or-equal-to (\$\ge\$).

Mathematically, how about a constant function, which is in fact the slowest growing function as it doesn't grow at all? Why not just return a constant and be done with it?

I think the PPCG question's rules forbid submitting a constant function, so let's not dwell on that any more (but it does make for a cheap trick, doesn't it?)

&lt;/BoringMaths&gt;

&lt;NonCritical&gt;

A few small improvements for your implementation in the readable version


Extract out Math.log2(n) into a variable.
I think ES6+ gets you let and const - use them instead of var. As far as I remember, the former gets you proper scoping and the latter allows you to declare a named constant. I think my point (1) should have a const declaration.


Type Coercion is not readable!

Don't use implicit Boolean coercion of numbers in code which you claim to be "readable" - it isn't. Use proper comparisons in readable code, and leave the cool weak-typing hackery for the golfed version. How much does writing out the actual condition improve the readability of the code?

Everything else seems to be fine - naming, indentation, and all.

&lt;/NonCritical&gt;

Suggested Code:

function Ackermann(m, n) {
  if (m &lt; 0 || n &lt; 0) {
     throw new TypeError("Arguments to Ackermann must be non-negative");
  }
  if (m == 0) {
     return n + 1;
  }
  else if (n == 0) {
     return Ackermann(m - 1, 1);
  } else {
     return Ackermann(m - 1, Ackermann(m, n - 1));
  }
}

function inverseAckermann(n) {
  const log2_n = Math.log2(n);
  let i = 0;
  // Taking `m` to be the constant 0 in the definition of the inverse Ackermann function
  do {
      ++i; // Pre-increment implies less side-effects
  } while (Ackermann(i, 0) &lt; log2_n); 

  return i;
}