Problem Summary

A modified Collatz process uses three step types \(D,U,d\), chosen by the current value modulo \(3\). For a given long step string and a large lower bound \(L\), we want the smallest starting value \(n>L\) whose trajectory begins with exactly that prescribed prefix. Whatever happens after the prefix is irrelevant.

Mathematical Approach

Let the prescribed prefix be \(s_1s_2\cdots s_m\), where each \(s_i\in\{D,U,d\}\).

1) Forward rules and why brute force is hopeless

The process is deterministic once the residue class modulo \(3\) is known:

$$D:\ x\equiv0\pmod3,\qquad x\mapsto \frac{x}{3},$$

$$U:\ x\equiv1\pmod3,\qquad x\mapsto \frac{4x+2}{3},$$

$$d:\ x\equiv2\pmod3,\qquad x\mapsto \frac{2x-1}{3}.$$

The lower bound in the actual problem is around \(10^{15}\), so testing consecutive starting values forward is not realistic. The correct idea is to reverse the prefix and describe all valid starts in one shot.

2) Inverting a single step

If \(y\) is the value after one step, then the previous value \(x\) must satisfy:

$$D^{-1}:\ x=3y,$$

$$U^{-1}:\ y=\frac{4x+2}{3}\Longrightarrow x=\frac{3y-2}{4},$$

$$d^{-1}:\ y=\frac{2x-1}{3}\Longrightarrow x=\frac{3y+1}{2}.$$

So every reverse step is an affine rational map.

3) Why the reverse formulas already enforce the correct residue class

At first sight, one might worry that the reverse maps only guarantee integrality, not the required modulo \(3\) condition. In fact integrality is enough:

If \(x=(3y-2)/4\in\mathbb Z\), then \(4x+2\) is divisible by \(3\). Since \(4\equiv1\pmod3\), this gives

$$x+2\equiv0\pmod3\Longrightarrow x\equiv1\pmod3.$$

Likewise, if \(x=(3y+1)/2\in\mathbb Z\), then \(2x-1\) is divisible by \(3\). Because \(2\equiv-1\pmod3\),

$$-x-1\equiv0\pmod3\Longrightarrow x\equiv2\pmod3.$$

So once the reverse step yields an integer, it is automatically a valid predecessor for the intended letter.

4) Reverse-composing the whole prefix gives one affine formula

Let \(t\) be the value obtained after the entire prescribed prefix has been executed. Running the prefix backward reconstructs the starting value \(n\). Because each reverse step is affine-rational, the full composition has the shape

$$n=\frac{At+B}{C}$$

for some integers \(A,B,C\) depending only on the prefix.

This is the central structural fact: the infinitely many valid starts are parameterized by a single integer \(t\).

5) Coefficient updates used by the code

Suppose the current reverse formula is

$$x=\frac{At+B}{C}.$$

If the next reverse step is \(D\), then

$$x\mapsto 3x=\frac{3At+3B}{C},$$

so

$$A\leftarrow3A,\qquad B\leftarrow3B,\qquad C\leftarrow C.$$

If the next reverse step is \(U\), then

$$x\mapsto \frac{3x-2}{4}=\frac{3(At+B)-2C}{4C},$$

so

$$A\leftarrow3A,\qquad B\leftarrow3B-2C,\qquad C\leftarrow4C.$$

If the next reverse step is \(d\), then

$$x\mapsto \frac{3x+1}{2}=\frac{3(At+B)+C}{2C},$$

so

$$A\leftarrow3A,\qquad B\leftarrow3B+C,\qquad C\leftarrow2C.$$

The implementation starts from the identity map \(n=t\), that is

$$A=1,\qquad B=0,\qquad C=1,$$

and scans the prefix from right to left.

6) Closed form for \(A\) and \(C\)

Every reverse step multiplies \(A\) by \(3\), so after a prefix of length \(m\),

$$A=3^m.$$

The denominator changes only for \(U\) and \(d\): \(U\) multiplies \(C\) by \(4=2^2\), and \(d\) multiplies \(C\) by \(2\). Therefore

$$C=2^{\,2\#U+\#d}.$$

In particular,

$$\gcd(A,C)=1.$$

This is why the congruence step in this problem is especially clean.

7) Integrality becomes a linear congruence

We need \(n=(At+B)/C\) to be an integer, so

$$At+B\equiv0\pmod C.$$

In a completely general affine-rational problem one would first set

$$g=\gcd(A,C),$$

check that \(g\mid B\), and reduce the congruence to

$$\frac{A}{g}t\equiv-\frac{B}{g}\pmod{\frac{C}{g}}.$$

The code keeps exactly this generic gcd-based path. But here \(g=1\), so there is always a unique residue class modulo \(C\):

$$t\equiv -B\,A^{-1}\pmod C.$$

Thus all valid \(t\) are of the form

$$t=t_0+kC,\qquad k\in\mathbb Z,$$

where \(t_0\) is the least nonnegative solution of the congruence.

8) The starting values themselves form an arithmetic progression

Substitute \(t=t_0+kC\) into \(n=(At+B)/C\):

$$n=\frac{At_0+B}{C}+kA=n_0+kA.$$

So the valid starting values are not scattered randomly; they form one arithmetic progression with step size \(A\).

This is the decisive optimization. Instead of checking many candidates, we compute one base solution \(n_0\) and jump directly by multiples of \(A\).

9) Choosing the smallest solution above the lower bound

Suppose the progression is

$$n=n_0+kA,\qquad k\ge0.$$

If \(n_0>L\), then the answer is simply \(n_0\). Otherwise we need the least integer \(k\) such that

$$n_0+kA>L.$$

This gives

$$k=\left\lfloor\frac{L-n_0}{A}\right\rfloor+1.$$

The code also makes one extra positivity adjustment on \(t\), because the least residue-class representative \(t_0\) can be \(0\). Replacing \(t\) by \(t+C\) increases \(n\) by \(A\), so this adjustment is perfectly consistent with the same arithmetic progression.

10) Worked example: prefix \(UD\)

Process the prefix backward.

First invert \(D\):

$$y\mapsto 3y.$$

Then invert \(U\):

$$n=\frac{3(3t)-2}{4}=\frac{9t-2}{4}.$$

Integrality requires

$$9t-2\equiv0\pmod4.$$

Since \(9\equiv1\pmod4\), this is

$$t\equiv2\pmod4.$$

The smallest positive choice is \(t=2\), giving

$$n=\frac{18-2}{4}=4.$$

Check the prefix forward:

$$4\xrightarrow{U}6\xrightarrow{D}2.$$

So \(4\) is indeed the smallest starting value whose trajectory begins with \(UD\).

11) Sample checkpoint from the source code

The program validates the sample sequence

$$\texttt{DdDddUUdDD}$$

with lower bound \(10^6\). The computed answer is

$$1004064.$$

