Problem Summary

Project Euler 282 asks for the modular sum

$$\sum_{n=0}^{6} A(n,n)\pmod{14^8},$$

where \(A(m,n)\) is the standard Ackermann function

$$A(0,n)=n+1,$$

$$A(m,0)=A(m-1,1)\quad (m\ge1),$$

$$A(m,n)=A(m-1,A(m,n-1))\quad (m,n\ge1).$$

The modulus is

$$M=14^8=1475789056.$$

The final residue is intentionally omitted; this page explains why the C++ solution can compute it without ever building the astronomically large raw Ackermann values.

Mathematical Approach

1) The first few Ackermann layers have closed forms

Starting from the definition, one gets the standard low-level identities:

$$A(0,n)=n+1,$$

$$A(1,n)=n+2,$$

$$A(2,n)=2n+3,$$

$$A(3,n)=2^{n+3}-3.$$

Therefore the diagonal values needed in the sum begin as

$$A(0,0)=1,\qquad A(1,1)=3,\qquad A(2,2)=7,\qquad A(3,3)=61.$$

These are exactly the constants returned by solve_n0(), solve_n1(), solve_n2(), and solve_n3().

2) From exponentials to tetration

Because

$$A(3,n)=2^{n+3}-3,$$

the next level satisfies

$$A(4,n+1)=A(3,A(4,n))=2^{A(4,n)+3}-3.$$

This is exactly the recursion of a power tower. Using Knuth's notation,

$$A(4,n)=2\uparrow\uparrow(n+3)-3,$$

where

$$2\uparrow\uparrow1=2,\qquad 2\uparrow\uparrow(h+1)=2^{\,2\uparrow\uparrow h}.$$

In particular, the \(n=4\) diagonal term is

$$A(4,4)=2\uparrow\uparrow7-3.$$

This is why the code computes

$$\texttt{hyper\_tower\_2(7,M)}-3 \pmod M$$

inside solve_n4().

3) The next Ackermann levels are even higher hyper-operators

The same pattern continues:

$$A(5,n)=2\uparrow\uparrow\uparrow(n+3)-3,$$

$$A(6,n)=2\uparrow\uparrow\uparrow\uparrow(n+3)-3,$$

and so on.

So the last two needed diagonal terms, \(A(5,5)\) and \(A(6,6)\), are not merely “very large”; they are far beyond any direct representation. The only sensible target is their residue modulo \(M\).

4) What the helper hyper_tower_2(h,m) computes

The recursive helper does not compute the actual tower \(2\uparrow\uparrow h\). It computes only its residue modulo \(m\):

$$T_h(m):=2\uparrow\uparrow h \pmod m.$$

For small heights the values are explicit:

$$T_0(m)=1,\qquad T_1(m)=2,\qquad T_2(m)=4,\qquad T_3(m)=16,\qquad T_4(m)=65536,$$

all taken modulo \(m\). These base cases are hard-coded in the function.

5) Why Euler-\(\varphi\) recursion is the right reduction

For large heights, we want

$$2^{E}\pmod m,$$

where \(E=2\uparrow\uparrow(h-1)\) is itself enormous. The classical coprime reduction says that modulo an odd modulus one may reduce exponents modulo \(\varphi(m)\). Here the base is \(2\), and our moduli along the recursion are not always coprime to \(2\), so one has to be careful.

The code uses the standard “lifted exponent” strategy:

1. compute the upper exponent modulo \(\varphi(m)\);

2. add one full totient period;

3. exponentiate modulo \(m\).

Formally, for the huge towers occurring in this problem, it evaluates

$$2^{\,e+\varphi(m)}\pmod m,$$

where

$$e=T_{h-1}(\varphi(m)).$$

This is exactly what the code does through

$$\texttt{eff\_exponent = exponent\_val + phi}.$$

6) Why the \(+\varphi(m)\) lift is safe here

This lift is not being used as a blind universal theorem for tiny exponents. It is safe here because all tower heights entering the recursive branch are already huge.

The modulus is

$$M=14^8=2^8\cdot 7^8.$$

For the \(2^8\) part, once the exponent is at least \(8\), we already have

$$2^E\equiv 0\pmod{2^8}.$$

For the odd part \(7^8\), the base \(2\) is coprime, so Euler reduction modulo

$$\varphi(7^8)=6\cdot 7^7$$

is valid.

Adding \(\varphi(m)\) guarantees that the reconstructed exponent is safely “large enough” for the \(2\)-power part while keeping the correct residue information for the odd part. Since the actual exponents in the problem are vastly larger than \(8\), this lifted reduction matches the true tower residue.

7) Stabilization of very tall towers modulo \(M\)

An important phenomenon is that the residues

$$2\uparrow\uparrow h \pmod M$$

eventually stabilize. In fact, with the recursion used by the code, the residue stops changing once the tower height is large enough. A direct check shows that the values are already constant from height \(11\) onward.

That means:

every sufficiently tall power tower of 2 has the same residue modulo \(M\).

This is the key reason the gigantic terms \(A(5,5)\) and \(A(6,6)\) become tractable.

8) Why \(A(5,5)\) and \(A(6,6)\) use the same surrogate height

We have

$$A(5,5)+3=2\uparrow\uparrow\uparrow 8,$$

which means “a tetration whose height is itself already enormous.” Likewise \(A(6,6)+3\) is vastly larger still.

Since tower residues modulo \(M\) have already stabilized by modest height, both of these Ackermann values land in the same stabilized residue class. Therefore the code is allowed to replace each of them by

$$2\uparrow\uparrow 200 \pmod M$$

as a safe surrogate. The particular choice \(200\) is not mathematically special; it is simply far beyond the stabilization threshold.

That is why solve_large_n() is called twice, once for the \(n=5\) term and once for the \(n=6\) term.

9) Final decomposition of the required sum

The problem asks for

$$S=\sum_{n=0}^{6}A(n,n)\pmod M.$$

The implementation splits this into:

four exact small constants for \(n=0,1,2,3\);

one genuine tetration term for \(n=4\), namely \(2\uparrow\uparrow7-3\);

two identical stabilized huge-level residues for \(n=5\) and \(n=6\).

So the entire problem is reduced to a few modular tower evaluations, not to raw Ackermann growth.

Code Logic

1) Fast modular power. power() uses binary exponentiation with 128-bit intermediate multiplication.

2) Totient computation. get_phi() factors the current modulus on the fly and returns \(\varphi(m)\).

3) Tower recursion. hyper_tower_2(height,m) evaluates \(2\uparrow\uparrow\text{height}\pmod m\) by recurring into modulus \(\varphi(m)\) and then lifting the exponent by one totient.

4) Ackermann layers. solve_n0() through solve_n3() return exact constants; solve_n4() returns the \(A(4,4)\) residue; solve_large_n() returns the stabilized residue used for both \(A(5,5)\) and \(A(6,6)\).

5) Final sum. The main function launches the seven pieces independently, collects them, and sums modulo \(M\).

Complexity Analysis

Each modular exponentiation costs \(O(\log e)\). The recursion depth is controlled by the totient chain of the modulus, and the tower height is replaced by small explicit heights or by a safe stabilized surrogate. So the runtime is tiny compared with the impossible cost of direct Ackermann evaluation, and memory usage is essentially constant.

