# Calculate Knuth's up arrow notation [duplicate]

Inspired by Expand exponentation.

Knuth's up arrow notation is used for big numbers such as Graham's number.

If we look deeper, we can see how it makes big numbers.

One arrow means exponentiation. e.g. 2↑3 equals 2^3 = 8.

Two or more arrows means repeating the instructions of n-1 arrows. e.g. 2↑↑3 equals 2↑2↑2 equals 2^(2^2)=16.

You will be given three integers, n, a, and m. n is the first number, a is the amount of arrows, and m is the second number.

Your code should output the final answer, which is the calculation of n ↑a m(↑x means there are x up-arrows, where x is an integer)

# Examples

2 1 2 -> 4
2 1 3 -> 8
2 2 3 -> 16
2 3 3 -> 65536

• Related. – Martin Ender Feb 20 '17 at 12:30
• I'd suggest to add 3 2 2 and 3 2 3 as additional test cases. – Arnauld Feb 20 '17 at 14:31

# APL, 22 bytes

{×⍺⍺:(⍺⍺-1)∇∇/⍵/⍺⋄⍺×⍵}


This is an operator that takes a as its operand (⍺⍺), and n and m as its left and right arguments (⍺ and ⍵).

Explanation:

• ×⍺⍺: if ⍺⍺ is positive:
• ⍵/⍺: replicate ⍺ ⍵ times
• (⍺⍺-1)∇∇/: fold the ⍺⍺-1-arrow function over the list.
• ⋄: otherwise (i.e. if ⍺⍺ is zero):
• ⍺×⍵: multiply the arguments

# Java 7, 121 bytes

int c(int n,int a,int m){return(int)(a<2?Math.pow(n,m):d(n,a));}double d(int n,int a){return Math.pow(n,a<2?n:d(n,a-1));}


Explanation:

int c(int n, int a, int m){         // Main method with the three integer-parameters as specified by OP's challenge
return (int)                      // Math.pow returns a double, so we cast it to an integer
(a < 2 ?                  // if (a == 1):
Math.pow(n, m)   //  Use n^m
:                  // else (a > 1):
d(n, a));        //  Use method d(n, a)
}

double d(int n, int a){             // Method d with two integer-parameters
return Math.pow(n, a < 2          // n ^ X where
? n           //  X = n    if (a == 1)
: d(n, a-1)); //  X = recursive call d(n, a-1)    if (a > 1)
}

// In pseudo-code:
c(n, a, m){
if a == 1: return n^m
if a > 1:  return d(n, a);
}
d(n, a){
if a == 1: return n^n
if a > 1:  return d(n, a-1);
}


Test code:

Try it here.

class M{
static int c(int n,int a,int m){return(int)(a<2?Math.pow(n,m):d(n,a));}
static double d(int n,int a){return Math.pow(n,a<2?n:d(n,a-1));}

public static void main(String[] a){
System.out.println(c(2, 1, 2));
System.out.println(c(2, 1, 3));
System.out.println(c(2, 2, 3));
System.out.println(c(2, 3, 3));
}
}


Output:

4
8
16
65536

• Unless I'm missing something in the challenge definition, I don't think that m should be ignored when a > 1. – Arnauld Feb 20 '17 at 14:00
• @Arnauld The way I read the challenge it is, unless I'm missing something.. :S I do get the correct output. How do you interpret OP's question, and could you come up with a test case where that interpretation would differ in terms of output compared to my pseudo-code explanation? – Kevin Cruijssen Feb 20 '17 at 14:11
• I think we should have 3 2 2 -> 3^3 = 27 and 3 2 3 -> 3^(3^3) = 7625597484987. (You can find these examples -- and more of them -- on Wikipedia) – Arnauld Feb 20 '17 at 14:30

# JavaScript ES7, 53 44 bytes

f=(a,b,c)=>b<2||c<1?a**c:f(a,b-1,f(a,b,c-1))


f=(a,b,c)=>b<2||c<1?a**c:f(a,b-1,f(a,b,c-1))

console.log(f(2,1,2));
console.log(f(2,1,3));
console.log(f(2,2,3));
console.log(f(2,3,3));

## Mathematica, 48 40 bytes

If[#3>1<#,#0[#0[#-1,##2],#2,#3-1],#2^#]&


Order of arguments is m, n, a (using the notation from the challenge).

# julia, 41 38 bytes

f(a,n,b)=b>1< n?f(a,n-1,f(a,n,b-1)):a^b


Thanks to @Martin 3 bytes saved.

Try it online!

a,b : operands
n: number of arrows

f(a,n,b)=n<2||b<1?a^b:f(a,n-1,f(a,n,b-1))

• You can save some bytes on the || by a) noting that b<2 also works, b) applying deMorgan to rewrite that as n>1&&b>1 (swapping the two branches of the ternary operator) and c) using inequality chaining on the 1: f(a,n,b)=b>1<n?f(a,n-1,f(a,n,b-1)):a^b – Martin Ender Feb 20 '17 at 14:35