Then the helper follows_prefix() runs the process forward and confirms that this value really starts with the required prefix. This is a strong end-to-end validation of the affine-congruence method.

How the Code Works

1) Parsing. The solver accepts --sequence=..., --lower-bound=..., and --skip-checkpoints.

2) Backward coefficient build. solve() scans the string from right to left and updates \((A,B,C)\) with the three formulas above.

3) Generic congruence solve. Even though this problem always has \(\gcd(A,C)=1\), the implementation still computes \(g=\gcd(A,C)\), reduces the congruence, and uses mod_inverse(). This makes the code robust and mathematically transparent.

4) Progression jump. Once it has one base solution, the code computes the least term above the lower bound without scanning any intermediate starts.

5) Integer safety. Intermediate affine coefficients are stored in __int128, because the prefix is long enough that ordinary 64-bit arithmetic would be risky during composition.

Complexity Analysis

If the prefix length is \(m\), building \((A,B,C)\) is \(O(m)\). Solving the modular inverse is \(O(\log C)\), and jumping to the first term above the lower bound is constant time. So the total runtime is linear in the prefix length, with \(O(1)\) memory.

Further Reading

  1. Problem page: https://projecteuler.net/problem=277
  2. Modular arithmetic and linear congruences: https://en.wikipedia.org/wiki/Modular_arithmetic
  3. Extended Euclidean algorithm: https://en.wikipedia.org/wiki/Extended_Euclidean_algorithm

Problemzusammenfassung

Eine modifizierte Collatz-Folge verwendet die drei Schrittarten \(D,U,d\), abhängig vom aktuellen Rest modulo \(3\). Für eine gegebene lange Schrittfolge und eine große Untergrenze \(L\) ist die kleinste Startzahl \(n>L\) gesucht, deren Bahn mit genau diesem Präfix beginnt. Was nach dem Präfix passiert, spielt keine Rolle.

Mathematischer Ansatz

Sei das vorgegebene Präfix \(s_1s_2\cdots s_m\) mit \(s_i\in\{D,U,d\}\).

1) Vorwärtsregeln und warum Vorwärtssuche aussichtslos ist

Die drei Regeln lauten:

$$D:\ x\equiv0\pmod3,\qquad x\mapsto \frac{x}{3},$$

$$U:\ x\equiv1\pmod3,\qquad x\mapsto \frac{4x+2}{3},$$

$$d:\ x\equiv2\pmod3,\qquad x\mapsto \frac{2x-1}{3}.$$

Da die Untergrenze im eigentlichen Problem bei etwa \(10^{15}\) liegt, wäre ein Test aufeinanderfolgender Startwerte praktisch unbrauchbar. Deshalb wird die Schrittfolge rückwärts analysiert.

2) Inversion eines einzelnen Schritts

Ist \(y\) der Wert nach einem Schritt, dann muss der vorherige Wert \(x\) erfüllen:

$$D^{-1}:\ x=3y,$$

$$U^{-1}:\ y=\frac{4x+2}{3}\Longrightarrow x=\frac{3y-2}{4},$$

$$d^{-1}:\ y=\frac{2x-1}{3}\Longrightarrow x=\frac{3y+1}{2}.$$

Jeder Rückwärtsschritt ist also eine affine rationale Abbildung.

3) Warum Ganzzahligkeit automatisch die richtige Restklasse erzwingt

Man könnte meinen, die Umkehrformeln garantieren nur Ganzzahligkeit, aber nicht die passende Modulo-\(3\)-Klasse. Tatsächlich genügt die Ganzzahligkeit:

Ist \(x=(3y-2)/4\in\mathbb Z\), dann ist \(4x+2\) durch \(3\) teilbar. Wegen \(4\equiv1\pmod3\) folgt

$$x+2\equiv0\pmod3\Longrightarrow x\equiv1\pmod3.$$

Ist \(x=(3y+1)/2\in\mathbb Z\), dann ist \(2x-1\) durch \(3\) teilbar. Da \(2\equiv-1\pmod3\), ergibt sich

$$-x-1\equiv0\pmod3\Longrightarrow x\equiv2\pmod3.$$

Somit landet ein gültiger Rückwärtsschritt automatisch in der korrekten Restklasse.

4) Die gesamte Rückwärtskomposition hat die Form \((At+B)/C\)

Sei \(t\) der Wert nach Ausführung des vollständigen Präfixes. Wenn man das Präfix von rechts nach links invertiert, erhält man den Startwert \(n\). Da jede Inversion affin-rational ist, hat die Gesamtformel die Gestalt

$$n=\frac{At+B}{C}.$$

Dies ist die zentrale Struktur: Alle gültigen Startwerte werden durch einen einzigen freien Parameter \(t\) beschrieben.

5) Die Koeffizienten-Updates im Detail

Sei die aktuelle Rückwärtsabbildung

$$x=\frac{At+B}{C}.$$

Für einen nachfolgenden Rückwärtsschritt \(D\) gilt

$$x\mapsto 3x=\frac{3At+3B}{C},$$

also

$$A\leftarrow3A,\qquad B\leftarrow3B,\qquad C\leftarrow C.$$

Für \(U\) gilt

$$x\mapsto \frac{3x-2}{4}=\frac{3(At+B)-2C}{4C},$$

also

$$A\leftarrow3A,\qquad B\leftarrow3B-2C,\qquad C\leftarrow4C.$$

Für \(d\) gilt

$$x\mapsto \frac{3x+1}{2}=\frac{3(At+B)+C}{2C},$$

also

$$A\leftarrow3A,\qquad B\leftarrow3B+C,\qquad C\leftarrow2C.$$

Gestartet wird mit der Identität \(n=t\), also

$$A=1,\qquad B=0,\qquad C=1,$$

und dann wird das Präfix rückwärts durchlaufen.

6) Geschlossene Form für \(A\) und \(C\)

Jeder Rückwärtsschritt multipliziert \(A\) mit \(3\). Deshalb gilt nach einem Präfix der Länge \(m\):

$$A=3^m.$$

Der Nenner \(C\) ändert sich nur bei \(U\) und \(d\): \(U\) multipliziert mit \(4=2^2\), \(d\) mit \(2\). Also

$$C=2^{\,2\#U+\#d}.$$

Insbesondere folgt

$$\gcd(A,C)=1.$$

7) Ganzzahligkeit wird zu einer linearen Kongruenz

Damit \(n=(At+B)/C\) ganzzahlig ist, muss gelten

$$At+B\equiv0\pmod C.$$

Im allgemeinen Fall setzt man

$$g=\gcd(A,C),$$

fordert \(g\mid B\) und reduziert auf

$$\frac{A}{g}t\equiv-\frac{B}{g}\pmod{\frac{C}{g}}.$$

Genau diesen allgemeineren Weg benutzt der Code. In unserem speziellen Problem ist jedoch stets \(g=1\), also existiert genau eine Restklasse modulo \(C\):