Further Reading

  1. Problem page: https://projecteuler.net/problem=282
  2. Ackermann function: https://en.wikipedia.org/wiki/Ackermann_function
  3. Tetration and power towers: https://en.wikipedia.org/wiki/Tetration

Problemzusammenfassung

Project Euler 282 verlangt die modulare Summe

$$\sum_{n=0}^{6}A(n,n)\pmod{14^8},$$

wobei \(A(m,n)\) die Standard-Ackermannfunktion ist:

$$A(0,n)=n+1,$$

$$A(m,0)=A(m-1,1)\quad(m\ge1),$$

$$A(m,n)=A(m-1,A(m,n-1))\quad(m,n\ge1).$$

Das Modul lautet

$$M=14^8=1475789056.$$

Die finale Restklasse wird hier nicht genannt; wichtig ist, wie der Code die riesigen Ackermann-Werte auf einige modulare Turmrechnungen reduziert.

Mathematischer Ansatz

1) Die ersten Ackermann-Schichten haben geschlossene Formen

Aus der Definition folgen die bekannten Identitäten

$$A(0,n)=n+1,$$

$$A(1,n)=n+2,$$

$$A(2,n)=2n+3,$$

$$A(3,n)=2^{n+3}-3.$$

Daraus ergeben sich auf der Diagonale sofort

$$A(0,0)=1,\qquad A(1,1)=3,\qquad A(2,2)=7,\qquad A(3,3)=61.$$

Genau diese Werte liefern solve_n0() bis solve_n3().

2) Von Exponentialen zu Tetration

Wegen

$$A(3,n)=2^{n+3}-3$$

gilt für die nächste Ebene

$$A(4,n+1)=A(3,A(4,n))=2^{A(4,n)+3}-3.$$

Das ist genau die Rekursion eines Potenzturms. In Knuth-Notation:

$$A(4,n)=2\uparrow\uparrow(n+3)-3,$$

wobei

$$2\uparrow\uparrow1=2,\qquad 2\uparrow\uparrow(h+1)=2^{\,2\uparrow\uparrow h}.$$

Insbesondere ist

$$A(4,4)=2\uparrow\uparrow7-3.$$

Darum berechnet solve_n4() genau den Term

$$\texttt{hyper\_tower\_2(7,M)}-3 \pmod M.$$

3) Die nächsten Ackermann-Ebenen sind noch höhere Hyperoperatoren

Das Muster setzt sich fort:

$$A(5,n)=2\uparrow\uparrow\uparrow(n+3)-3,$$

$$A(6,n)=2\uparrow\uparrow\uparrow\uparrow(n+3)-3.$$

Damit sind \(A(5,5)\) und \(A(6,6)\) unvorstellbar groß. Sinnvoll ist nur noch ihre Restklasse modulo \(M\).

4) Was hyper_tower_2(h,m) tatsächlich auswertet

Die Hilfsfunktion berechnet nicht den echten Turm \(2\uparrow\uparrow h\), sondern nur seinen Rest modulo \(m\):

$$T_h(m):=2\uparrow\uparrow h \pmod m.$$

Für kleine Höhen sind die Werte direkt bekannt:

$$T_0(m)=1,\qquad T_1(m)=2,\qquad T_2(m)=4,\qquad T_3(m)=16,\qquad T_4(m)=65536,$$

jeweils modulo \(m\). Diese Basisfälle sind im Code explizit eingebaut.

5) Warum die Rekursion über Euler-\(\varphi\) funktioniert

Für große Höhen möchten wir

$$2^E\pmod m$$

berechnen, wobei \(E=2\uparrow\uparrow(h-1)\) selbst gewaltig ist. Für ungerade Moduli darf man Exponenten modulo \(\varphi(m)\) reduzieren. Hier ist die Basis aber \(2\), also nicht immer teilerfremd zum aktuellen Modul.

Der Code verwendet daher die übliche „angehobene Exponenten“-Strategie:

erst den oberen Exponenten modulo \(\varphi(m)\) berechnen,

dann eine volle Totient-Periode addieren,

und schließlich modulo \(m\) potenzieren.

Formal wird also

$$2^{\,e+\varphi(m)}\pmod m$$

mit

$$e=T_{h-1}(\varphi(m))$$

ausgewertet. Genau das steckt im Code in

$$\texttt{eff\_exponent = exponent\_val + phi}.$$

6) Warum das \(+\varphi(m)\) hier sicher ist

Das ist hier keine blinde Allgemeinaussage für kleine Exponenten. Es ist sicher, weil alle Türme, die in diesen Rekursionszweig gelangen, bereits riesig sind.

Das Modul faktorisiert als

$$M=14^8=2^8\cdot 7^8.$$

Für den \(2^8\)-Anteil genügt bereits

$$E\ge 8,$$

damit

$$2^E\equiv0\pmod{2^8}.$$

Für den ungeraden Anteil \(7^8\) ist \(2\) teilerfremd, also darf der Exponent modulo

$$\varphi(7^8)=6\cdot 7^7$$

reduziert werden. Das Hinzufügen von \(\varphi(m)\) stellt sicher, dass der rekonstruierte Exponent für den Zweieranteil groß genug bleibt, während die richtige Information für den ungeraden Anteil erhalten bleibt.

7) Stabilisierung sehr hoher Türme modulo \(M\)

Die Reste

$$2\uparrow\uparrow h \pmod M$$

werden ab hinreichender Höhe konstant. Mit der im Code verwendeten Rekursion stabilisiert sich der Wert bereits ab Höhe \(11\).

Das bedeutet:

jeder ausreichend hohe Zweierturm hat modulo \(M\) denselben Rest.

Genau dadurch werden die gigantischen Terme \(A(5,5)\) und \(A(6,6)\) überhaupt behandelbar.

8) Warum \(A(5,5)\) und \(A(6,6)\) denselben Ersatzterm verwenden

Es gilt

$$A(5,5)+3=2\uparrow\uparrow\uparrow 8,$$

also eine Tetration, deren Höhe selbst schon astronomisch ist. \(A(6,6)+3\) ist noch ungleich größer.

Da sich die Turmreste modulo \(M\) aber schon ab kleiner Höhe stabilisieren, fallen beide Werte in dieselbe stabile Restklasse. Deshalb darf der Code beide durch

$$2\uparrow\uparrow 200 \pmod M$$

ersetzen. Die Höhe \(200\) ist nicht speziell; sie liegt einfach weit jenseits der Stabilisierungsschwelle.

9) Endgültige Zerlegung der gesuchten Summe

Gesucht ist

$$S=\sum_{n=0}^{6}A(n,n)\pmod M.$$

Die Implementierung zerlegt dies in:

vier kleine exakte Konstanten für \(n=0,1,2,3\);

einen echten Tetrationsterm für \(n=4\), nämlich \(2\uparrow\uparrow7-3\);

zwei identische stabilisierte Großterme für \(n=5\) und \(n=6\).

Code-Logik

