All Euler problems
Project Euler

The Hyperexponentiation of a Number

The hyperexponentiation (or tetration) of a number a by a positive integer b is recursively defined: a uparrowuparrow b = a & if b = 1 a^(a uparrowuparrow (b-1)) & if b > 1 Find 1777 uparrowuparrow...

Source sync Apr 19, 2026
Problem #0188
Level Level 05
Solved By 7,190
Languages C++, Python
Answer 95962097
Length 185 words
modular_arithmeticnumber_theoryrecursion

Problem Statement

This archive keeps the full statement, math, and original media on the page.

The hyperexponentiation or tetration of a number $a$ by a positive integer $b$, denoted by $a\mathbin{\uparrow \uparrow}b$ or $^b a$, is recursively defined by: $$ \begin{cases} a \mathbin{\uparrow \uparrow} 1 = a \\ a \mathbin{\uparrow \uparrow} (k+1) = a^{(a \mathbin{\uparrow \uparrow} k)} \end{cases} $$ Thus we have e.g. $3 \mathbin{\uparrow \uparrow} 2 = 3^3 = 27$, hence $3 \mathbin{\uparrow \uparrow} 3 = 3^{27} = 7625597484987$ and $3 \mathbin{\uparrow \uparrow} 4$ is roughly $10^{3.6383346400240996 \cdot 10^{12}}$.

Find the last $8$ digits of $1777 \mathbin{\uparrow \uparrow} 1855$.

Problem 188: The Hyperexponentiation of a Number

Mathematical Analysis

Euler’s Theorem and Iterated Totient

To compute aN(modm)a^N \pmod{m}, when gcd(a,m)\gcd(a, m) might not be 1, we use the generalized version:

For Nlog2(m)N \ge \log_2(m):

aNa(Nmodϕ(m))+ϕ(m)(modm)a^N \equiv a^{(N \bmod \phi(m)) + \phi(m)} \pmod{m}

This allows us to reduce the exponent modulo ϕ(m)\phi(m), adding ϕ(m)\phi(m) to ensure the exponent is large enough.

Iterated Totient Descent

To compute 177717771777(mod108)1777^{1777^{1777^{\cdots}}} \pmod{10^8}, we recursively reduce the modulus:

m0=108,m1=ϕ(108),m2=ϕ(m1),m_0 = 10^8, \quad m_1 = \phi(10^8), \quad m_2 = \phi(m_1), \quad \ldots

The Euler totient function satisfies ϕ(n)<n\phi(n) < n for n>1n > 1 and ϕ(n)\phi(n) is even for n>2n > 2, so the sequence m0,m1,m2,m_0, m_1, m_2, \ldots decreases rapidly and reaches 1 in O(logm0)O(\log m_0) steps.

Computation Chain

ϕ(108)=108(11/2)(11/5)=4×107\phi(10^8) = 10^8 \cdot (1 - 1/2)(1 - 1/5) = 4 \times 10^7

The chain of totients reaches 1 well before 1855 levels of recursion, so at sufficient depth the tower value is simply “large enough” and we use the formula with +ϕ(m)+\phi(m).

Editorial

The recursion depth is at most O(log(108))O(\log(10^8)), which is very small (~30 or so). We evaluate the closed-form expressions derived above directly from the relevant parameters and return the resulting value.

Pseudocode

def hyper(a, b, mod):
    If mod == 1 then
        Return 0
    If b == 1 then
        Return a % mod
    exp = hyper(a, b - 1, euler_totient(mod))
    Return pow(a, exp + euler_totient(mod), mod)

The recursion depth is at most O(log(108))O(\log(10^8)), which is very small (~30 or so).


## Complexity

- **Time**: $O(\log^2(m))$ where $m = 10^8$, since we recurse $O(\log m)$ times and each modular exponentiation takes $O(\log m)$.
- **Space**: $O(\log m)$ for the recursion stack.

## Answer

$$
\boxed{95962097}
$$

Code

Each problem page includes the exact C++ and Python source files from the local archive.

C++ project_euler/problem_188/solution.cpp
#include <bits/stdc++.h>
using namespace std;

long long euler_totient(long long n) {
    long long result = n;
    for (long long p = 2; p * p <= n; p++) {
        if (n % p == 0) {
            while (n % p == 0) n /= p;
            result -= result / p;
        }
    }
    if (n > 1) result -= result / n;
    return result;
}

long long power_mod(long long base, long long exp, long long mod) {
    if (mod == 1) return 0;
    long long result = 1;
    base %= mod;
    while (exp > 0) {
        if (exp & 1) result = (__int128)result * base % mod;
        base = (__int128)base * base % mod;
        exp >>= 1;
    }
    return result;
}

long long hyper(long long a, long long b, long long mod) {
    if (mod == 1) return 0;
    if (b == 1) return a % mod;
    long long phi = euler_totient(mod);
    long long exp = hyper(a, b - 1, phi);
    return power_mod(a, exp + phi, mod);
}

int main() {
    cout << hyper(1777, 1855, 100000000) << endl;
    return 0;
}