$$t\equiv -B\,A^{-1}\pmod C.$$

Alle Lösungen haben daher die Form

$$t=t_0+kC,\qquad k\in\mathbb Z,$$

wobei \(t_0\) die kleinste nichtnegative Lösung ist.

8) Auch die Startwerte bilden eine arithmetische Progression

Setzt man \(t=t_0+kC\) in \(n=(At+B)/C\) ein, so erhält man

$$n=\frac{At_0+B}{C}+kA=n_0+kA.$$

Die gültigen Startwerte selbst bilden also eine arithmetische Progression mit Schrittweite \(A\). Dadurch muss man nicht viele Kandidaten testen, sondern kann direkt zum ersten Term oberhalb der Untergrenze springen.

9) Auswahl der kleinsten Lösung oberhalb \(L\)

Ist

$$n=n_0+kA,\qquad k\ge0,$$

dann genügt bei \(n_0\le L\) die kleinste ganze Zahl

$$k=\left\lfloor\frac{L-n_0}{A}\right\rfloor+1.$$

Zusätzlich erzwingt der Code \(t>0\), weil der kleinste Kongruenzrepräsentant \(t_0\) auch \(0\) sein kann. Erhöht man \(t\) um \(C\), so wächst \(n\) genau um \(A\), also bleibt man auf derselben Progression.

10) Durchgerechnetes Beispiel: Präfix \(UD\)

Man invertiert zuerst \(D\):

$$y\mapsto 3y.$$

Danach invertiert man \(U\):

$$n=\frac{3(3t)-2}{4}=\frac{9t-2}{4}.$$

Ganzzahligkeit verlangt

$$9t-2\equiv0\pmod4.$$

Da \(9\equiv1\pmod4\), ist das äquivalent zu

$$t\equiv2\pmod4.$$

Mit \(t=2\) folgt

$$n=\frac{18-2}{4}=4.$$

Vorwärtskontrolle:

$$4\xrightarrow{U}6\xrightarrow{D}2.$$

Also ist \(4\) die kleinste Startzahl mit Präfix \(UD\).

11) Beispiel-Checkpoint aus dem Quellcode

Die Implementierung testet die Beispielsequenz

$$\texttt{DdDddUUdDD}$$

für die Untergrenze \(10^6\). Das Ergebnis ist

$$1004064.$$

Danach prüft follows_prefix() durch Vorwärtssimulation, dass diese Zahl das gewünschte Präfix wirklich erzeugt.

Wie der Code arbeitet

1) Einlesen. Unterstützt werden --sequence=..., --lower-bound=... und --skip-checkpoints.

2) Rückwärtsaufbau. solve() läuft die Zeichenkette von rechts nach links durch und aktualisiert \((A,B,C)\).

3) Allgemeine Kongruenzlösung. Obwohl hier immer \(\gcd(A,C)=1\) gilt, reduziert der Code das Problem zunächst über \(g=\gcd(A,C)\) und verwendet dann mod_inverse(). Das macht die Methode sauber und allgemein.

4) Direkter Sprung. Aus einem Basisterm \(n_0\) und der Schrittweite \(A\) wird sofort der erste zulässige Wert oberhalb der Schranke berechnet.

5) Zahlbereich. Für die Zwischenkoeffizienten benutzt die Lösung __int128, damit die lange Affinkomposition sicher ausgewertet wird.

Komplexitätsanalyse

Bei Präfixlänge \(m\) kostet der Aufbau von \((A,B,C)\) \(O(m)\). Das modulare Inverse benötigt \(O(\log C)\), der abschließende Sprung ist konstant. Insgesamt also lineare Laufzeit in der Präfixlänge und \(O(1)\) Speicher.

Weiterführende Hinweise

  1. Problem: https://projecteuler.net/problem=277
  2. Modulare Arithmetik und Kongruenzen: https://de.wikipedia.org/wiki/Kongruenz_(Zahlentheorie)
  3. Erweiterter euklidischer Algorithmus: https://de.wikipedia.org/wiki/Erweiterter_euklidischer_Algorithmus

Problem Özeti

Değiştirilmiş bir Collatz süreci, mevcut değerin \(3\) ile bölümünden kalanına göre \(D,U,d\) adımlarını uygular. Verilen uzun bir önek dizisi ve büyük bir alt sınır \(L\) için, yörüngesi tam bu önekle başlayan ve \(L\)’den büyük olan en küçük başlangıç değeri \(n\) istenir. Önekten sonra ne olduğu önemli değildir.

Matematiksel Yaklaşım

Ön ek \(s_1s_2\cdots s_m\) olsun; her \(s_i\in\{D,U,d\}\).

1) İleri kurallar ve neden kaba kuvvet olmaz

İleri süreç üç deterministic kuralla tanımlıdır:

$$D:\ x\equiv0\pmod3,\qquad x\mapsto \frac{x}{3},$$

$$U:\ x\equiv1\pmod3,\qquad x\mapsto \frac{4x+2}{3},$$

$$d:\ x\equiv2\pmod3,\qquad x\mapsto \frac{2x-1}{3}.$$

Asıl problemde alt sınır yaklaşık \(10^{15}\) olduğu için, ardışık başlangıç değerlerini ileri yönde denemek pratik değildir. Doğru yaklaşım, öneği tersten çözmektir.

2) Tek bir adımı tersine çevirmek

Bir adımdan sonraki değer \(y\) ise önceki değer \(x\) şu şekilde bulunur:

$$D^{-1}:\ x=3y,$$

$$U^{-1}:\ y=\frac{4x+2}{3}\Longrightarrow x=\frac{3y-2}{4},$$

$$d^{-1}:\ y=\frac{2x-1}{3}\Longrightarrow x=\frac{3y+1}{2}.$$

Dolayısıyla her ters adım afin-rasyonel bir dönüşümdür.

3) Neden ters formüllerde tamsayılık doğru mod \(3\) sınıfını otomatik verir?

İlk bakışta, ters formüller yalnızca “sonuç tamsayı olsun” şartını veriyor gibi görünür. Oysa bu yeterlidir:

\(x=(3y-2)/4\in\mathbb Z\) ise \(4x+2\) sayısı \(3\) ile bölünür. \(4\equiv1\pmod3\) olduğundan

$$x+2\equiv0\pmod3\Longrightarrow x\equiv1\pmod3.$$

Benzer biçimde \(x=(3y+1)/2\in\mathbb Z\) ise \(2x-1\) sayısı \(3\) ile bölünür. \(2\equiv-1\pmod3\) olduğu için

$$-x-1\equiv0\pmod3\Longrightarrow x\equiv2\pmod3.$$

Yani ters adım tamsayı üretirse, doğru harfin gerektirdiği mod sınıfına zaten düşer.

4) Tüm önek tek bir \((At+B)/C\) formuna iner