1) Schnelle Modpotenz. power() verwendet binäre Exponentiation mit 128-Bit-Zwischenprodukten.

2) Totient-Berechnung. get_phi() faktorisiert den aktuellen Modulus und liefert \(\varphi(m)\).

3) Turmrekursion. hyper_tower_2(height,m) berechnet \(2\uparrow\uparrow\text{height}\pmod m\), indem rekursiv auf \(\varphi(m)\) gewechselt und danach der Exponent um eine Totient-Periode angehoben wird.

4) Ackermann-Schichten. solve_n0() bis solve_n3() liefern exakte Konstanten; solve_n4() liefert den \(A(4,4)\)-Rest; solve_large_n() liefert den stabilisierten Großrest für \(A(5,5)\) und \(A(6,6)\).

5) Endsumme. In main() werden die sieben Bausteine separat berechnet und modulo \(M\) addiert.

Komplexitätsanalyse

Jede modulare Potenzierung kostet \(O(\log e)\). Die Rekursionstiefe wird durch die Totient-Kette des Moduls begrenzt, und die effektiven Turmhöhen werden durch kleine exakte Basisfälle oder eine stabile Ersatzhöhe abgeschnitten. Damit bleibt die Laufzeit winzig, verglichen mit jeder direkten Ackermann-Auswertung, und der Speicherbedarf ist praktisch konstant.

Weiterführende Hinweise

  1. Problem: https://projecteuler.net/problem=282
  2. Ackermann-Funktion: https://de.wikipedia.org/wiki/Ackermannfunktion
  3. Tetration: https://de.wikipedia.org/wiki/Tetration

Problem Özeti

Project Euler 282,

$$\sum_{n=0}^{6} A(n,n)\pmod{14^8}$$

toplamını ister; burada \(A(m,n)\) standart Ackermann fonksiyonudur:

$$A(0,n)=n+1,$$

$$A(m,0)=A(m-1,1)\quad(m\ge1),$$

$$A(m,n)=A(m-1,A(m,n-1))\quad(m,n\ge1).$$

Modül

$$M=14^8=1475789056$$

olur. Nihai kalıntı burada verilmez; amaç, kodun dev Ackermann değerlerini nasıl küçük bir modüler üs kulesi hesabına indirdiğini açıklamaktır.

Matematiksel Yaklaşım

1) İlk Ackermann katmanlarının kapalı biçimleri vardır

Tanımdan şu klasik özdeşlikler çıkar:

$$A(0,n)=n+1,$$

$$A(1,n)=n+2,$$

$$A(2,n)=2n+3,$$

$$A(3,n)=2^{n+3}-3.$$

Bu yüzden diyagonalda hemen

$$A(0,0)=1,\qquad A(1,1)=3,\qquad A(2,2)=7,\qquad A(3,3)=61$$

elde edilir. Kodda solve_n0() ile solve_n3() tam olarak bu sabitleri döndürür.

2) Üstel ifadelerden tetrasyona geçiş

\(A(3,n)=2^{n+3}-3\) olduğundan

$$A(4,n+1)=A(3,A(4,n))=2^{A(4,n)+3}-3$$

yazılır. Bu, tam olarak üs kulesi özyinelemesidir. Knuth ok gösterimiyle:

$$A(4,n)=2\uparrow\uparrow(n+3)-3,$$

burada

$$2\uparrow\uparrow1=2,\qquad 2\uparrow\uparrow(h+1)=2^{\,2\uparrow\uparrow h}.$$

Özellikle

$$A(4,4)=2\uparrow\uparrow7-3$$

olur. Bu yüzden solve_n4() içinde

$$\texttt{hyper\_tower\_2(7,M)}-3 \pmod M$$

hesaplanır.

3) Sonraki Ackermann katmanları daha yüksek hiperoperasyonlardır

Örüntü devam eder:

$$A(5,n)=2\uparrow\uparrow\uparrow(n+3)-3,$$

$$A(6,n)=2\uparrow\uparrow\uparrow\uparrow(n+3)-3.$$

Dolayısıyla \(A(5,5)\) ve \(A(6,6)\) “çok büyük” değil, pratik olarak temsil edilemez kadar büyük sayılardır. Tek makul hedef bunların mod \(M\) altındaki kalıntılarıdır.

4) hyper_tower_2(h,m) gerçekte ne hesaplar?

Bu yardımcı fonksiyon, gerçek \(2\uparrow\uparrow h\) değerini kurmaz; yalnızca onun mod \(m\) kalıntısını hesaplar:

$$T_h(m):=2\uparrow\uparrow h \pmod m.$$

Küçük yükseklikler için değerler doğrudan bilinir:

$$T_0(m)=1,\qquad T_1(m)=2,\qquad T_2(m)=4,\qquad T_3(m)=16,\qquad T_4(m)=65536,$$

tabii hepsi mod \(m\) altında. Kodun base case’leri bunları açıkça kullanır.

5) Euler-\(\varphi\) özyinelemesi neden doğru araç?

Yüksek kulelerde hesaplamak istediğimiz şey

$$2^E\pmod m$$

şeklindedir; burada \(E=2\uparrow\uparrow(h-1)\) zaten devasa büyüktür. Taban \(2\) olduğundan modül her zaman eş-asal olmayabilir; bu yüzden sıradan Euler indirgemesini körlemesine uygulamak yetmez.

Kod şu “kaldırılmış üs” stratejisini kullanır:

1. üstteki üssü \(\varphi(m)\) modunda hesapla,

2. bir tam totient periyodu ekle,

3. sonra mod \(m\) altında üsle.

Formel olarak, büyük kuleler için

$$2^{\,e+\varphi(m)}\pmod m$$

hesaplanır; burada

$$e=T_{h-1}(\varphi(m)).$$

Koddaki

$$\texttt{eff\_exponent = exponent\_val + phi}$$

satırı tam olarak budur.

6) \(+\varphi(m)\) düzeltmesi neden bu problemde güvenlidir?

Bu düzeltme, küçük üsler için evrensel bir sihirli kural olarak kullanılmıyor. Burada güvenli olmasının sebebi, bu dala giren bütün kule yüksekliklerinin zaten aşırı büyük olmasıdır.

Modülün çarpanlara ayrılması

$$M=14^8=2^8\cdot 7^8$$

şeklindedir. \(2^8\) kısmı için üs

$$E\ge 8$$

olduğu anda

$$2^E\equiv0\pmod{2^8}$$

olur. Tek sayılı kısım olan \(7^8\) için ise taban \(2\) eş-asaldır; dolayısıyla üs,

$$\varphi(7^8)=6\cdot 7^7$$

modunda indirgenebilir.

\(\varphi(m)\) eklemek, yeniden kurulan üssün \(2\)-adic kısım için yeterince büyük kalmasını sağlarken, tek sayılı kısım için gerekli modüler bilgiyi de korur. Bu problemde gerçek üsler zaten 8’in çok çok üzerindedir; dolayısıyla bu kaldırma doğru kalıntıyı verir.

7) Çok yüksek kulelerin mod \(M\) altında stabilizasyonu

Şu kalıntılar

$$2\uparrow\uparrow h \pmod M$$

