Consider the following decision problem: given two lists of positive integers $a_1, a_2, \dots, a_n$ and $b_1, b_2, \dots, b_m$ the task is to decide if $a_1^{a_2^{\cdot^{\cdot^{\cdot^{a_n}}}}} < b_1^{b_2^{\cdot^{\cdot^{\cdot^{b_m}}}}}$.

  • Is this problem in the class $P$?
  • If yes, then what is the algorithm solving it in polynomial time?
  • Otherwise, what is the fastest algorithm that can solve it?


  • I mean polynomial type with respect to the size of the input, i.e. total number of digits in all $a_i, b_i$.
  • $p^{q^{r^s}}=p^{(q^{(r^s)})}$, not $((p^q)^r)^s$.
  • 17,225
  • 9
  • 47
  • 121
Vladimir Reshetnikov
  • 45,303
  • 7
  • 151
  • 282
  • 1
    At first glance, it doesn't seem likely that the problem is in P. If you are to compute each tower, which is only too likely in a worst-case scenario, you will need at least exponential space. For example, to write $a^b$ you need $b\log(a)$ of space, and $b$ is exponential w.r.t. $\log(b)$, which is the size of $b$. I think that in general you will need something like $\exp(\exp(\cdots\exp(c)\cdots))$ in space, where $c$ is the topmost element of the tower ($a_n$ or $b_m$), so the height of the tower is, I think, $n$. – Janoma Jan 28 '12 at 17:46
  • It seems like an interesting question, but I think you need limitations on $a_i$ and $b_i$ for this to be answerable. Otherwise, you can introduce arbitrary space requirement (and thus PSPACE, EXPSPACE etc) just for comparing $ a_1 $ and $b_1". That said, I also agree with Janoma that this seems likely to be EXPSPACE even with bounded numbers. – Desiato Mar 20 '12 at 01:25
  • 8
    A related question is discussed at http://mathematica.stackexchange.com/questions/24815/how-to-compare-power-towers-in-mathematica – Liu Jin Tsai May 08 '13 at 02:26
  • You need to specify a computational model. How long it takes to access each datum can be critical to determining complexity. – dfeuer May 08 '13 at 03:26
  • The complexity class of a problem is not dependent of the space required to storage numbers. What is really necessary to know is "how much computations" are necessary to compute this numbers. I believe that there is no problem to consider a hypotethical computer with infinite memory if you want. – Integral May 08 '13 at 03:28
  • Integral, the problem is that "get the value at index $n$ in an array of bits" is at least an $O(n)$ operation on a Turing machine. In a tree-based model, it may be around $O(\log n)$. In a RAM model (not realistic for very large memories) it may be $O(1)$. This will not affect whether it's polynomial, I don't think, but it can affect the order of the polynomial. – dfeuer May 08 '13 at 03:33
  • @dfeuer Are you saying the computational model must consider finite memory, otherwise the problem is automatically not $P$ ? – Integral May 08 '13 at 03:39
  • Just to clarify, what I'm trying to say is, the number $$A={a_1}^{a_2^{.{^{.^{.^{a_n}}}}}}$$ has $\log_{2}A$ binary digits, let $B$ analogously. If we do not care about memory limitations, we have only two problems to consider: the cost to compare $A$ and $B$, digit by digit, which is $\leq\max\{\log_{2}A, \log_{2}B\}$, and the cost to compute $A$ and $B$, which is the big problem. So, my question is: what is the cost to compute $A$ and $B$ if we have enough memory? – Integral May 08 '13 at 03:58
  • Anyway...I can't solve it and maybe I'm just making confusion here. Going to search... – Integral May 08 '13 at 04:08
  • 7
    Obviously, in many cases there is a cheaper way to get the answer than to explicitly calculate the power towers and then compare them digit by digit. I suppose, you do not need to fully calculate the numbers to see that 2^2^2^2^2^2 < 3^3^3^3^3^3^3^3^3. – Vladimir Reshetnikov May 08 '13 at 04:17
  • Sure...but in most of cases won't be like that. We need something more general, of course explicity calculations are not the best way. – Integral May 08 '13 at 04:20
  • 3
    @VladimirReshetnikov Thanks for your +350! I reinvested them into a new bounty. Hopefully we will see a complete and correct solution soon. – Piotr Shatalin May 15 '13 at 03:35

3 Answers3


Recently I asked a very similar question at Mathematica.SE. I assume you know it, because you participated in the discussion.