Öneğin tamamı uygulandıktan sonraki değere \(t\) diyelim. Öneği sağdan sola ters uygularsak başlangıç değeri \(n\)’i yeniden kurarız. Her ters adım afin-rasyonel olduğundan tüm bileşim şu biçimdedir:

$$n=\frac{At+B}{C}.$$

Bu, çözümün ana yapısıdır: geçerli bütün başlangıç değerleri tek bir serbest parametre \(t\) ile ifade edilir.

5) Kodun kullandığı katsayı güncellemeleri

Mevcut ters formül

$$x=\frac{At+B}{C}$$

olsun. Sıradaki ters adım \(D\) ise

$$x\mapsto 3x=\frac{3At+3B}{C},$$

dolayısıyla

$$A\leftarrow3A,\qquad B\leftarrow3B,\qquad C\leftarrow C.$$

Sıradaki ters adım \(U\) ise

$$x\mapsto \frac{3x-2}{4}=\frac{3(At+B)-2C}{4C},$$

yani

$$A\leftarrow3A,\qquad B\leftarrow3B-2C,\qquad C\leftarrow4C.$$

Sıradaki ters adım \(d\) ise

$$x\mapsto \frac{3x+1}{2}=\frac{3(At+B)+C}{2C},$$

dolayısıyla

$$A\leftarrow3A,\qquad B\leftarrow3B+C,\qquad C\leftarrow2C.$$

Başlangıçta özdeş dönüşüm alınır:

$$A=1,\qquad B=0,\qquad C=1,$$

ve dizi sağdan sola taranır.

6) \(A\) ve \(C\) için kapalı biçim

Her ters adım \(A\)’yı \(3\) ile çarptığı için önek uzunluğu \(m\) ise

$$A=3^m.$$

Payda \(C\) yalnızca \(U\) ve \(d\) adımlarından etkilenir: \(U\) için \(\times4=2^2\), \(d\) için \(\times2\). Dolayısıyla

$$C=2^{\,2\#U+\#d}.$$

Böylece hemen

$$\gcd(A,C)=1$$

elde edilir.

7) Tamsayılık tek bir lineer kongruansa dönüşür

\(n=(At+B)/C\) tamsayı olmalıdır; bu da

$$At+B\equiv0\pmod C$$

şartıdır. Tam genel durumda önce

$$g=\gcd(A,C)$$

yazılır, \(g\mid B\) kontrol edilir ve denklem

$$\frac{A}{g}t\equiv-\frac{B}{g}\pmod{\frac{C}{g}}$$

şeklinde sadeleştirilir. Kod da bu genel yolu izler. Fakat bu problemde her zaman \(g=1\) olduğundan doğrudan

$$t\equiv -B\,A^{-1}\pmod C$$

olur. Yani tüm çözümler

$$t=t_0+kC,\qquad k\in\mathbb Z$$

şeklindedir.

8) Başlangıç değerlerinin kendisi de aritmetik dizidir

\(t=t_0+kC\) ifadesini geri koyarsak

$$n=\frac{At_0+B}{C}+kA=n_0+kA$$

çıkar. Yani geçerli başlangıç değerleri tek bir aritmetik dizi oluşturur; adım farkı \(A\)’dır. Çözümün hız kazanmasının nedeni tam olarak budur.

9) Alt sınırın üstündeki en küçük çözümü seçmek

Geçerli başlangıçlar

$$n=n_0+kA,\qquad k\ge0$$

ise ve \(n_0\le L\) ise, \(n_0+kA>L\) eşitsizliğini sağlayan en küçük \(k\)

$$k=\left\lfloor\frac{L-n_0}{A}\right\rfloor+1$$

olur. Kod ayrıca \(t>0\) koşulunu da garanti eder; çünkü en küçük kongruans temsilcisi \(t_0\) bazen \(0\) olabilir. \(t\)’ye \(C\) eklemek \(n\)’e tam olarak \(A\) eklediği için aynı aritmetik dizi üzerinde kalırız.

10) Çalışan örnek: \(UD\) öneği

Öneği tersten işle:

Önce \(D\) terslenir:

$$y\mapsto 3y.$$

Sonra \(U\) terslenir:

$$n=\frac{3(3t)-2}{4}=\frac{9t-2}{4}.$$

Tamsayılık için

$$9t-2\equiv0\pmod4$$

gerekir. \(9\equiv1\pmod4\) olduğundan

$$t\equiv2\pmod4$$

bulunur. En küçük pozitif çözüm \(t=2\)’dir; o hâlde

$$n=\frac{18-2}{4}=4.$$

İleri kontrol:

$$4\xrightarrow{U}6\xrightarrow{D}2.$$

Demek ki \(4\), yörüngesi \(UD\) ile başlayan en küçük başlangıç değeridir.

11) Kaynak koddaki örnek checkpoint

Program şu örnek diziyi doğrular:

$$\texttt{DdDddUUdDD}$$

ve alt sınır \(10^6\) için

$$1004064$$

sonucunu bulur. Ardından follows_prefix() fonksiyonu bu sayının gerçekten istenen önekle başladığını ileri yönde kontrol eder.

Kodun Çalışma Mantığı

1) Girdi işleme. --sequence=..., --lower-bound=... ve --skip-checkpoints seçenekleri desteklenir.

2) Ters katsayı inşası. solve() diziyi sağdan sola tarar ve \((A,B,C)\) katsayılarını günceller.

3) Genel kongruans çözümü. Bu problemde \(\gcd(A,C)=1\) olsa da kod yine de genel gcd azaltmasını ve mod_inverse() çağrısını kullanır. Bu hem daha genel hem de matematiksel olarak daha şeffaftır.

4) Doğrudan sıçrama. İlk baz çözüm bulunduğunda, alt sınırı geçen ilk terim doğrudan hesaplanır; aradaki hiçbir aday denenmez.

5) Sayısal güvenlik. Uzun önek yüzünden ara katsayılar büyüyebildiği için çözüm, bileşim boyunca __int128 kullanır.

Karmaşıklık Analizi

Önek uzunluğu \(m\) ise \((A,B,C)\) inşası \(O(m)\) sürer. Modüler ters alma \(O(\log C)\), son sıçrama ise sabit zamandır. Toplam çalışma süresi önek uzunluğunda doğrusaldır ve bellek kullanımı \(O(1)\)’dir.

İleri Okuma

  1. Problem metni: https://projecteuler.net/problem=277
  2. Modüler aritmetik ve kongruanslar: https://tr.wikipedia.org/wiki/Modüler_aritmetik
  3. Genişletilmiş Öklid algoritması: https://tr.wikipedia.org/wiki/Genişletilmiş_Öklid_algoritması

Resumen del Problema

Una variante de la sucesión de Collatz usa tres tipos de paso \(D,U,d\), elegidos según el residuo módulo \(3\). Dada una cadena larga de pasos y una cota inferior grande \(L\), queremos el menor valor inicial \(n>L\) cuya trayectoria empieza exactamente con ese prefijo. Lo que ocurra después no importa.