yeterince büyük \(h\) için sabitlenir. Kodun kullandığı özyineleme ile bu stabilizasyonun yükseklik \(11\) civarında oluştuğu doğrudan görülebilir.

Yani:

yeterince yüksek bütün 2 tabanlı üs kuleleri mod \(M\) altında aynı kalıntıya iner.

İşte \(A(5,5)\) ve \(A(6,6)\) terimlerini yönetilebilir yapan şey budur.

8) \(A(5,5)\) ve \(A(6,6)\) neden aynı vekil yükseklikle hesaplanıyor?

Şuna dikkat edin:

$$A(5,5)+3=2\uparrow\uparrow\uparrow 8.$$

Bu, yüksekliği kendi başına astronomik olan bir tetrasyon anlamına gelir. \(A(6,6)+3\) ise bundan da çok daha büyüktür.

Fakat mod \(M\) altında kule kalıntıları zaten küçük bir yükseklikten sonra sabitlendiği için, bu iki değer aynı kararlı kalıntı sınıfına düşer. Bu yüzden kod her ikisini de güvenli bir vekil olarak

$$2\uparrow\uparrow 200 \pmod M$$

ile temsil eder. \(200\) sayısının özel bir anlamı yoktur; yalnızca stabilizasyon eşiğinin çok üstündedir.

Bu nedenle solve_large_n() iki kez çağrılır: biri \(A(5,5)\), biri \(A(6,6)\) için.

9) İstenen toplamın son ayrıştırması

Aranan ifade

$$S=\sum_{n=0}^{6}A(n,n)\pmod M$$

olduğundan, implementasyon bunu şu parçalara ayırır:

\(n=0,1,2,3\) için dört küçük sabit;

\(n=4\) için tek gerçek tetrasyon terimi, yani \(2\uparrow\uparrow7-3\);

\(n=5\) ve \(n=6\) için iki adet aynı stabilize büyük-terim kalıntısı.

Böylece bütün problem, gerçek Ackermann büyümesini üretmeden birkaç modüler kule hesabına indirgenmiş olur.

Kodun Mantığı

1) Hızlı modüler üs alma. power(), 128-bit ara çarpımlarla binary exponentiation uygular.

2) Totient hesabı. get_phi() mevcut modülü çarpanlarına ayırıp \(\varphi(m)\) döndürür.

3) Kule özyinelemesi. hyper_tower_2(height,m), \(2\uparrow\uparrow\text{height}\pmod m\) değerini, \(\varphi(m)\)’ye inip sonra üssü bir totient periyodu kadar kaldırarak hesaplar.

4) Ackermann katmanları. solve_n0()-solve_n3() tam sabitleri, solve_n4() \(A(4,4)\) kalıntısını, solve_large_n() ise \(A(5,5)\) ve \(A(6,6)\) için ortak stabilize kalıntıyı üretir.

5) Son toplam. main() yedi bileşeni ayrı hesaplatır ve mod \(M\) altında toplar.

Karmaşıklık Analizi

Her modüler üs alma \(O(\log e)\) zamandadır. Özyineleme derinliği modülün totient zinciriyle sınırlıdır; kule yükseklikleri ya küçük kapalı durumlarla ya da stabilize güvenli vekillerle kesildiği için toplam süre çok küçüktür. Doğrudan Ackermann hesaplamasıyla karşılaştırıldığında bu yaklaşım pratikte sabit maliyetlidir.

İleri Okuma

  1. Problem metni: https://projecteuler.net/problem=282
  2. Ackermann fonksiyonu: https://tr.wikipedia.org/wiki/Ackermann_fonksiyonu
  3. Tetrasyon: https://en.wikipedia.org/wiki/Tetration

Resumen del Problema

Project Euler 282 pide la suma modular

$$\sum_{n=0}^{6}A(n,n)\pmod{14^8},$$

donde \(A(m,n)\) es la función de Ackermann estándar:

$$A(0,n)=n+1,$$

$$A(m,0)=A(m-1,1)\quad(m\ge1),$$

$$A(m,n)=A(m-1,A(m,n-1))\quad(m,n\ge1).$$

El módulo es

$$M=14^8=1475789056.$$

Aquí no se muestra el residuo final; interesa entender cómo el código sustituye valores de Ackermann imposibles de construir por unas pocas evaluaciones modulares de torres de potencias.

Enfoque Matemático

1) Las primeras capas de Ackermann tienen forma cerrada

De la definición se obtienen las identidades clásicas

$$A(0,n)=n+1,$$

$$A(1,n)=n+2,$$

$$A(2,n)=2n+3,$$

$$A(3,n)=2^{n+3}-3.$$

Por tanto, en la diagonal aparecen inmediatamente

$$A(0,0)=1,\qquad A(1,1)=3,\qquad A(2,2)=7,\qquad A(3,3)=61.$$

Éstos son los valores exactos que devuelven solve_n0() hasta solve_n3().

2) De exponenciales a tetración

Como

$$A(3,n)=2^{n+3}-3,$$

la siguiente capa satisface

$$A(4,n+1)=A(3,A(4,n))=2^{A(4,n)+3}-3.$$

Eso es exactamente la recursión de una torre de potencias. En notación de Knuth,

$$A(4,n)=2\uparrow\uparrow(n+3)-3,$$

donde

$$2\uparrow\uparrow1=2,\qquad 2\uparrow\uparrow(h+1)=2^{\,2\uparrow\uparrow h}.$$

En particular,

$$A(4,4)=2\uparrow\uparrow7-3.$$

Por eso solve_n4() calcula

$$\texttt{hyper\_tower\_2(7,M)}-3 \pmod M.$$

3) Las siguientes capas son hiperoperadores aún más altos

El patrón continúa:

$$A(5,n)=2\uparrow\uparrow\uparrow(n+3)-3,$$

$$A(6,n)=2\uparrow\uparrow\uparrow\uparrow(n+3)-3.$$

Así, \(A(5,5)\) y \(A(6,6)\) ya no son simplemente enormes; están mucho más allá de cualquier representación directa. Solo tiene sentido su residuo módulo \(M\).

4) Qué calcula realmente hyper_tower_2(h,m)

La función auxiliar no construye la torre real \(2\uparrow\uparrow h\). Solo calcula su residuo módulo \(m\):

$$T_h(m):=2\uparrow\uparrow h \pmod m.$$

Para alturas pequeñas, los valores son explícitos:

$$T_0(m)=1,\qquad T_1(m)=2,\qquad T_2(m)=4,\qquad T_3(m)=16,\qquad T_4(m)=65536,$$

siempre tomados módulo \(m\). Estos casos base están codificados directamente.

5) Por qué la recursión con Euler-\(\varphi\) es la reducción correcta

Para alturas grandes queremos evaluar

$$2^E\pmod m,$$

donde \(E=2\uparrow\uparrow(h-1)\) es gigantesco. Para módulos impares, se puede reducir el exponente módulo \(\varphi(m)\). Aquí la base es \(2\), así que no siempre es coprima con el módulo.

Por eso el código usa la estrategia estándar de “exponente levantado”:

1. calcular el exponente superior módulo \(\varphi(m)\);

2. sumar una vuelta completa de la función totiente;