Leonid Shifrin suggested an algorithm that solves this problem for the majority of cases, although there were cases when it gave an incorrect answer. But his approach seems correct and it looks like it is possible to fix those defects. Although it was not rigorously proved, his algorithm seems to work in polynomial time. It looks like it would be fair if he got the bounty for this question, but for some reason he didn't want to.

So, this question is not yet settled completely and I am going to look for the complete and correct solution, and will start a new bounty for this question once the current one expires. I do not expect to get a bounty for this answer, but should you choose to award it, I will add it up to the amount of the new bounty so that it passes to whomever eventually solves this question.

Piotr Shatalin
  • 2,515
  • 22
  • 35
  • 2
    There is an approach at Robert Munafo's "Hypercalc" site. I did not check how far we can extend the powertower there, but from his description I've the impression, it can be used for fairly high powertowers and that the explanation might be that what you're looking for. See: http://mrob.com/pub/perl/hypercalc.html – Gottfried Helms May 21 '13 at 15:07
  • Hypercalc has 27^googolplex = 10^googolplex. It probably works much like my solution below – Thomas Ahle May 21 '13 at 17:04

For readability I'll write $[a_1,a_2,\ldots,a_n]$ for the tower $a_1^{a_2^{a_3^\cdots}}$.

Let all of the $a_i,b_i$ be in the interval $[2,N]$ where $N=2^K$ (if any $a_i$ or $b_i$ is 1 we can truncate the tower at the previous level, and the inputs must be bounded to talk about complexity).

Then consider two towers of the same height $$ T=[N,N,\ldots,N,x] \quad \mathrm{and} \quad S=[2,2,\dots,2,y] $$ i.e. T is the largest tower in our input range with $x$ at the top, and S is the smallest with $y$ at the top.