Enfoque Matemático

Sea el prefijo \(s_1s_2\cdots s_m\), con \(s_i\in\{D,U,d\}\).

1) Reglas hacia delante y por qué no sirve el brute force

Las reglas son

$$D:\ x\equiv0\pmod3,\qquad x\mapsto \frac{x}{3},$$

$$U:\ x\equiv1\pmod3,\qquad x\mapsto \frac{4x+2}{3},$$

$$d:\ x\equiv2\pmod3,\qquad x\mapsto \frac{2x-1}{3}.$$

Como la cota inferior real ronda \(10^{15}\), probar valores iniciales consecutivos es inviable. La idea correcta es invertir el prefijo.

2) Invertir un paso

Si \(y\) es el valor después de un paso, el valor previo \(x\) debe satisfacer

$$D^{-1}:\ x=3y,$$

$$U^{-1}:\ y=\frac{4x+2}{3}\Longrightarrow x=\frac{3y-2}{4},$$

$$d^{-1}:\ y=\frac{2x-1}{3}\Longrightarrow x=\frac{3y+1}{2}.$$

3) La integridad ya fuerza la clase módulo \(3\)

Si \(x=(3y-2)/4\) es entero, entonces \(4x+2\) es múltiplo de \(3\). Como \(4\equiv1\pmod3\), obtenemos

$$x+2\equiv0\pmod3\Longrightarrow x\equiv1\pmod3.$$

Si \(x=(3y+1)/2\) es entero, entonces \(2x-1\) es múltiplo de \(3\). Dado que \(2\equiv-1\pmod3\),

$$-x-1\equiv0\pmod3\Longrightarrow x\equiv2\pmod3.$$

Por tanto, un paso inverso entero ya es automáticamente válido para la letra correspondiente.

4) Todo el prefijo invertido tiene forma \((At+B)/C\)

Sea \(t\) el valor tras ejecutar todo el prefijo. Al invertirlo de derecha a izquierda, reconstruimos el valor inicial \(n\). Como cada inversión es afín-racional, la composición total es

$$n=\frac{At+B}{C}.$$

5) Actualizaciones de coeficientes

Si la fórmula actual es

$$x=\frac{At+B}{C},$$

entonces para \(D\):

$$A\leftarrow3A,\qquad B\leftarrow3B,\qquad C\leftarrow C.$$

Para \(U\):

$$A\leftarrow3A,\qquad B\leftarrow3B-2C,\qquad C\leftarrow4C.$$

Para \(d\):

$$A\leftarrow3A,\qquad B\leftarrow3B+C,\qquad C\leftarrow2C.$$

Se empieza con la identidad \(n=t\):

$$A=1,\qquad B=0,\qquad C=1.$$

6) Forma cerrada de \(A\) y \(C\)

Cada paso multiplica \(A\) por \(3\), así que

$$A=3^m.$$

Solo \(U\) y \(d\) afectan al denominador, por lo que

$$C=2^{\,2\#U+\#d}.$$

En particular,

$$\gcd(A,C)=1.$$

7) La condición de integridad se reduce a una congruencia lineal

Necesitamos

$$At+B\equiv0\pmod C.$$

En el caso general se toma \(g=\gcd(A,C)\), se reduce la congruencia y se trabaja módulo \(C/g\). El código conserva exactamente esa versión general. Pero aquí \(g=1\), así que existe una única clase residual:

$$t\equiv -B\,A^{-1}\pmod C.$$

Por tanto

$$t=t_0+kC,\qquad k\in\mathbb Z.$$

8) Los valores iniciales forman una progresión aritmética

Sustituyendo \(t=t_0+kC\),

$$n=\frac{At_0+B}{C}+kA=n_0+kA.$$

Así, todos los inicios válidos forman una sola progresión aritmética de diferencia \(A\).

9) Cómo elegir el menor inicio por encima de \(L\)

Si

$$n=n_0+kA,\qquad k\ge0,$$

entonces para \(n_0\le L\) el menor \(k\) válido es

$$k=\left\lfloor\frac{L-n_0}{A}\right\rfloor+1.$$

El código también fuerza \(t>0\), porque el representante mínimo \(t_0\) puede ser \(0\). Añadir \(C\) a \(t\) aumenta \(n\) exactamente en \(A\).

10) Ejemplo trabajado: prefijo \(UD\)

Invertimos primero \(D\):

$$y\mapsto 3y.$$

Luego invertimos \(U\):

$$n=\frac{3(3t)-2}{4}=\frac{9t-2}{4}.$$

La integridad exige

$$9t-2\equiv0\pmod4.$$

Como \(9\equiv1\pmod4\), queda

$$t\equiv2\pmod4.$$

Con \(t=2\) resulta

$$n=\frac{18-2}{4}=4.$$

Verificación hacia delante:

$$4\xrightarrow{U}6\xrightarrow{D}2.$$

11) Checkpoint del código

La implementación comprueba la secuencia

$$\texttt{DdDddUUdDD}$$

con cota inferior \(10^6\), obteniendo

$$1004064.$$

Después follows_prefix() confirma por simulación directa que el prefijo es correcto.

Cómo Funciona el Código

1) Construcción hacia atrás. solve() recorre la cadena de derecha a izquierda y actualiza \((A,B,C)\).

2) Congruencia general. Aunque aquí \(\gcd(A,C)=1\), el programa conserva la reducción por gcd y el uso de mod_inverse().

3) Salto directo. Una vez hallada la progresión \(n_0+kA\), el algoritmo salta directamente al primer término por encima de la cota.

4) Seguridad numérica. Se usan enteros de 128 bits para las cantidades intermedias.

Complejidad

Si el prefijo tiene longitud \(m\), construir \((A,B,C)\) cuesta \(O(m)\). El inverso modular cuesta \(O(\log C)\) y el salto final es \(O(1)\). El espacio es constante.

Lecturas

  1. Problema: https://projecteuler.net/problem=277
  2. Aritmética modular: https://es.wikipedia.org/wiki/Aritmética_modular
  3. Algoritmo extendido de Euclides: https://es.wikipedia.org/wiki/Algoritmo_de_Euclides

问题概述

这个修改版 Collatz 过程按照当前值模 \(3\) 的余数选择三种步骤 \(D,U,d\)。给定一个很长的步骤前缀和一个很大的下界 \(L\),要求找出最小的 \(n>L\),使得从 \(n\) 开始的轨道 恰好以该前缀开头。前缀之后的后续行为不重要。

数学方法

设给定前缀为 \(s_1s_2\cdots s_m\),其中 \(s_i\in\{D,U,d\}\)。

1) 正向规则与为何不能暴力搜索

三条规则是

$$D:\ x\equiv0\pmod3,\qquad x\mapsto \frac{x}{3},$$