3. exponentiar módulo \(m\).

Formalmente, para estas torres enormes se evalúa

$$2^{\,e+\varphi(m)}\pmod m,$$

con

$$e=T_{h-1}(\varphi(m)).$$

Eso es exactamente la línea

$$\texttt{eff\_exponent = exponent\_val + phi}.$$

6) Por qué el desplazamiento \(+\varphi(m)\) es seguro aquí

No se está usando como una afirmación universal para exponentes pequeños. Aquí es correcto porque todas las torres que entran en esa rama ya son enormes.

El módulo se factoriza como

$$M=14^8=2^8\cdot 7^8.$$

Para la parte \(2^8\), basta con que

$$E\ge 8$$

para tener

$$2^E\equiv0\pmod{2^8}.$$

Para la parte impar \(7^8\), la base \(2\) es coprima, así que puede reducirse el exponente módulo

$$\varphi(7^8)=6\cdot 7^7.$$

Sumar \(\varphi(m)\) garantiza que el exponente reconstruido siga siendo suficientemente grande para la parte \(2\)-ádica, mientras conserva la información correcta para la parte impar. Como los exponentes reales del problema son muchísimo mayores que \(8\), este levantamiento produce el residuo correcto.

7) Estabilización de torres muy altas módulo \(M\)

Los residuos

$$2\uparrow\uparrow h \pmod M$$

acaban estabilizándose. Con la recursión implementada por el código, el valor ya deja de cambiar a partir de la altura \(11\).

Eso significa que:

cualquier torre suficientemente alta de base 2 tiene el mismo residuo módulo \(M\).

Ésta es la idea clave que hace manejables \(A(5,5)\) y \(A(6,6)\).

8) Por qué \(A(5,5)\) y \(A(6,6)\) usan el mismo sustituto de altura

Se tiene

$$A(5,5)+3=2\uparrow\uparrow\uparrow 8,$$

es decir, una tetración cuya altura ya es astronómica. \(A(6,6)+3\) es muchísimo mayor todavía.

Como los residuos de torres módulo \(M\) ya se han estabilizado a alturas modestas, ambos valores caen en la misma clase residual estable. Por eso el código puede reemplazarlos por

$$2\uparrow\uparrow 200 \pmod M$$

como altura sustituta segura. El número \(200\) no tiene nada mágico; simplemente está muy por encima del umbral de estabilización.

9) Descomposición final de la suma buscada

La cantidad pedida es

$$S=\sum_{n=0}^{6}A(n,n)\pmod M.$$

La implementación la divide en:

cuatro constantes pequeñas exactas para \(n=0,1,2,3\);

un único término genuino de tetración para \(n=4\), a saber \(2\uparrow\uparrow7-3\);

dos residuos gigantes estabilizados e idénticos para \(n=5\) y \(n=6\).

Lógica del Código

1) Potencia modular rápida. power() usa exponenciación binaria con multiplicación intermedia de 128 bits.

2) Función totiente. get_phi() factoriza el módulo actual y devuelve \(\varphi(m)\).

3) Recursión de torres. hyper_tower_2(height,m) evalúa \(2\uparrow\uparrow\text{height}\pmod m\) recurriendo al módulo \(\varphi(m)\) y levantando luego el exponente en una totiente.

4) Capas de Ackermann. solve_n0() a solve_n3() devuelven constantes exactas; solve_n4() devuelve el residuo de \(A(4,4)\); solve_large_n() devuelve el residuo estabilizado usado para \(A(5,5)\) y \(A(6,6)\).

5) Suma final. La función principal calcula por separado los siete bloques y los suma módulo \(M\).

Complejidad

Cada exponenciación modular cuesta \(O(\log e)\). La profundidad recursiva queda controlada por la cadena de totientes del módulo, y las alturas efectivas de las torres se reemplazan por casos base pequeños o por una altura sustituta ya estabilizada. Por eso el tiempo es minúsculo comparado con cualquier intento de expandir Ackermann directamente, y la memoria usada es esencialmente constante.

Lecturas

  1. Problema: https://projecteuler.net/problem=282
  2. Función de Ackermann: https://es.wikipedia.org/wiki/Función_de_Ackermann
  3. Tetración: https://es.wikipedia.org/wiki/Tetración

问题概述

Project Euler 282 要求计算

$$\sum_{n=0}^{6}A(n,n)\pmod{14^8},$$

其中 \(A(m,n)\) 是标准 Ackermann 函数:

$$A(0,n)=n+1,$$

$$A(m,0)=A(m-1,1)\quad(m\ge1),$$

$$A(m,n)=A(m-1,A(m,n-1))\quad(m,n\ge1).$$

模数是

$$M=14^8=1475789056.$$

这里不直接给出最终余数;重点是解释代码为何能在完全不构造巨大 Ackermann 值的前提下得到正确的模结果。

数学方法

1) 前几层 Ackermann 有闭式

由定义可以推出经典恒等式:

$$A(0,n)=n+1,$$

$$A(1,n)=n+2,$$

$$A(2,n)=2n+3,$$

$$A(3,n)=2^{n+3}-3.$$

因此对角线上前几项立即得到

$$A(0,0)=1,\qquad A(1,1)=3,\qquad A(2,2)=7,\qquad A(3,3)=61.$$

这正是代码中 solve_n0()solve_n3() 返回的常数。

2) 从指数函数进入 tetration

因为

$$A(3,n)=2^{n+3}-3,$$

所以下一层满足

$$A(4,n+1)=A(3,A(4,n))=2^{A(4,n)+3}-3.$$

这正是幂塔递推。用 Knuth 箭号表示,

$$A(4,n)=2\uparrow\uparrow(n+3)-3,$$

其中

$$2\uparrow\uparrow1=2,\qquad 2\uparrow\uparrow(h+1)=2^{\,2\uparrow\uparrow h}.$$

特别地,

$$A(4,4)=2\uparrow\uparrow7-3.$$

因此 solve_n4() 正是在计算

$$\texttt{hyper\_tower\_2(7,M)}-3 \pmod M.$$

3) 更高 Ackermann 层就是更高超运算

这个模式继续向上:

$$A(5,n)=2\uparrow\uparrow\uparrow(n+3)-3,$$

$$A(6,n)=2\uparrow\uparrow\uparrow\uparrow(n+3)-3.$$

因此 \(A(5,5)\) 和 \(A(6,6)\) 已经远远超出任何直接表示范围,唯一合理目标就是它们模 \(M\) 的余数。

4) hyper_tower_2(h,m) 真正计算的是什么

这个辅助函数并不去构造真实的 \(2\uparrow\uparrow h\),而只计算它对 \(m\) 的余数:

$$T_h(m):=2\uparrow\uparrow h \pmod m.$$

对于较小高度,值可直接写出:

$$T_0(m)=1,\qquad T_1(m)=2,\qquad T_2(m)=4,\qquad T_3(m)=16,\qquad T_4(m)=65536,$$

都按模 \(m\) 取值。代码里把这些作为 base case。

5) 为什么要用 Euler-\(\varphi\) 递归降模

当高度很大时,我们要算的是

$$2^E\pmod m,$$

