The title refers to a three-heap Nim position with heap sizes
$$n,\qquad 2n,\qquad 3n.$$
In Nim, a position is losing for the next player exactly when the xor of the heap sizes is zero. So we must count the integers \(n\) with
$$1\le n\le 2^k,\qquad n\oplus 2n\oplus 3n=0.$$
Since
$$3n=n+2n,$$
the xor condition becomes
$$n\oplus 2n\oplus (n+2n)=0.$$
Now recall the binary identity
$$a\oplus b=a+b \iff a\land b=0,$$
which says that xor equals ordinary addition exactly when no carry occurs. Therefore
$$n\oplus 2n\oplus 3n=0 \iff n\oplus 2n = n+2n \iff n\land 2n = 0.$$
So the whole problem is reduced to asking when the binary expansions of \(n\) and \(2n\) overlap.
Multiplying by \(2\) is just a left shift:
$$2n = n \ll 1.$$
Thus the bitwise condition
$$n\land 2n = 0$$
means that no 1-bit of \(n\) may sit immediately next to another 1-bit, because a bit at position \(i\) in \(n\) overlaps with a bit at position \(i+1\) after shifting. Hence
$$n\oplus 2n\oplus 3n=0$$
if and only if the binary representation of \(n\) contains no substring \(11\).
Take \(n=5\). In binary,
$$5=101_2,\qquad 10=1010_2,\qquad 15=1111_2.$$
Because \(101\) has no adjacent 1s, the carry-free condition holds, and indeed
$$5\oplus 10\oplus 15=0.$$
Now take \(n=6\):
$$6=110_2.$$
This contains adjacent 1s, so \(6+12\) has a carry, and correspondingly
$$6\oplus 12\oplus 18\ne 0.$$
Let \(A_t\) be the number of binary strings of length \(t\) with no adjacent 1s. There are two cases:
Ending in 0. Then the first \(t-1\) bits form any valid length-\((t-1)\) string.
Ending in 1. Then the previous bit must be 0, and the first \(t-2\) bits form any valid length-\((t-2)\) string.
Therefore
$$A_t=A_{t-1}+A_{t-2},$$
with initial values
$$A_0=1,\qquad A_1=2.$$
So \(A_t\) is a Fibonacci count. If we use the convention
$$F_1=1,\qquad F_2=1,\qquad F_{m}=F_{m-1}+F_{m-2},$$
then
$$A_t=F_{t+2}.$$
The count \(A_k\) describes valid \(k\)-bit strings, which is the same as valid integers in the half-open range
$$0\le n<2^k.$$
But the problem asks for
$$1\le n\le 2^k.$$
This changes the set in a very simple way: we remove \(0\), but we add \(2^k\), whose binary form is
$$1000\cdots 0,$$
and that number is also valid because it clearly has no adjacent 1s. So the count does not change at all. Hence the final answer is
$$A_k=F_{k+2}.$$
The implementation sets bits = exponent + 1 and returns the corresponding Fibonacci entry, which is exactly this value.
For \(k=3\), the valid values are
$$1,2,4,5,8,$$
so the count is
$$5=F_5.$$
For the C++ checkpoint,
$$k=10 \Rightarrow F_{12}=144.$$
For the actual Project Euler target,
$$k=30 \Rightarrow F_{32}=2178309.$$
The solver does not test any \(n\) individually. It simply builds Fibonacci numbers up to index \(k+2\) and returns that value. The brute-force checks in the C++ version for small exponents confirm that this combinatorial count exactly matches the xor definition.
The runtime is
$$O(k),$$
and memory is also \(O(k)\) in the current implementation, though it could be reduced to \(O(1)\) with two rolling Fibonacci variables. This is exponentially better than checking all \(2^k\) candidates.
Der Titel bezieht sich auf eine Nim-Stellung mit drei Haufen der Größen
$$n,\qquad 2n,\qquad 3n.$$
In Nim ist eine Stellung genau dann Verluststellung für den nächsten Spieler, wenn das xor aller Haufengrößen null ist. Also müssen wir die Zahlen \(n\) mit
$$1\le n\le 2^k,\qquad n\oplus 2n\oplus 3n=0$$
zählen.
Wegen
$$3n=n+2n$$
wird die xor-Bedingung zu
$$n\oplus 2n\oplus (n+2n)=0.$$
Nun gilt in Binärarithmetik
$$a\oplus b=a+b \iff a\land b=0,$$
also xor gleich gewöhnlicher Addition genau dann, wenn kein Übertrag auftritt. Damit folgt
$$n\oplus 2n\oplus 3n=0 \iff n\oplus 2n=n+2n \iff n\land 2n=0.$$
Multiplikation mit \(2\) ist einfach ein Linksshift:
$$2n=n\ll 1.$$
Die Bedingung
$$n\land 2n=0$$
sagt also, dass sich keine 1-Bits von \(n\) mit den um eine Stelle nach links verschobenen Bits überlappen dürfen. Das ist genau dann der Fall, wenn die Binärdarstellung von \(n\) keine Teilfolge \(11\) enthält. Also gilt
$$n\oplus 2n\oplus 3n=0$$
genau dann, wenn \(n\) keine benachbarten Einsen besitzt.
Für \(n=5\) gilt
$$5=101_2,\qquad 10=1010_2,\qquad 15=1111_2.$$
Da \(101\) keine benachbarten Einsen enthält, ist die Summe \(5+10\) übertragsfrei, und tatsächlich
$$5\oplus 10\oplus 15=0.$$
Für \(n=6\) hingegen ist
$$6=110_2,$$
also treten benachbarte Einsen auf; damit entsteht beim Addieren von \(6\) und \(12\) ein Übertrag, und entsprechend ist
$$6\oplus 12\oplus 18\ne 0.$$
Sei \(A_t\) die Anzahl binärer Strings der Länge \(t\) ohne benachbarte Einsen. Dann gibt es zwei Fälle:
Endet auf 0. Dann sind die ersten \(t-1\) Bits ein beliebiger gültiger String der Länge \(t-1\).
Endet auf 1. Dann muss das vorige Bit 0 sein, und die ersten \(t-2\) Bits bilden einen gültigen String der Länge \(t-2\).
Also gilt
$$A_t=A_{t-1}+A_{t-2},$$
mit Anfangswerten
$$A_0=1,\qquad A_1=2.$$
Das ist eine Fibonacci-Rekursion. Mit der Konvention
$$F_1=1,\qquad F_2=1,\qquad F_m=F_{m-1}+F_{m-2}$$
erhält man
$$A_t=F_{t+2}.$$
\(A_k\) zählt gültige \(k\)-Bit-Strings, also genau die Zahlen im Bereich
$$0\le n<2^k.$$
Die Aufgabe verlangt aber
$$1\le n\le 2^k.$$
Das ändert die Menge nur minimal: \(0\) fällt weg, aber \(2^k\) kommt hinzu. Dessen Binärdarstellung ist
$$1000\cdots 0,$$
also ebenfalls gültig. Deshalb bleibt die Anzahl unverändert. Die gesuchte Antwort ist also
$$A_k=F_{k+2}.$$
Für \(k=3\) sind die gültigen Werte
$$1,2,4,5,8,$$
also insgesamt
$$5=F_5.$$
Der C++-Checkpoint lautet
$$k=10 \Rightarrow F_{12}=144.$$
Für das eigentliche Ziel der Aufgabe gilt
$$k=30 \Rightarrow F_{32}=2178309.$$
Der Solver testet kein einziges \(n\) direkt. Er berechnet nur Fibonacci-Zahlen bis zum benötigten Index \(k+2\) und gibt diesen Wert zurück. Die Brute-Force-Checks der C++-Version für kleine Exponenten bestätigen, dass dieser kombinatorische Zählwert exakt mit der ursprünglichen xor-Bedingung übereinstimmt.
Die Laufzeit ist
$$O(k),$$
der Speicher im aktuellen Code ebenfalls \(O(k)\); mit rollenden Variablen wäre auch \(O(1)\) möglich. Gegenüber dem naiven Test aller \(2^k\) Kandidaten ist das ein exponentieller Gewinn.
Başlık, yığın boyutları
$$n,\qquad 2n,\qquad 3n$$
olan üç yığınlı bir Nim durumunu ifade eder. Nim'de sıradaki oyuncu için kayıp durum, yığınların xor'unun sıfır olmasıdır. Bu yüzden
$$1\le n\le 2^k,\qquad n\oplus 2n\oplus 3n=0$$
şartını sağlayan \(n\) değerlerini saymamız gerekir.
$$3n=n+2n$$
olduğundan xor eşitliği
$$n\oplus 2n\oplus (n+2n)=0$$
haline gelir. Şimdi şu ikilik kimliği kullanalım:
$$a\oplus b=a+b \iff a\land b=0.$$
Bu, xor'un normal toplama ile ancak taşıma yoksa aynı olduğunu söyler. Dolayısıyla
$$n\oplus 2n\oplus 3n=0 \iff n\oplus 2n=n+2n \iff n\land 2n=0.$$
\(2\) ile çarpmak sadece sola kaydırmaktır:
$$2n=n\ll 1.$$
O halde
$$n\land 2n=0$$
koşulu, \(n\)'in bir bitinin sola kaymış haliyle çakışmamasını ister. Bu da tam olarak \(n\)'in ikilik yazımında yan yana iki tane \(1\) bulunmaması anlamına gelir. Yani
$$n\oplus 2n\oplus 3n=0$$
ancak ve ancak \(n\)'in ikilik gösterimi \(11\) alt dizisini içermiyorsa doğrudur.
\(n=5\) için
$$5=101_2,\qquad 10=1010_2,\qquad 15=1111_2$$
olur. \(101\) yazımında yan yana 1 olmadığı için toplama taşımasızdır ve gerçekten
$$5\oplus 10\oplus 15=0.$$
Öte yandan \(n=6\) için
$$6=110_2$$
yazımı yan yana 1 içerir; bu yüzden \(6+12\) toplamında taşıma oluşur ve
$$6\oplus 12\oplus 18\ne 0$$
çıkar.
Uzunluğu \(t\) olan ve ardışık 1 içermeyen ikilik dizilerin sayısına \(A_t\) diyelim. İki durum vardır:
Son bit 0 ise. İlk \(t-1\) bit herhangi bir geçerli uzunluk-\((t-1)\) dizi olabilir.
Son bit 1 ise. Bir önceki bit zorunlu olarak 0 olmalı; ilk \(t-2\) bit de geçerli bir uzunluk-\((t-2)\) dizi oluşturmalıdır.
Böylece
$$A_t=A_{t-1}+A_{t-2}$$
elde edilir. Başlangıç değerleri
$$A_0=1,\qquad A_1=2$$
olduğundan bu bir Fibonacci sayımıdır. Eğer
$$F_1=1,\qquad F_2=1,\qquad F_m=F_{m-1}+F_{m-2}$$
tanımını kullanırsak
$$A_t=F_{t+2}$$
olur.
\(A_k\), geçerli \(k\)-bit dizilerini, yani
$$0\le n<2^k$$
aralığındaki geçerli sayıları sayar. Fakat problem
$$1\le n\le 2^k$$
aralığını ister. Bu değişiklik çok basittir: \(0\) listeden çıkar, ama yerine
$$2^k=1000\cdots 0_2$$
sayısı eklenir ve bu sayı da açıkça geçerlidir. Yani toplam sayı hiç değişmez. Sonuç bu yüzden
$$A_k=F_{k+2}$$
olur. Kodun Fibonacci tablosuyla döndürdüğü değer tam olarak budur.
\(k=3\) için geçerli değerler
$$1,2,4,5,8$$
olduğundan sayı
$$5=F_5$$
çıkar. C++ çözümündeki ikinci kontrol
$$k=10 \Rightarrow F_{12}=144$$
şeklindedir. Asıl Project Euler hedefi için ise
$$k=30 \Rightarrow F_{32}=2178309.$$
Çözücü tek tek \(n\) değerlerini test etmez. Yalnızca gerekli indeks kadar Fibonacci sayısı üretir ve doğru terimi döndürür. C++ sürümündeki küçük brute-force testleri de bu kombinatoryal sayımın xor tanımıyla birebir uyuştuğunu doğrular.
Çalışma süresi
$$O(k),$$
bellek ise mevcut kodda \(O(k)\)'dir; kayan iki Fibonacci terimi ile \(O(1)\)'e de indirilebilir. Bu, tüm \(2^k\) adayı denemeye göre üstel ölçüde daha iyidir.
El título alude a una posición de Nim con montones de tamaño
$$n,\qquad 2n,\qquad 3n.$$
En Nim, una posición es perdedora para el siguiente jugador exactamente cuando el xor de los montones es cero. Por tanto, debemos contar los enteros \(n\) tales que
$$1\le n\le 2^k,\qquad n\oplus 2n\oplus 3n=0.$$
Como
$$3n=n+2n,$$
la condición xor se reescribe como
$$n\oplus 2n\oplus (n+2n)=0.$$
Ahora usamos la identidad binaria
$$a\oplus b=a+b \iff a\land b=0,$$
que dice que xor coincide con la suma ordinaria exactamente cuando no hay acarreos. Entonces
$$n\oplus 2n\oplus 3n=0 \iff n\oplus 2n=n+2n \iff n\land 2n=0.$$
Multiplicar por \(2\) sólo desplaza a la izquierda:
$$2n=n\ll 1.$$
Por tanto, la condición
$$n\land 2n=0$$
dice que ningún bit 1 de \(n\) puede solaparse con el bit siguiente tras el desplazamiento. Eso ocurre exactamente cuando la expansión binaria de \(n\) no contiene el patrón \(11\). Así,
$$n\oplus 2n\oplus 3n=0$$
si y sólo si \(n\) no tiene unos adyacentes en binario.
Para \(n=5\),
$$5=101_2,\qquad 10=1010_2,\qquad 15=1111_2.$$
Como \(101\) no tiene unos consecutivos, la suma es sin acarreos y en efecto
$$5\oplus 10\oplus 15=0.$$
En cambio, para \(n=6\),
$$6=110_2,$$
hay unos consecutivos, así que aparece un acarreo en \(6+12\) y
$$6\oplus 12\oplus 18\ne 0.$$
Sea \(A_t\) el número de cadenas binarias de longitud \(t\) sin unos adyacentes. Hay dos casos:
Termina en 0. Los primeros \(t-1\) bits pueden ser cualquier cadena válida de longitud \(t-1\).
Termina en 1. El bit anterior debe ser 0, y los primeros \(t-2\) bits forman cualquier cadena válida de longitud \(t-2\).
Por tanto,
$$A_t=A_{t-1}+A_{t-2},$$
con valores iniciales
$$A_0=1,\qquad A_1=2.$$
Ésta es una recurrencia de Fibonacci. Si usamos
$$F_1=1,\qquad F_2=1,\qquad F_m=F_{m-1}+F_{m-2},$$
entonces
$$A_t=F_{t+2}.$$
\(A_k\) cuenta cadenas válidas de longitud \(k\), es decir, enteros válidos en el rango
$$0\le n<2^k.$$
Pero el problema pide
$$1\le n\le 2^k.$$
La diferencia es simple: quitamos el \(0\), pero añadimos \(2^k\), cuya forma binaria es
$$1000\cdots 0,$$
que también es válida. Así, el número total no cambia. La respuesta final es entonces
$$A_k=F_{k+2}.$$
Para \(k=3\), los valores válidos son
$$1,2,4,5,8,$$
así que el conteo es
$$5=F_5.$$
El checkpoint en C++ da
$$k=10 \Rightarrow F_{12}=144.$$
Para el objetivo real de Project Euler,
$$k=30 \Rightarrow F_{32}=2178309.$$
El solver no prueba ningún \(n\) individualmente. Sólo construye los números de Fibonacci hasta el índice necesario \(k+2\) y devuelve ese valor. Las comprobaciones brute-force en C++ para exponentes pequeños validan que este conteo combinatorio coincide exactamente con la definición por xor.
El tiempo es
$$O(k),$$
y la memoria también es \(O(k)\) en la implementación actual, aunque podría reducirse a \(O(1)\) con dos variables rodantes. Eso es exponencialmente mejor que verificar los \(2^k\) candidatos.
标题中的 Nim 指的是三个堆的大小分别为
$$n,\qquad 2n,\qquad 3n.$$
在 Nim 中,当且仅当所有堆大小的 xor 为 \(0\) 时,当前局面对下一位玩家是必败态。因此我们要统计满足
$$1\le n\le 2^k,\qquad n\oplus 2n\oplus 3n=0$$
的整数 \(n\) 的个数。
因为
$$3n=n+2n,$$
所以 xor 条件可写成
$$n\oplus 2n\oplus (n+2n)=0.$$
再利用二进制恒等式
$$a\oplus b=a+b \iff a\land b=0,$$
即 xor 与普通加法相同当且仅当没有进位。于是
$$n\oplus 2n\oplus 3n=0 \iff n\oplus 2n=n+2n \iff n\land 2n=0.$$
乘以 \(2\) 只是左移一位:
$$2n=n\ll 1.$$
因此条件
$$n\land 2n=0$$
表示 \(n\) 中的某个 1 位不能与左移后的下一位重叠。这恰好等价于 \(n\) 的二进制表示中不含子串 \(11\)。所以
$$n\oplus 2n\oplus 3n=0$$
当且仅当 \(n\) 的二进制没有相邻的两个 1。
取 \(n=5\),则
$$5=101_2,\qquad 10=1010_2,\qquad 15=1111_2.$$
因为 \(101\) 没有相邻的 1,所以是无进位相加,确实有
$$5\oplus 10\oplus 15=0.$$
而 \(n=6\) 时,
$$6=110_2$$
含有相邻的 1,因此 \(6+12\) 会产生进位,从而
$$6\oplus 12\oplus 18\ne 0.$$
设 \(A_t\) 为长度 \(t\) 的“无相邻 1”二进制串个数。分两类:
末位是 0。 前 \(t-1\) 位可以是任意合法长度 \(t-1\) 串。
末位是 1。 前一位必须是 0,因此前 \(t-2\) 位可以是任意合法长度 \(t-2\) 串。
故有递推
$$A_t=A_{t-1}+A_{t-2},$$
初值为
$$A_0=1,\qquad A_1=2.$$
这就是 Fibonacci 型递推。若取
$$F_1=1,\qquad F_2=1,\qquad F_m=F_{m-1}+F_{m-2},$$
则
$$A_t=F_{t+2}.$$
\(A_k\) 统计的是长度为 \(k\) 的合法 bit 串,也就是区间
$$0\le n<2^k$$
中的合法整数个数。但题目要求的是
$$1\le n\le 2^k.$$
这只是把 \(0\) 去掉,再把 \(2^k\) 加进来。由于
$$2^k=1000\cdots 0_2$$
本身也是合法的,所以总数完全不变。因此最终答案仍为
$$A_k=F_{k+2}.$$
当 \(k=3\) 时,合法值为
$$1,2,4,5,8,$$
总数是
$$5=F_5.$$
C++ 中的小检查还给出
$$k=10 \Rightarrow F_{12}=144.$$
对于真正的 Project Euler 目标,
$$k=30 \Rightarrow F_{32}=2178309.$$
程序完全不逐个测试 \(n\)。它只构造到所需下标 \(k+2\) 的 Fibonacci 数并直接返回。C++ 版本对小指数做 brute-force 对照,验证这个组合计数与原始 xor 定义完全一致。
时间复杂度为
$$O(k),$$
当前实现的空间复杂度也是 \(O(k)\),但若只保留最近两项 Fibonacci,可降到 \(O(1)\)。相比枚举全部 \(2^k\) 个候选,这是指数级提升。
Название задачи отсылает к позиции в Ниме с тремя кучами размеров
$$n,\qquad 2n,\qquad 3n.$$
В Ниме позиция проигрышна для следующего игрока тогда и только тогда, когда xor размеров куч равен нулю. Значит, нужно подсчитать все \(n\), удовлетворяющие
$$1\le n\le 2^k,\qquad n\oplus 2n\oplus 3n=0.$$
Так как
$$3n=n+2n,$$
условие xor переписывается как
$$n\oplus 2n\oplus (n+2n)=0.$$
Используем двоичную тождественность
$$a\oplus b=a+b \iff a\land b=0,$$
то есть xor совпадает с обычным сложением тогда и только тогда, когда нет переносов. Поэтому
$$n\oplus 2n\oplus 3n=0 \iff n\oplus 2n=n+2n \iff n\land 2n=0.$$
Умножение на \(2\) — это просто сдвиг влево:
$$2n=n\ll 1.$$
Следовательно, условие
$$n\land 2n=0$$
говорит, что ни один единичный бит числа \(n\) не должен накладываться на единичный бит после сдвига. Это эквивалентно тому, что двоичная запись \(n\) не содержит подстроки \(11\). Итак,
$$n\oplus 2n\oplus 3n=0$$
тогда и только тогда, когда у \(n\) нет соседних единиц в двоичной записи.
Для \(n=5\) имеем
$$5=101_2,\qquad 10=1010_2,\qquad 15=1111_2.$$
Запись \(101\) не содержит соседних единиц, поэтому сложение без переносов возможно, и действительно
$$5\oplus 10\oplus 15=0.$$
А для \(n=6\)
$$6=110_2,$$
где уже есть соседние единицы; значит, в \(6+12\) появится перенос, и потому
$$6\oplus 12\oplus 18\ne 0.$$
Пусть \(A_t\) — число двоичных строк длины \(t\) без соседних единиц. Есть два варианта:
Строка оканчивается на 0. Тогда первые \(t-1\) битов образуют любую допустимую строку длины \(t-1\).
Строка оканчивается на 1. Тогда предыдущий бит обязан быть 0, а первые \(t-2\) битов образуют любую допустимую строку длины \(t-2\).
Значит,
$$A_t=A_{t-1}+A_{t-2},$$
с начальными значениями
$$A_0=1,\qquad A_1=2.$$
Это именно рекурсия Фибоначчи. При соглашении
$$F_1=1,\qquad F_2=1,\qquad F_m=F_{m-1}+F_{m-2}$$
получаем
$$A_t=F_{t+2}.$$
\(A_k\) считает допустимые \(k\)-битные строки, то есть числа из диапазона
$$0\le n<2^k.$$
Но в задаче нужен диапазон
$$1\le n\le 2^k.$$
Из множества уходит \(0\), но добавляется \(2^k\), а его двоичная запись
$$1000\cdots 0$$
тоже допустима. Поэтому итоговое количество не меняется. Следовательно, ответ равен
$$A_k=F_{k+2}.$$
При \(k=3\) допустимые числа таковы:
$$1,2,4,5,8,$$
поэтому количество равно
$$5=F_5.$$
В C++ есть контроль
$$k=10 \Rightarrow F_{12}=144.$$
Для реальной задачи Project Euler
$$k=30 \Rightarrow F_{32}=2178309.$$
Решение вообще не проверяет отдельные значения \(n\). Оно просто строит числа Фибоначчи до нужного индекса \(k+2\) и возвращает соответствующее значение. Brute-force проверки для малых \(k\) в C++ подтверждают, что это комбинаторное рассуждение точно совпадает с исходным xor-условием.
Время работы равно
$$O(k),$$
а память в текущем коде тоже \(O(k)\), хотя с двумя скользящими переменными её можно уменьшить до \(O(1)\). Это экспоненциально лучше, чем проверять все \(2^k\) кандидатов.
عنوان المسألة يشير إلى وضعية Nim ذات ثلاث كومات أحجامها
$$n,\qquad 2n,\qquad 3n.$$
وفي Nim تكون الوضعية خاسرة للاعب التالي إذا وفقط إذا كان xor لأحجام الكومات يساوي الصفر. لذلك نحتاج إلى عدّ كل \(n\) التي تحقق
$$1\le n\le 2^k,\qquad n\oplus 2n\oplus 3n=0.$$
بما أن
$$3n=n+2n,$$
فإن شرط xor يصبح
$$n\oplus 2n\oplus (n+2n)=0.$$
ونستخدم الهوية الثنائية
$$a\oplus b=a+b \iff a\land b=0,$$
أي أن xor يساوي الجمع العادي تمامًا عندما لا يوجد حمل. ومن ثم
$$n\oplus 2n\oplus 3n=0 \iff n\oplus 2n=n+2n \iff n\land 2n=0.$$
الضرب في \(2\) مجرد إزاحة لليسار:
$$2n=n\ll 1.$$
إذن الشرط
$$n\land 2n=0$$
يعني أن أي بت يساوي \(1\) في \(n\) لا يجوز أن يتراكب مع بت يساوي \(1\) بعد الإزاحة. وهذا يكافئ تمامًا أن التمثيل الثنائي لـ \(n\) لا يحتوي على المقطع \(11\). أي أن
$$n\oplus 2n\oplus 3n=0$$
إذا وفقط إذا لم تكن في كتابة \(n\) الثنائية وحدتان متجاورتان.
إذا أخذنا \(n=5\)، فإن
$$5=101_2,\qquad 10=1010_2,\qquad 15=1111_2.$$
ولأن \(101\) لا يحتوي على وحدتين متجاورتين، يكون الجمع بلا حمل، وبالفعل
$$5\oplus 10\oplus 15=0.$$
أما عند \(n=6\)، فإن
$$6=110_2$$
يحتوي على وحدتين متجاورتين، ولذلك يظهر حمل في \(6+12\)، ومن ثم
$$6\oplus 12\oplus 18\ne 0.$$
ليكن \(A_t\) عدد السلاسل الثنائية بطول \(t\) التي لا تحتوي على وحدات متجاورة. لدينا حالتان:
تنتهي بـ 0. حينها تكون أول \(t-1\) بتات أي سلسلة صالحة بطول \(t-1\).
تنتهي بـ 1. حينها يجب أن يكون البت السابق 0، وتكون أول \(t-2\) بتات أي سلسلة صالحة بطول \(t-2\).
إذًا
$$A_t=A_{t-1}+A_{t-2},$$
مع القيم الابتدائية
$$A_0=1,\qquad A_1=2.$$
وهذه علاقة فيبوناتشي. وإذا استخدمنا التعريف
$$F_1=1,\qquad F_2=1,\qquad F_m=F_{m-1}+F_{m-2},$$
فإن
$$A_t=F_{t+2}.$$
العدد \(A_k\) يحصي السلاسل الصحيحة بطول \(k\)، أي الأعداد الصحيحة المسموح بها ضمن المجال
$$0\le n<2^k.$$
لكن المسألة تطلب المجال
$$1\le n\le 2^k.$$
والفرق هنا بسيط: نحذف \(0\)، لكننا نضيف \(2^k\)، وتمثيله الثنائي هو
$$1000\cdots 0,$$
وهو صالح أيضًا لأنه لا يحتوي على وحدات متجاورة. لذا لا يتغير العدد الكلي أصلًا، ويكون الجواب النهائي
$$A_k=F_{k+2}.$$
عند \(k=3\) تكون القيم الصحيحة
$$1,2,4,5,8,$$
ومن ثم يكون العدد
$$5=F_5.$$
ولدى كود ++C نقطة تحقق أخرى:
$$k=10 \Rightarrow F_{12}=144.$$
أما للهدف الحقيقي في Project Euler فنحصل على
$$k=30 \Rightarrow F_{32}=2178309.$$
لا يختبر الحل أي قيمة \(n\) على حدة. بل يبني أعداد فيبوناتشي حتى الفهرس المطلوب \(k+2\) ثم يعيد هذه القيمة مباشرة. كما أن اختبارات brute-force الصغيرة في نسخة ++C تؤكد أن هذا العد التوافقي يطابق تعريف xor الأصلي بدقة.
زمن التنفيذ هو
$$O(k),$$
والذاكرة أيضًا \(O(k)\) في التنفيذ الحالي، مع إمكانية خفضها إلى \(O(1)\) باستعمال آخر حدين فقط من فيبوناتشي. وهذا أفضل أُسّيًا من فحص جميع \(2^k\) قيم ممكنة.