$$U:\ x\equiv1\pmod3,\qquad x\mapsto \frac{4x+2}{3},$$

$$d:\ x\equiv2\pmod3,\qquad x\mapsto \frac{2x-1}{3}.$$

由于题目下界约为 \(10^{15}\),逐个起点向前试几乎不可能。核心思路是把整个前缀反过来处理。

2) 单步逆变换

若一步之后的值为 \(y\),则前一步的值 \(x\) 必须满足

$$D^{-1}:\ x=3y,$$

$$U^{-1}:\ y=\frac{4x+2}{3}\Longrightarrow x=\frac{3y-2}{4},$$

$$d^{-1}:\ y=\frac{2x-1}{3}\Longrightarrow x=\frac{3y+1}{2}.$$

3) 为什么“逆变换得到整数”就自动落在正确余数类

如果 \(x=(3y-2)/4\) 是整数,则 \(4x+2\) 可被 \(3\) 整除。因为 \(4\equiv1\pmod3\),可得

$$x+2\equiv0\pmod3\Longrightarrow x\equiv1\pmod3.$$

如果 \(x=(3y+1)/2\) 是整数,则 \(2x-1\) 可被 \(3\) 整除。由于 \(2\equiv-1\pmod3\),可得

$$-x-1\equiv0\pmod3\Longrightarrow x\equiv2\pmod3.$$

所以逆向公式只要产出整数,就已经自动满足该字母所需的模 \(3\) 条件。

4) 整个前缀逆合成后一定是 \((At+B)/C\)

设执行完整个前缀后的值为 \(t\)。把前缀从右向左逆过来,就能重建初值 \(n\)。由于每个逆步骤都是仿射有理变换,整体一定可以写成

$$n=\frac{At+B}{C}.$$

5) 代码里的系数更新

若当前逆向公式为

$$x=\frac{At+B}{C},$$

则遇到 \(D\) 时

$$A\leftarrow3A,\qquad B\leftarrow3B,\qquad C\leftarrow C.$$

遇到 \(U\) 时

$$A\leftarrow3A,\qquad B\leftarrow3B-2C,\qquad C\leftarrow4C.$$

遇到 \(d\) 时

$$A\leftarrow3A,\qquad B\leftarrow3B+C,\qquad C\leftarrow2C.$$

初始条件是恒等映射 \(n=t\):

$$A=1,\qquad B=0,\qquad C=1.$$

6) \(A\) 和 \(C\) 的闭式结构

每一步都把 \(A\) 乘以 \(3\),所以

$$A=3^m.$$

只有 \(U\) 和 \(d\) 改变分母,其中 \(U\) 乘 \(4\),\(d\) 乘 \(2\),因此

$$C=2^{\,2\#U+\#d}.$$

于是立刻得到

$$\gcd(A,C)=1.$$

7) 整数条件化为线性同余

要使 \(n=(At+B)/C\) 为整数,必须有

$$At+B\equiv0\pmod C.$$

一般情形下先设

$$g=\gcd(A,C),$$

然后把同余约化到模 \(C/g\)。代码保留了这一通用流程。但在本题里 \(g=1\),所以只有一个模 \(C\) 的剩余类:

$$t\equiv -B\,A^{-1}\pmod C.$$

于是所有解都是

$$t=t_0+kC,\qquad k\in\mathbb Z.$$

8) 初始值本身也形成等差数列

代回去有

$$n=\frac{At_0+B}{C}+kA=n_0+kA.$$

也就是说,所有合法起点构成一个公差为 \(A\) 的等差数列。

9) 如何选出大于下界 \(L\) 的最小解

$$n=n_0+kA,\qquad k\ge0,$$

则在 \(n_0\le L\) 时,最小可行 \(k\) 为

$$k=\left\lfloor\frac{L-n_0}{A}\right\rfloor+1.$$

代码还会额外保证 \(t>0\),因为最小同余代表 \(t_0\) 有可能是 \(0\)。把 \(t\) 增加一个 \(C\) 会让 \(n\) 恰好增加一个 \(A\),因此仍在同一条等差数列上。

10) 示例:前缀 \(UD\)

先逆 \(D\):

$$y\mapsto 3y.$$

再逆 \(U\):

$$n=\frac{3(3t)-2}{4}=\frac{9t-2}{4}.$$

整数条件是

$$9t-2\equiv0\pmod4.$$

因为 \(9\equiv1\pmod4\),所以

$$t\equiv2\pmod4.$$

最小正解 \(t=2\),因此

$$n=\frac{18-2}{4}=4.$$

正向验证:

$$4\xrightarrow{U}6\xrightarrow{D}2.$$

11) 源码中的示例校验

程序会验证样例序列

$$\texttt{DdDddUUdDD}$$

在下界 \(10^6\) 时得到答案

$$1004064,$$

随后用 follows_prefix() 再正向检查这个结果确实拥有该前缀。

代码逻辑

1) 逆向构造。 solve() 从右到左扫描字符串并更新 \((A,B,C)\)。

2) 通用同余求解。 虽然本题总有 \(\gcd(A,C)=1\),但代码仍先走 gcd 约化,再调用 mod_inverse()

3) 直接跳跃。 一旦得到等差数列 \(n_0+kA\),就直接算出第一个超过下界的项。

4) 数值安全。 中间系数使用 128 位整数存储。

复杂度分析

若前缀长度为 \(m\),则构造 \((A,B,C)\) 的代价是 \(O(m)\),模逆代价是 \(O(\log C)\),最终跳跃是 \(O(1)\)。空间复杂度为常数。

延伸阅读

  1. 题目页面: https://projecteuler.net/problem=277
  2. 模运算与同余: https://zh.wikipedia.org/wiki/模算术
  3. 扩展欧几里得算法: https://zh.wikipedia.org/wiki/扩展欧几里得算法

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

В модифицированной Collatz-процедуре шаги \(D,U,d\) выбираются по остатку текущего числа по модулю \(3\). Для заданного длинного префикса шагов и большой нижней границы \(L\) нужно найти наименьшее стартовое число \(n>L\), чья траектория начинается ровно с этого префикса. Всё, что происходит после префикса, уже не важно.

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

Пусть префикс равен \(s_1s_2\cdots s_m\), где \(s_i\in\{D,U,d\}\).

1) Прямые правила и почему прямой перебор не годится

Правила таковы:

$$D:\ x\equiv0\pmod3,\qquad x\mapsto \frac{x}{3},$$

$$U:\ x\equiv1\pmod3,\qquad x\mapsto \frac{4x+2}{3},$$

$$d:\ x\equiv2\pmod3,\qquad x\mapsto \frac{2x-1}{3}.$$

Так как нижняя граница в задаче порядка \(10^{15}\), поочерёдно проверять стартовые значения бессмысленно. Нужно развернуть префикс назад.

2) Обратные преобразования одного шага