其中 \(E=2\uparrow\uparrow(h-1)\) 本身已经极大。对奇模数时,可以把指数模 \(\varphi(m)\) 约化;但这里底数是 \(2\),不一定总与当前模数互素,所以不能不加说明地直接套用。

代码采用的是常见的“抬高指数”策略:

1. 先在 \(\varphi(m)\) 下递归计算上层指数;

2. 再加上一整圈 totient 周期;

3. 最后对 \(m\) 做快速幂。

形式上就是对巨大幂塔计算

$$2^{\,e+\varphi(m)}\pmod m,$$

其中

$$e=T_{h-1}(\varphi(m)).$$

这正对应代码中的

$$\texttt{eff\_exponent = exponent\_val + phi}.$$

6) 为什么在这里加上 \(+\varphi(m)\) 是安全的

这里并不是把它当成对任意小指数都成立的万能定理来用。它之所以安全,是因为进入这个递归分支的所有幂塔都已经极高。

模数分解为

$$M=14^8=2^8\cdot 7^8.$$

对 \(2^8\) 这一部分,只要指数满足

$$E\ge 8,$$

就已经有

$$2^E\equiv0\pmod{2^8}.$$

而对奇数部分 \(7^8\),底数 \(2\) 与它互素,所以指数可以模

$$\varphi(7^8)=6\cdot 7^7$$

约化。

加上 \(\varphi(m)\) 可以确保重建出的指数对 \(2\)-进部分足够大,同时对奇数部分保留正确的同余信息。由于本题中的真实指数远远大于 \(8\),这种“抬高”与真实幂塔余数一致。

7) 很高的 2 幂塔在模 \(M\) 下会稳定

序列

$$2\uparrow\uparrow h \pmod M$$

在高度足够大后会稳定下来。按代码采用的递归方式,到了高度 \(11\) 左右就已经不再变化。

这意味着:

任何足够高的 2 幂塔,在模 \(M\) 下都有同一个余数。

这正是 \(A(5,5)\) 和 \(A(6,6)\) 变得可处理的核心原因。

8) 为什么 \(A(5,5)\) 与 \(A(6,6)\) 可以用同一个代理高度

注意

$$A(5,5)+3=2\uparrow\uparrow\uparrow 8,$$

也就是“高度本身已经天文级别”的 tetration。至于 \(A(6,6)+3\),则更是远大得多。

但由于模 \(M\) 下幂塔余数在较小高度后就稳定,因此这两个值都会落入同一个稳定余数类。于是代码可以把它们都安全地替换成

$$2\uparrow\uparrow 200 \pmod M$$

作为代理高度。这里的 \(200\) 没有特殊数学意义,只是远远超过稳定阈值。

9) 最终所求和式的拆分

题目要的是

$$S=\sum_{n=0}^{6}A(n,n)\pmod M.$$

实现中把它拆成:

\(n=0,1,2,3\) 的四个小常数;

\(n=4\) 的一个真实 tetration 项,即 \(2\uparrow\uparrow7-3\);

\(n=5\) 与 \(n=6\) 的两个相同稳定大项余数。

这样整个问题就变成了少量模幂塔计算,而不是直接面对 Ackermann 的原始爆炸性增长。

代码逻辑

1) 快速幂。 power() 用二进制快速幂和 128 位中间乘法实现模幂计算。

2) Totient 计算。 get_phi() 对当前模数做因子分解并返回 \(\varphi(m)\)。

3) 幂塔递归。 hyper_tower_2(height,m) 通过递归到 \(\varphi(m)\) 并在最后把指数抬高一个 totient 周期,来计算 \(2\uparrow\uparrow\text{height}\pmod m\)。

4) Ackermann 各层。 solve_n0()solve_n3() 返回精确小常数,solve_n4() 返回 \(A(4,4)\) 的模余数,solve_large_n() 返回 \(A(5,5)\) 和 \(A(6,6)\) 共用的稳定余数。

5) 最终求和。 主函数把七个部分分别算出后,在模 \(M\) 下求和。

复杂度分析

每次模幂计算的代价是 \(O(\log e)\)。递归深度由模数的 totient 链控制,而幂塔高度要么落在很小的显式基例中,要么被安全地替换成已经稳定的代理高度。因此运行时间极小,内存也基本是常数级,远远优于任何直接展开 Ackermann 的做法。

延伸阅读

  1. 题目页面: https://projecteuler.net/problem=282
  2. Ackermann 函数: https://zh.wikipedia.org/wiki/阿克曼函数
  3. Tetration: https://zh.wikipedia.org/wiki/四重幂运算

Краткое описание

Project Euler 282 требует вычислить

$$\sum_{n=0}^{6}A(n,n)\pmod{14^8},$$

где \(A(m,n)\) — стандартная функция Аккермана:

$$A(0,n)=n+1,$$

$$A(m,0)=A(m-1,1)\quad(m\ge1),$$

$$A(m,n)=A(m-1,A(m,n-1))\quad(m,n\ge1).$$

Модуль равен

$$M=14^8=1475789056.$$

Окончательный остаток здесь не приводится; цель — объяснить, как программа заменяет чудовищные значения Аккермана несколькими модульными вычислениями башен степеней.

Математический подход

1) Первые слои Аккермана имеют замкнутые формы

Из определения следуют стандартные тождества

$$A(0,n)=n+1,$$

$$A(1,n)=n+2,$$

$$A(2,n)=2n+3,$$

$$A(3,n)=2^{n+3}-3.$$

Следовательно, по диагонали сразу получаем

$$A(0,0)=1,\qquad A(1,1)=3,\qquad A(2,2)=7,\qquad A(3,3)=61.$$

Именно эти константы возвращают solve_n0()solve_n3().

2) От экспонент к тетрации

Поскольку

$$A(3,n)=2^{n+3}-3,$$

то следующая ступень удовлетворяет

$$A(4,n+1)=A(3,A(4,n))=2^{A(4,n)+3}-3.$$

Это ровно рекурсия башни степеней. В нотации Кнута:

$$A(4,n)=2\uparrow\uparrow(n+3)-3,$$

где

$$2\uparrow\uparrow1=2,\qquad 2\uparrow\uparrow(h+1)=2^{\,2\uparrow\uparrow h}.$$

В частности,

$$A(4,4)=2\uparrow\uparrow7-3.$$

Поэтому solve_n4() считает именно

$$\texttt{hyper\_tower\_2(7,M)}-3 \pmod M.$$

3) Следующие уровни — еще более высокие гипероперации

Дальше шаблон продолжается:

$$A(5,n)=2\uparrow\uparrow\uparrow(n+3)-3,$$

$$A(6,n)=2\uparrow\uparrow\uparrow\uparrow(n+3)-3.$$

Поэтому \(A(5,5)\) и \(A(6,6)\) уже настолько велики, что их нельзя даже мысленно “посчитать напрямую”. Реальный объект вычисления — только остаток по модулю \(M\).

4) Что действительно вычисляет hyper_tower_2(h,m)

Эта вспомогательная функция не строит настоящий \(2\uparrow\uparrow h\). Она вычисляет только его остаток по модулю \(m\):