With $N, x\ge 2$ and $y>2Kx$ then $$ \begin{aligned} 2^y & > 2^{2Kx} \\ & = N^{2x} \\ & > 2log(N)N^x &\text{ as $x \gt 1 \ge \frac{1+log(log(N))}{log(N)}$} \\ & = 2KN^x \end{aligned} $$ Now write $x'=N^x$ and $y'=2^y>2Kx'$ then $$ [N,N,x]=[N,x']<[2,y']=[2,2,y] $$ Hence by induction $T<S$ when $y>2Kx$.

So we only need to calculate the exponents down from the top until one exceeds the other by a factor of $2K$, then that tower is greater no matter what values fill in the lower ranks.

If the towers have different heights, wlog assume $n>m$, then first we reduce $$ [a_1,a_2,\ldots,a_n] = [a_1,a_2,\ldots,a_{m-1},A] $$ where $A=[a_m,a_{m+1},\ldots,a_n]$. If we can determine that $A>2Kb_m$ then the $a$ tower is larger.

If the towers match on several of the highest exponents, then we can reduce the need for large computations with a shortcut. Assume $n=m$, that $a_j> b_j$ for some $j<m$ and $a_i=b_i$ for $j<i\le m$. Then $$ [a_1,a_2,\ldots,a_m] = [a_1,a_2,\ldots,a_j,X] \\ [b_1,b_2,\ldots,b_m] = [b_1,b_2,\ldots,b_j,X] $$ and the $a$ tower is larger if $(a_j/b_j)^X>2K$. So we don't need to compute $X$ fully if we can determine that it exceeds $\log(2K)/\log(a_j/b_j)$.

These checks need to be combined with a numeric method like the one @ThomasAhle gave. They can solve the problem that method has with deep trees that match at the top, but can't handle $[4,35,15],[20,57,13]$ which are too big to compute but don't allow for one of these shortcuts.

Thomas Ahle
  • 3,973
  • 18
  • 38
  • 10,788
  • 1
  • 24
  • 53
  • 1
    Very nice! I think you've got the correct answer. Only, in the inductive proof, why is $2^y = (N^x)^2$? – Thomas Ahle May 22 '13 at 07:02
  • 1
    @ThomasAhle Oh thanks, should be greater than, not equals. $N=2^K,y>2Kx$ so $2^y>2^{2Kx}=((2^K)^x)^2=(N^x)^2$. – Zander May 22 '13 at 11:12
  • Got it. So for $a > b \ge 2$ we just need $x > log(2K)/log(N/(N-1)) \ge log(2K)/log(a/b)$ to get $a^x > 2Kb^x$. For N = 100 that means $x$ just needs to be at least 258. Amazing. – Thomas Ahle May 22 '13 at 12:06
  • Actually we still need something: What if after the four top levels the numeric approach reaches its limit, and we still don't have $x=y$ or $y>2Kx$? – Thomas Ahle May 23 '13 at 00:20
  • 1
    @ThomasAhle Yes, I agree something else is needed. For 4 (or any fixed number of levels) I think we can just increase our calculation precision and still keep it polynomial time. But that doesn't work for an arbitrary number of "close" levels. I think abc-conjecture type bounds (Stewart & Yu e.g.) can do it by guaranteeing the difference is large even if the ratio is close to 1. I don't have time right now but will try to write this up later. – Zander May 23 '13 at 11:08
  • I wonder if induction would be enough. It seems that if you require two towers to have a ratio higher than $k$, it transforms into their sub towers having a bound difference. I can't get further than that though – Thomas Ahle May 25 '13 at 08:03
  • 1
    @Zander Came across this problem and I've been interested in a solution that works for all cases. I know it's been a few years but if you're still around do you think you could write it up? – exfret Mar 31 '19 at 21:25

My approach is similarly numeric to Leonid's, but more precise and perhaps easier to analyse. It supports real exponents > 0.

The idea is to represent power towers as a single floating point number with $n$ exponentiations: $(x\mid n) := exp^n(x)$. Normalizing $x\in[0,1)$, this format allows easy comparison between numbers.

What remains is a way to calculate $a^{(x\mid n)}$ for any real, positive $a$. My Python code below is an attempt to do so, while being as numerically stable as possibly, e.g. by using the log-sum trick. My code runs in time proportional to the height of the tower (number of apow calls) and the iterated-log of it's value (number of recursive calls).

I haven't been able to find two towers with values close enough to case my method to fail. At least for integer exponents. With fractional exponents it is possible to create very towers too close for my representation to handle. E.g. $$ 2^{2^{2^{2^0}}} \\ < \\ 2^{2^{2^{2^{(1/2)^{2^{2^{2^2}}}}}}} $$

I would be interested in suggestions to other types of counter examples, especially integer ones.

It seems to me that for the problem to be in P, we need to non-numerical methods. It doesn't seem unlikely at all, that certain analytical cases are harder than P.

from math import log, exp

def normalize((x,n)):
  """ Adjusts n to put x in the range [0,1) """
  if x >= 1: return normalize((log(x),n+1))
  if x < 0:  return normalize((exp(x),n-1))
  return (x,n)
normdec = lambda f: lambda *a: normalize(f(*a))

def apow(a,(x,n)):
  """ Calculates a^(x|n) """
  if a == 1: return (1,0)
  if a < 1: return (rpow(x,n)*log(a), 1)
  if n == 0: return (x*log(a), 1)
  if n >= 1:
    y, k = cpow(log(log(a)), x, n-1)
    return (y, k+2)

def cpow(c,x,n):
  """ Calculates (x|n) + c """
  if c == 0: return (x, n)
  if n == 0: return (x + c, 0)
  z = rpow(x,n-1)
  if z <= log(abs(c)):
    return (exp(z)+c, 0)
  if c < 0: y, k = cpow(log(1-exp(log(-c)-z)), x, n-1)
  if c > 0: y, k = cpow(log(1+exp(log(c)-z)), x, n-1)
  return (y, k+1)

def rpow(x,n):
  """ Calculates (x|n) as a float
      Returs Infinty if the value is out of range"""
    for _ in range(n):
      x = exp(x)
  except OverflowError:
    # We get into this case in two situations
    # 1) We are calculating log((x|n) + c) and c contributes very little
    # 2) We are calculating a^(x|n) for a < 1 and (x|n) is so small it doesn't
    #    fit into a float
    return float('inf')
  return x

def powtow(bs):
  """ Calculates b[0]**b[1]**b[2]**...**b[m-1] in the (x|n) form.
      Equivalent to `foldr apow (1,0) bs'
      e.g. apow(b[0], apow(b[1], apow(b[2], (1,0)))) """
  if not bs: return (1,0)
  return apow(bs[0], powtow(bs[1:]))

if __name__ == "__main__":
  print powtow([1,2,3,4,5])
  print powtow([2,3,4,5])
  print powtow([5,4,3,2])
  print powtow([4,4,3,3,3])
  print powtow([3,3,3,3,3])
  print powtow([4,6,8,8,9])
  print powtow([2,2,5,2,7,4,9,3,7,6,9,9,9,9,3,2])
  print powtow([3,3,6,3,9,4,2,3,2,2,2,2,2,3,3,3])
  print powtow([2,3,2,3,5,8])
  print powtow([3,2,2,7,6,7])
  print powtow([2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,2,2,2])
  print powtow([2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,16])
  print powtow([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9])
  print powtow([1.54090919967, 1.46228204461, 1.78555495826, 1.75545819035, 2.21730941808, 1.0797564499, 7.90630125423, 0.881978093585, 1.75085618709, 2.23911325176, 1.39697337886, 1.16053659586, 1.5939192079, 6.11401961748, 0.844860266481, 1.92758094038, 4.64573316954, 0.870819420274, 1.49026447511, 1.77839910981, 1.46208378213, 2.29956158055, 1.00884903003, 1.77521724246, 2])
  print powtow([2.32185478602, 1.88198918762, 2.27614315145, 1.77518235487, 1.4841479727, 0.563158971798, 0.732132856919, 0.669957968262, 2.16345101714, 2.23185963501, 0.824885385628, 0.873101580546, 1.45714899023, 2.3973000247, 0.507154709525, 1.94022843601, 1.29982267606, 0.578058713016, 1.58207655843, 1.79417433851, 1.18630377782, 1.37314328673, 0.655551609076, 1.57569812897, 1])
  print powtow([2, 2, 2, 1])
  print powtow([2, 2, 2, 2, .5, 2, 2, 2, 2])

  flip = lambda (a,b): (b,a)
  snd = lambda (a,b): b
  import itertools
  f = lambda xs: [1./x for x in xs]
  # Print all power towers of permutations [2..6], sorted
  print list(reversed(sorted((flip(powtow(p)),p) for p in itertools.permutations(range(2,7)))))
  # Print all power towers of permutations [1/2..1/6] sorted
  print list(reversed(sorted((flip(powtow(f(p))),p) for p in itertools.permutations(range(2,7)))))


powtow([2,2,2,2,2,2,2,2,2,2,2,2,2,2,4,2,2,2]) = (0.1184590219613409, 18)
powtow([9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]) = (0.10111176550354063, 18)

powtow([2,2,5,2,7,4,9,3,7,6,9,9,9,9,3,2]) = (0.10111176550354042, 17)
powtow([3,3,6,3,9,4,2,3,2,2,2,2,2,3,3,3]) = (0.19648862015624008, 17)

Counter examples:

powtow([2,2,2,2,2,2,2]) = (0.8639310719129168, 6)
powtow([3,2,2,2,2,2,2]) = (0.8639310719129168, 6)
Thomas Ahle
  • 3,973
  • 18
  • 38
  • 1
    I read http://petr-mitrichev.blogspot.co.uk/2012/05/world-finals-day-2-upe-dinner.html to get some more ideas. It seems like Petr assumes that once the head of the tower is large enough for the LI representation to be equal, we can just look at the remaining tower, from top to bottom, and choose the one with the largest value the first time they differ. – Thomas Ahle May 21 '13 at 21:32
  • 1
    I assume the counterexample in your answer is the case where your algorithm fails to give the correct answer. It is exactly the case on which both [WolframAlpha](http://www.wolframalpha.com/input/?i=2%5E2%5E2%5E2%5E2%5E2%5E2+<+3%5E2%5E2%5E2%5E2%5E2%5E2) and [HyperCalc](http://mrob.com/pub/comp/hypercalc/hypercalc-javascript.html) (try `3^2^2^2^2^2^2 - 2^2^2^2^2^2^2`) also fail. Do have any ideas about how this defect could be fixed? – Vladimir Reshetnikov May 22 '13 at 00:27
  • 1
    Yes. I believe if we bound the exponents so $1 < a < 100$ (or maybe a much larger upper bound) we can use my method for comparing the height 3 or 4 head of the tower. It should be strong enough to tell us if they are equal or one is larger. Plan B is to choose the highest tower. Plan C is the interesting one: At this point the values of the rest of the tower only matter if the heads are equal, so we can walk down the towers in parallel, stopping as soon as we see a differing value. – Thomas Ahle May 22 '13 at 06:48
  • Hence the main thing to be proven is that once the head of a tower exceeds a certain point, and the rest of the exponents are bounded (and equally numerous), we can simply look at the top differing value. It's a bit counter intuitive, but it seems very likely from the simple inequalities you get. Zander's post might be exactly what is needed. – Thomas Ahle May 22 '13 at 06:51
  • From Zander's post it seems like the critical point is just less than $N(C+log(log(N)))$ where $N$ is the upper bound for exponents. (And $C = log(2/log(2))) < 1.06$). Since a tower of height 4 (with no ones) is at least 65536 we don't have to calculate more than 4 levels for $N$ up to around 19,000. – Thomas Ahle May 22 '13 at 12:39