Если после шага получилось значение \(y\), то предыдущее \(x\) должно удовлетворять

$$D^{-1}:\ x=3y,$$

$$U^{-1}:\ y=\frac{4x+2}{3}\Longrightarrow x=\frac{3y-2}{4},$$

$$d^{-1}:\ y=\frac{2x-1}{3}\Longrightarrow x=\frac{3y+1}{2}.$$

3) Почему целочисленность уже гарантирует правильный остаток

Если \(x=(3y-2)/4\) — целое число, то \(4x+2\) делится на \(3\). Поскольку \(4\equiv1\pmod3\), имеем

$$x+2\equiv0\pmod3\Longrightarrow x\equiv1\pmod3.$$

Если \(x=(3y+1)/2\) — целое, то \(2x-1\) делится на \(3\). Так как \(2\equiv-1\pmod3\), получаем

$$-x-1\equiv0\pmod3\Longrightarrow x\equiv2\pmod3.$$

Значит, обратная формула, дающая целое число, автоматически попадает в нужный класс по модулю \(3\).

4) Полная обратная композиция имеет вид \((At+B)/C\)

Пусть \(t\) — значение после выполнения всего заданного префикса. Если применять обратные шаги справа налево, можно восстановить стартовое число \(n\). Поскольку каждый шаг аффинно-рационален, вся композиция имеет вид

$$n=\frac{At+B}{C}.$$

5) Обновление коэффициентов

Если текущая формула имеет вид

$$x=\frac{At+B}{C},$$

то для \(D\):

$$A\leftarrow3A,\qquad B\leftarrow3B,\qquad C\leftarrow C.$$

Для \(U\):

$$A\leftarrow3A,\qquad B\leftarrow3B-2C,\qquad C\leftarrow4C.$$

Для \(d\):

$$A\leftarrow3A,\qquad B\leftarrow3B+C,\qquad C\leftarrow2C.$$

Стартуем с тождества \(n=t\), то есть

$$A=1,\qquad B=0,\qquad C=1.$$

6) Закрытая форма для \(A\) и \(C\)

Каждый обратный шаг умножает \(A\) на \(3\), поэтому

$$A=3^m.$$

Знаменатель меняют только \(U\) и \(d\), так что

$$C=2^{\,2\#U+\#d}.$$

Следовательно,

$$\gcd(A,C)=1.$$

7) Целочисленность превращается в линейную конгруэнцию

Нужно, чтобы

$$At+B\equiv0\pmod C.$$

В общем случае код сначала вычисляет \(g=\gcd(A,C)\), сокращает сравнение по модулю \(C/g\), а затем ищет обратный элемент. Но в данной задаче всегда \(g=1\), поэтому остаётся единственный класс:

$$t\equiv -B\,A^{-1}\pmod C.$$

То есть все решения задаются как

$$t=t_0+kC,\qquad k\in\mathbb Z.$$

8) Стартовые значения тоже образуют арифметическую прогрессию

Подставляя \(t=t_0+kC\), получаем

$$n=\frac{At_0+B}{C}+kA=n_0+kA.$$

Значит, все допустимые старты лежат в одной арифметической прогрессии с шагом \(A\).

9) Как выбрать минимальное решение выше \(L\)

Если

$$n=n_0+kA,\qquad k\ge0,$$

то при \(n_0\le L\) минимальный подходящий индекс равен

$$k=\left\lfloor\frac{L-n_0}{A}\right\rfloor+1.$$

Код дополнительно следит, чтобы \(t>0\), поскольку наименьший представитель класса \(t_0\) может оказаться равным нулю. Увеличение \(t\) на \(C\) увеличивает \(n\) ровно на \(A\).

10) Пример: префикс \(UD\)

Сначала обращаем \(D\):

$$y\mapsto 3y.$$

Затем обращаем \(U\):

$$n=\frac{3(3t)-2}{4}=\frac{9t-2}{4}.$$

Требование целочисленности:

$$9t-2\equiv0\pmod4.$$

Так как \(9\equiv1\pmod4\), имеем

$$t\equiv2\pmod4.$$

Минимальный положительный \(t=2\), откуда

$$n=\frac{18-2}{4}=4.$$

Проверка вперёд:

$$4\xrightarrow{U}6\xrightarrow{D}2.$$

11) Проверка из исходного кода

В программе проверяется последовательность

$$\texttt{DdDddUUdDD}$$

при нижней границе \(10^6\). Ответ равен

$$1004064,$$

после чего функция follows_prefix() подтверждает прямой симуляцией, что префикс действительно совпадает.

Логика кода

1) Обратная сборка. solve() проходит строку справа налево и обновляет \((A,B,C)\).

2) Общая конгруэнция. Хотя здесь всегда \(\gcd(A,C)=1\), код всё равно использует общий путь через gcd и mod_inverse().

3) Прыжок по прогрессии. Получив \(n_0+kA\), программа сразу вычисляет первый член выше нижней границы.

4) Безопасность типов. Для промежуточных коэффициентов применяется __int128.

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

Если длина префикса равна \(m\), построение \((A,B,C)\) занимает \(O(m)\), вычисление обратного элемента — \(O(\log C)\), а финальный прыжок — \(O(1)\). Память постоянна.

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

  1. Условие: https://projecteuler.net/problem=277
  2. Модульная арифметика: https://ru.wikipedia.org/wiki/Сравнение_по_модулю
  3. Расширенный алгоритм Евклида: https://ru.wikipedia.org/wiki/Расширенный_алгоритм_Евклида

ملخص المسألة

في هذه النسخة المعدلة من متتالية Collatz توجد ثلاث حركات \(D,U,d\)، ويُختار نوع الحركة بحسب باقي القسمة على \(3\). لدينا بادئة طويلة معطاة وحدّ سفلي كبير \(L\)، ونريد أصغر قيمة ابتدائية \(n>L\) بحيث يبدأ المسار بالضبط بهذه البادئة. ما يحدث بعد انتهاء البادئة لا يهم.

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

لنكتب البادئة على الصورة \(s_1s_2\cdots s_m\) حيث \(s_i\in\{D,U,d\}\).

1) القواعد الأمامية ولماذا لا يصلح البحث المباشر

القواعد هي:

$$D:\ x\equiv0\pmod3,\qquad x\mapsto \frac{x}{3},$$

$$U:\ x\equiv1\pmod3,\qquad x\mapsto \frac{4x+2}{3},$$

$$d:\ x\equiv2\pmod3,\qquad x\mapsto \frac{2x-1}{3}.$$

وبما أن الحد السفلي في المسألة الحقيقية يقارب \(10^{15}\)، فإن تجربة القيم الابتدائية واحدةً بعد أخرى أمر غير عملي. لذلك يجب عكس البادئة.

2) عكس خطوة واحدة

إذا كان \(y\) هو القيمة بعد خطوة واحدة، فإن القيمة السابقة \(x\) يجب أن تحقق