$$T_h(m):=2\uparrow\uparrow h \pmod m.$$

Для малых высот значения известны явно:

$$T_0(m)=1,\qquad T_1(m)=2,\qquad T_2(m)=4,\qquad T_3(m)=16,\qquad T_4(m)=65536,$$

все по модулю \(m\). Эти базовые случаи и зашиты в коде.

5) Почему редукция через Euler-\(\varphi\) здесь естественна

Для больших высот нужно вычислять

$$2^E\pmod m,$$

где \(E=2\uparrow\uparrow(h-1)\) само по себе огромно. Для нечётных модулей можно сокращать показатель по \(\varphi(m)\). Но здесь основание равно \(2\), так что взаимная простота соблюдается не всегда.

Поэтому программа использует стандартную стратегию “поднятого показателя”:

1. вычислить верхний показатель по модулю \(\varphi(m)\);

2. прибавить один полный тотентный период;

3. возвести в степень по модулю \(m\).

То есть фактически для гигантских башен считается

$$2^{\,e+\varphi(m)}\pmod m,$$

где

$$e=T_{h-1}(\varphi(m)).$$

Это и есть строка

$$\texttt{eff\_exponent = exponent\_val + phi}.$$

6) Почему прибавление \(+\varphi(m)\) здесь корректно

Здесь это не используется как универсальная формула для маленьких показателей. Корректность обеспечивается тем, что все башни, попадающие в рекурсивную ветвь, уже чрезвычайно высоки.

Модуль раскладывается как

$$M=14^8=2^8\cdot 7^8.$$

Для части \(2^8\) достаточно, чтобы

$$E\ge 8,$$

тогда

$$2^E\equiv0\pmod{2^8}.$$

Для нечётной части \(7^8\) число \(2\) взаимно просто с модулем, значит показатель можно редуцировать по

$$\varphi(7^8)=6\cdot 7^7.$$

Прибавление \(\varphi(m)\) гарантирует, что восстановленный показатель остаётся “достаточно большим” для двоичной части и одновременно хранит правильную информацию для нечётной части. А в нашей задаче истинные показатели несравнимо больше \(8\).

7) Стабилизация высоких башен по модулю \(M\)

Последовательность остатков

$$2\uparrow\uparrow h \pmod M$$

при больших \(h\) стабилизируется. Для рекурсии, используемой в коде, это происходит уже примерно с высоты \(11\).

Значит:

любая достаточно высокая башня из двоек имеет один и тот же остаток по модулю \(M\).

Это и позволяет работать с \(A(5,5)\) и \(A(6,6)\).

8) Почему \(A(5,5)\) и \(A(6,6)\) заменяются одной и той же суррогатной высотой

Имеем

$$A(5,5)+3=2\uparrow\uparrow\uparrow 8,$$

то есть тетрацию, высота которой сама уже астрономична. \(A(6,6)+3\) ещё намного больше.

Но так как остатки башен по модулю \(M\) стабилизируются на малых высотах, оба этих значения попадают в один и тот же стабильный класс остатков. Поэтому код может безопасно подставить вместо них

$$2\uparrow\uparrow 200 \pmod M$$

как суррогатную высоту. Число \(200\) не имеет особого математического смысла — оно просто намного выше порога стабилизации.

9) Конечная декомпозиция требуемой суммы

Нужно вычислить

$$S=\sum_{n=0}^{6}A(n,n)\pmod M.$$

Программа разбивает это на:

четыре малые точные константы для \(n=0,1,2,3\);

один настоящий тетрационный член для \(n=4\), а именно \(2\uparrow\uparrow7-3\);

два одинаковых стабилизированных огромных члена для \(n=5\) и \(n=6\).

Логика кода

1) Быстрое модульное возведение в степень. power() использует бинарное возведение в степень и 128-битные промежуточные произведения.

2) Вычисление тотента. get_phi() факторизует текущий модуль и возвращает \(\varphi(m)\).

3) Рекурсия башен. hyper_tower_2(height,m) вычисляет \(2\uparrow\uparrow\text{height}\pmod m\), рекурсируя к модулю \(\varphi(m)\) и затем поднимая показатель на одну тотентную длину.

4) Слои Аккермана. solve_n0()solve_n3() возвращают точные константы; solve_n4() даёт остаток для \(A(4,4)\); solve_large_n() возвращает стабилизированный остаток, используемый и для \(A(5,5)\), и для \(A(6,6)\).

5) Финальная сумма. В main() семь компонент вычисляются отдельно и суммируются по модулю \(M\).

Анализ сложности

Каждое модульное возведение в степень стоит \(O(\log e)\). Глубина рекурсии ограничена тотентной цепочкой модуля, а реальные высоты башен заменяются либо явными малыми базами, либо безопасной стабилизированной высотой. Поэтому время работы ничтожно по сравнению с невозможной прямой оценкой Аккермана, а память практически постоянна.

Дополнительные материалы

  1. Условие: https://projecteuler.net/problem=282
  2. Функция Аккермана: https://ru.wikipedia.org/wiki/Функция_Аккермана
  3. Тетрация: https://ru.wikipedia.org/wiki/Тетрация

ملخص المسألة

تطلب مسألة Project Euler 282 حساب

$$\sum_{n=0}^{6}A(n,n)\pmod{14^8},$$

حيث \(A(m,n)\) هي دالة Ackermann القياسية:

$$A(0,n)=n+1,$$

$$A(m,0)=A(m-1,1)\quad(m\ge1),$$

$$A(m,n)=A(m-1,A(m,n-1))\quad(m,n\ge1).$$

والمودولو هو

$$M=14^8=1475789056.$$

لا نعرض الباقي النهائي هنا؛ المهم هو فهم كيف يحول الكود قيم Ackermann الهائلة إلى عدد قليل من حسابات أبراج الأسس المعيارية.

المنهج الرياضي

1) الطبقات الأولى من Ackermann لها صيغ مغلقة

من التعريف نحصل على الهويات المعروفة

$$A(0,n)=n+1,$$

$$A(1,n)=n+2,$$

$$A(2,n)=2n+3,$$

$$A(3,n)=2^{n+3}-3.$$

ومن ثم تكون القيم القطرية الأولى

$$A(0,0)=1,\qquad A(1,1)=3,\qquad A(2,2)=7,\qquad A(3,3)=61.$$

وهذه هي بالضبط الثوابت التي تعيدها الدوال solve_n0() حتى solve_n3().

2) من الأسّيات إلى tetration

بما أن

$$A(3,n)=2^{n+3}-3,$$

فإن المستوى التالي يحقق

$$A(4,n+1)=A(3,A(4,n))=2^{A(4,n)+3}-3.$$

وهذا هو بالضبط تكرار برج قوى. وبترميز Knuth:

$$A(4,n)=2\uparrow\uparrow(n+3)-3,$$

حيث

$$2\uparrow\uparrow1=2,\qquad 2\uparrow\uparrow(h+1)=2^{\,2\uparrow\uparrow h}.$$

وعلى وجه الخصوص

$$A(4,4)=2\uparrow\uparrow7-3.$$

ولهذا تحسب solve_n4() المقدار

$$\texttt{hyper\_tower\_2(7,M)}-3 \pmod M.$$

3) المستويات الأعلى هي Hyper-operators أعلى

يستمر النمط على النحو الآتي:

$$A(5,n)=2\uparrow\uparrow\uparrow(n+3)-3,$$

$$A(6,n)=2\uparrow\uparrow\uparrow\uparrow(n+3)-3.$$

إذن \(A(5,5)\) و\(A(6,6)\) ليسا “كبيرين جدًا” فقط، بل خارجين تمامًا عن أي تمثيل مباشر عملي. الشيء المعقول الوحيد هو حساب الباقي modulo \(M\).

4) ما الذي تحسبه hyper_tower_2(h,m) فعلًا؟

هذه الدالة لا تبني القيمة الحقيقية لـ \(2\uparrow\uparrow h\)، بل تحسب فقط بقاياها modulo \(m\):

$$T_h(m):=2\uparrow\uparrow h \pmod m.$$

أما الارتفاعات الصغيرة فلها قيم صريحة:

$$T_0(m)=1,\qquad T_1(m)=2,\qquad T_2(m)=4,\qquad T_3(m)=16,\qquad T_4(m)=65536,$$

كل ذلك modulo \(m\). وهذه الحالات الأساسية موجودة صراحة في الكود.

5) لماذا يعمل الاختزال التكراري عبر Euler-\(\varphi\)؟

عند الارتفاعات الكبيرة نريد حساب

$$2^E\pmod m,$$

حيث \(E=2\uparrow\uparrow(h-1)\) هائل بدوره. في المودولات الفردية يمكن اختزال الأس modulo \(\varphi(m)\)، لكن هنا الأساس هو \(2\)، وبالتالي لا توجد المرافقة التوافقية دائمًا.

لهذا يستخدم الكود استراتيجية “الأس المرفوع” المعتادة:

1. احسب الأس العلوي modulo \(\varphi(m)\)،

2. أضف دورة totient كاملة،

3. ثم ارفع \(2\) إلى هذا الأس modulo \(m\).

أي أنه يحسب فعليًا، في هذه الأبراج الضخمة،

$$2^{\,e+\varphi(m)}\pmod m,$$

حيث

$$e=T_{h-1}(\varphi(m)).$$

وهذا هو بالضبط ما يفعله السطر

$$\texttt{eff\_exponent = exponent\_val + phi}.$$

6) لماذا تكون إضافة \(+\varphi(m)\) آمنة هنا؟

ليست هذه حيلة عامة لكل أس صغير. هي صحيحة هنا لأن كل الأبراج التي تصل إلى هذا الفرع التكراري كبيرة جدًا أصلًا.

نفكك المودولو:

$$M=14^8=2^8\cdot 7^8.$$

بالنسبة للجزء \(2^8\)، يكفي أن يكون

$$E\ge 8$$

كي نحصل على

$$2^E\equiv0\pmod{2^8}.$$

أما بالنسبة للجزء الفردي \(7^8\)، فإن \(2\) أولي معه، ولذا يمكن اختزال الأس modulo

$$\varphi(7^8)=6\cdot 7^7.$$

إضافة \(\varphi(m)\) تضمن أن يظل الأس المعاد بناؤه “كبيرًا بما يكفي” للجزء الثنائي، مع الاحتفاظ بالمعلومة الصحيحة للجزء الفردي. وبما أن الأسس الحقيقية في هذه المسألة أكبر بكثير من \(8\)، فإن هذه الرفعة تعطي الباقي الصحيح.

7) استقرار الأبراج العالية modulo \(M\)

تتثبت المتتالية

$$2\uparrow\uparrow h \pmod M$$

عند ارتفاع كافٍ. وباستخدام التكرار الموجود في الكود، يصل هذا الاستقرار تقريبًا عند الارتفاع \(11\).

أي إن:

كل برج قوى عالٍ بما يكفي للأساس 2 يمتلك الباقي نفسه modulo \(M\).

وهذا هو السبب الحاسم الذي يجعل \(A(5,5)\) و\(A(6,6)\) قابلين للمعالجة.

8) لماذا يُستبدل \(A(5,5)\) و\(A(6,6)\) بالارتفاع نفسه؟

لدينا

$$A(5,5)+3=2\uparrow\uparrow\uparrow 8,$$

أي tetration يكون ارتفاعها نفسه هائلًا. أما \(A(6,6)+3\) فهو أكبر بكثير من ذلك.

لكن بما أن بقايا الأبراج modulo \(M\) تستقر عند ارتفاع صغير نسبيًا، فإن هاتين القيمتين تسقطان في الفئة المستقرة نفسها. لذلك يستطيع الكود أن يستبدلهما بأمان بـ

$$2\uparrow\uparrow 200 \pmod M$$

كارتفاع بديل. والعدد \(200\) ليس له معنى خاص، بل هو فقط أعلى بكثير من عتبة الاستقرار.

9) التفكيك النهائي للمجموع المطلوب

الكمية المطلوبة هي

$$S=\sum_{n=0}^{6}A(n,n)\pmod M.$$

وتفككها الخوارزمية إلى:

أربع ثوابت صغيرة دقيقة لـ \(n=0,1,2,3\)،

وحدّ tetration حقيقي واحد لـ \(n=4\)، أي \(2\uparrow\uparrow7-3\)،

وحدّين هائلين مستقرين ومتماثلين لـ \(n=5\) و\(n=6\).

منطق الكود

1) الرفع السريع للأس. تستخدم power() الرفع الثنائي مع نواتج وسيطة 128-بت.

2) حساب \(\varphi\). تقوم get_phi() بتحليل المودولو الحالي وإرجاع \(\varphi(m)\).

3) تكرار الأبراج. تحسب hyper_tower_2(height,m) القيمة \(2\uparrow\uparrow\text{height}\pmod m\) عبر النزول إلى \(\varphi(m)\) ثم رفع الأس بمقدار totient واحد.

4) طبقات Ackermann. تعطي solve_n0() إلى solve_n3() ثوابت دقيقة، وتعيد solve_n4() بقايا \(A(4,4)\)، وتعيد solve_large_n() الباقي المستقر المستخدم لكل من \(A(5,5)\) و\(A(6,6)\).

5) الجمع النهائي. تحسب الدالة الرئيسية المكونات السبع كلًّا على حدة ثم تجمعها modulo \(M\).

تحليل التعقيد

كل عملية أس معياري تكلف \(O(\log e)\). ويظل عمق التكرار محدودًا بسلسلة totient الخاصة بالمودولو، بينما تُستبدل الارتفاعات الفعلية للأبراج إما بحالات أساسية صغيرة أو بارتفاع آمن مستقر. لذلك يبقى الزمن صغيرًا جدًا مقارنة بأي محاولة مباشرة لتوليد قيم Ackermann، كما أن الذاكرة تكاد تكون ثابتة.

مراجع إضافية

  1. صفحة المسألة: https://projecteuler.net/problem=282
  2. دالة Ackermann: https://ar.wikipedia.org/wiki/دالة_آكرمان
  3. Tetration: https://en.wikipedia.org/wiki/Tetration