$$D^{-1}:\ x=3y,$$

$$U^{-1}:\ y=\frac{4x+2}{3}\Longrightarrow x=\frac{3y-2}{4},$$

$$d^{-1}:\ y=\frac{2x-1}{3}\Longrightarrow x=\frac{3y+1}{2}.$$

3) لماذا تكفي صحة العدد الصحيح لضمان فئة الباقي الصحيحة

إذا كان \(x=(3y-2)/4\) عددًا صحيحًا، فإن \(4x+2\) يقبل القسمة على \(3\). ولأن \(4\equiv1\pmod3\)، فهذا يعني

$$x+2\equiv0\pmod3\Longrightarrow x\equiv1\pmod3.$$

وبالمثل، إذا كان \(x=(3y+1)/2\) صحيحًا، فإن \(2x-1\) يقبل القسمة على \(3\). وبما أن \(2\equiv-1\pmod3\)، نحصل على

$$-x-1\equiv0\pmod3\Longrightarrow x\equiv2\pmod3.$$

إذن متى أعطت الصيغة العكسية عددًا صحيحًا، فهي تضعنا تلقائيًا في فئة الباقي المناسبة.

4) عكس البادئة كلها يعطي صيغة واحدة من الشكل \((At+B)/C\)

لتكن \(t\) هي القيمة بعد تنفيذ البادئة كلها. إذا طبقنا الخطوات العكسية من اليمين إلى اليسار، أمكننا استرجاع القيمة الابتدائية \(n\). ولأن كل خطوة عكسية هي تحويل خطي كسري، فالصيغة النهائية تكون

$$n=\frac{At+B}{C}.$$

5) تحديث المعاملات كما في الكود

إذا كانت الصيغة الحالية هي

$$x=\frac{At+B}{C},$$

فعند عكس \(D\) نحصل على

$$A\leftarrow3A,\qquad B\leftarrow3B,\qquad C\leftarrow C.$$

وعند عكس \(U\):

$$A\leftarrow3A,\qquad B\leftarrow3B-2C,\qquad C\leftarrow4C.$$

وعند عكس \(d\):

$$A\leftarrow3A,\qquad B\leftarrow3B+C,\qquad C\leftarrow2C.$$

وتبدأ العملية من التحويل المطابق \(n=t\)، أي

$$A=1,\qquad B=0,\qquad C=1.$$

6) الشكل المغلق لـ \(A\) و\(C\)

كل خطوة عكسية تضرب \(A\) في \(3\)، ولذلك

$$A=3^m.$$

أما \(C\) فلا يتغير إلا عند \(U\) و\(d\)، حيث تضرب \(U\) في \(4\) وتضرب \(d\) في \(2\). ومن ثم

$$C=2^{\,2\#U+\#d}.$$

وعليه

$$\gcd(A,C)=1.$$

7) شرط الصحة يتحول إلى توافق خطي

لكي يكون \(n=(At+B)/C\) عددًا صحيحًا، يجب أن يكون

$$At+B\equiv0\pmod C.$$

في الحالة العامة يعرّف الكود

$$g=\gcd(A,C),$$

ثم يختزل المقارنة modulo \(C/g\). هذا هو المسار العام الذي يحتفظ به الكود. لكن في هذه المسألة دائمًا \(g=1\)، ولذلك توجد فئة باقٍ وحيدة:

$$t\equiv -B\,A^{-1}\pmod C.$$

أي أن جميع الحلول تكتب بالشكل

$$t=t_0+kC,\qquad k\in\mathbb Z.$$

8) القيم الابتدائية نفسها تشكل متتالية حسابية

بالتعويض عن \(t=t_0+kC\) نحصل على

$$n=\frac{At_0+B}{C}+kA=n_0+kA.$$

إذن جميع البدايات الصحيحة تقع في متتالية حسابية واحدة فرقها \(A\).

9) اختيار أصغر حل فوق الحد السفلي

إذا كانت البدايات المسموح بها هي

$$n=n_0+kA,\qquad k\ge0,$$

فإن أصغر \(k\) يحقق \(n_0+kA>L\) عند \(n_0\le L\) هو

$$k=\left\lfloor\frac{L-n_0}{A}\right\rfloor+1.$$

كما يضمن الكود أيضًا أن \(t>0\)، لأن أصغر ممثل للفئة التوافقية \(t_0\) قد يكون صفرًا. وزيادة \(t\) بمقدار \(C\) تزيد \(n\) بمقدار \(A\)، أي نبقى على المتتالية نفسها.

10) مثال محلول: البادئة \(UD\)

نعكس أولًا \(D\):

$$y\mapsto 3y.$$

ثم نعكس \(U\):

$$n=\frac{3(3t)-2}{4}=\frac{9t-2}{4}.$$

حتى يكون \(n\) صحيحًا لا بد من

$$9t-2\equiv0\pmod4.$$

ولأن \(9\equiv1\pmod4\)، فهذا يكافئ

$$t\equiv2\pmod4.$$

أصغر حل موجب هو \(t=2\)، ومنه

$$n=\frac{18-2}{4}=4.$$

والتحقق الأمامي يعطي

$$4\xrightarrow{U}6\xrightarrow{D}2.$$

11) نقطة التحقق الموجودة في المصدر

يفحص البرنامج السلسلة

$$\texttt{DdDddUUdDD}$$

مع الحد \(10^6\)، ويجد القيمة

$$1004064.$$

ثم تؤكد الدالة follows_prefix() بالمسار الأمامي أن هذه القيمة تبدأ بالفعل بالبادئة المطلوبة.

كيف يعمل الكود

1) البناء العكسي. تمر الدالة solve() على السلسلة من اليمين إلى اليسار وتحدّث \((A,B,C)\).

2) حل التوافق العام. رغم أن \(\gcd(A,C)=1\) دائمًا هنا، فإن الكود يحتفظ بالصياغة العامة عبر gcd ثم يستخدم mod_inverse().

3) القفز المباشر. بعد معرفة المتتالية \(n_0+kA\)، يُحسب أول حد فوق \(L\) مباشرة من دون تجربة القيم الوسيطة.

4) الأمان العددي. تُستخدم أعداد 128-بت للمعاملات الوسيطة أثناء التركيب.

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

إذا كان طول البادئة \(m\)، فإن بناء \((A,B,C)\) يكلف \(O(m)\)، وحساب المعكوس المعياري يكلف \(O(\log C)\)، أما اختيار أول حد فوق \(L\) فزمنه ثابت. استهلاك الذاكرة \(O(1)\).

مراجع إضافية

  1. صفحة المسألة: https://projecteuler.net/problem=277
  2. الحساب المعياري: https://ar.wikipedia.org/wiki/حساب_معياري
  3. خوارزمية إقليدس الموسعة: https://ar.wikipedia.org/wiki/خوارزمية_إقليدس