Call a positive integer \(b\)-pandigital if its base-\(b\) representation contains every digit \(0,1,\dots,b-1\) at least once. It is \(n\)-super-pandigital if this happens for every base \(b\) with \(2 \le b \le n\). The task is to find the 10 smallest 12-super-pandigital numbers and sum them.
The key point is that the smallest solutions cannot come from arbitrary integers. Any 12-super-pandigital number must already be pandigital in base 12, and that forces a very rigid structure that makes an ordered search possible.
The method used by the implementations rests on five ideas: restrict the search to the smallest possible base-12 length, test digit coverage with a bit mask, reject candidates as soon as one base fails, preserve numerical order through lexicographic permutation order, and jump directly to permutation blocks with the factorial number system.
If \(x\) is 12-super-pandigital, then its base-12 expansion must contain every digit \(0,1,\dots,11\). Therefore the expansion must have at least 12 digits.
The smallest possible candidates are exactly those with 12 digits in base 12. In that case every required digit appears once, so the digit string is a permutation of
$$\{0,1,2,\dots,11\}.$$
The leading digit cannot be \(0\), because that would really be an 11-digit representation. Hence the minimal search layer consists of all base-12 numbers whose digits are a permutation of \(0,1,\dots,11\) with nonzero first digit.
The number of such candidates is
$$12!-11!=11\cdot 11!.$$
This is the whole reason the search is feasible: once the program finds 10 valid numbers inside this 12-digit layer, they are automatically the 10 smallest overall, because every base-12 number with more than 12 digits is larger than every member of the minimal layer.
Fix a base \(b\). Repeated division writes \(x\) as
$$x=d_0+d_1b+d_2b^2+\cdots,\qquad 0\le d_i<b.$$
Every remainder \(d_i\) is a digit of the base-\(b\) expansion. To record which digits appear, set bit \(d_i\) in a mask. In mathematical notation, define
$$S_b(x)=\bigvee_i 2^{d_i},$$
where \(\vee\) denotes bitwise OR. The full mask for base \(b\) is
$$M_b=2^b-1.$$
Then
$$x\text{ is }b\text{-pandigital}\iff S_b(x)=M_b.$$
This criterion is exact because digit \(j\) appears at least once if and only if bit \(j\) is set. It also supports early exit: once the mask has become \(M_b\), the remaining digits no longer matter.
Every candidate in the minimal layer is already 12-pandigital by construction, so only the smaller bases remain to be checked. Thus
$$x\text{ is 12-super-pandigital}\iff \forall b\in\{2,3,\dots,11\},\ S_b(x)=2^b-1.$$
The implementations test these bases from larger to smaller and stop immediately at the first failure. This is mathematically sound because the condition is a conjunction: one failed base is enough to reject the candidate.
Every minimal candidate has the form
$$x=a_{11}12^{11}+a_{10}12^{10}+\cdots+a_1 12+a_0,$$
where \((a_{11},a_{10},\dots,a_0)\) is a permutation of \(0,1,\dots,11\) and \(a_{11}\ne 0\).
For fixed length and fixed base, lexicographic order of the digit tuples is the same as numerical order. The first differing higher-position digit dominates all lower positions. Therefore a lexicographic permutation scan lists these candidates from smallest to largest.
That justifies two practical rules:
$$\text{skip every permutation whose first digit is }0,$$
and
$$\text{stop as soon as 10 hits have been collected.}$$
The optimized 12-case search does not restart from the beginning for every worker. Instead it uses factoradic indexing, which maps an integer \(k\) directly to the \(k\)-th permutation in lexicographic order.
Because the first \(11!\) lexicographic permutations begin with digit \(0\), the useful interval is
$$11!\le k<12!.$$
This makes block decomposition straightforward. The C++ implementation splits the interval into chunks of size
$$9!,$$
lets each worker decode the first permutation of its block, and then advances lexicographically within that block. The blocks are disjoint, so parallelism changes only running time, not the mathematics.
A useful small checkpoint is the smallest 5-super-pandigital number, \(978\). Its representations are
$$978=12403_5=33102_4=1100020_3=1111010010_2.$$
In base \(5\), the digits \(0,1,2,3,4\) all appear. In base \(4\), the digits \(0,1,2,3\) all appear. In base \(3\), the digits \(0,1,2\) all appear. In base \(2\), both digits \(0\) and \(1\) appear. Hence \(978\) is pandigital in every base from \(2\) through \(5\), so it is 5-super-pandigital.
The C++, Python, and Java implementations all follow the same mathematical plan. They search the minimal base-12 pandigital layer, convert each permutation into its numeric value, and then test bases \(11\) down to \(2\) with the coverage-mask criterion.
The generic per-base test repeatedly extracts a remainder, sets the corresponding bit, divides by the base, and compares the current mask against the full mask. The C++ implementation adds two engineering optimizations for the final 12-case. For base \(8\), digit extraction becomes
$$x\bmod 8=x\,\&\,7,\qquad \left\lfloor\frac{x}{8}\right\rfloor=x\gg 3,$$
so the loop uses fast bit operations. For the remaining search space, factoradic block starts allow multiple workers to scan disjoint chunks in parallel before the hits are merged and sorted.
The Java implementation uses the same mathematical search but performs the permutation scan sequentially through direct index-to-permutation decoding. The Python implementation delegates execution to the compiled search, so it inherits the same ordering of candidates and the same pandigital tests.
The minimal layer contains \(12!-11!\) candidates. For each candidate, at most 10 additional bases need to be checked. A single base check takes time proportional to the number of digits of the candidate in that base, which is bounded by a small constant because \(n=12\) is fixed.
So, for this problem, the worst-case running time is dominated by scanning the permutation layer and is effectively \(O(12!)\), with strong constant-factor reductions from early rejection, base-specific fast paths, and parallel block processing. Memory usage is \(O(1)\) per worker plus a small buffer for the successful hits.
Eine positive ganze Zahl heißt \(b\)-pandigital, wenn ihre Darstellung zur Basis \(b\) jede Ziffer \(0,1,\dots,b-1\) mindestens einmal enthält. Sie heißt \(n\)-super-pandigital, wenn das für jede Basis \(b\) mit \(2 \le b \le n\) gilt. Gesucht ist die Summe der 10 kleinsten 12-super-pandigitalen Zahlen.
Der entscheidende Punkt ist, dass die kleinsten Lösungen nicht aus einer unstrukturierten Ganzzahlsuche kommen. Jede 12-super-pandigitale Zahl muss bereits in Basis 12 pandigital sein, und genau das erzwingt einen stark eingeschränkten Suchraum.
Die Lösung beruht auf fünf Beobachtungen: Man beschränkt sich auf die minimale Basis-12-Länge, testet Ziffernabdeckung mit einer Bitmaske, verwirft Kandidaten beim ersten fehlgeschlagenen Test, benutzt die lexikographische Reihenfolge der Permutationen als Zahlenreihenfolge und springt mit dem Fakultätszahlensystem direkt zu Blockanfängen.
Ist \(x\) 12-super-pandigital, dann muss seine Basis-12-Darstellung alle Ziffern \(0,1,\dots,11\) enthalten. Also braucht sie mindestens 12 Stellen.
Die kleinsten möglichen Kandidaten sind genau die Zahlen mit 12 Stellen in Basis 12. Dann kommt jede erforderliche Ziffer genau einmal vor, also ist die Darstellung eine Permutation von
$$\{0,1,2,\dots,11\}.$$
Die erste Ziffer darf nicht \(0\) sein, denn sonst hätte die Zahl in Wirklichkeit nur 11 Stellen. Somit besteht die minimale Suchschicht aus allen Basis-12-Zahlen, deren Ziffern eine Permutation von \(0,1,\dots,11\) mit führender Nichtnullziffer sind.
Die Anzahl dieser Kandidaten ist
$$12!-11!=11\cdot 11!.$$
Genau dadurch wird die Suche praktikabel: Sobald innerhalb dieser 12-stelligen Schicht 10 gültige Zahlen gefunden wurden, sind es automatisch die 10 kleinsten insgesamt, denn jede Basis-12-Zahl mit mehr als 12 Stellen ist größer als jedes Element der minimalen Schicht.
Fixiere eine Basis \(b\). Durch wiederholtes Dividieren schreibt man \(x\) als
$$x=d_0+d_1b+d_2b^2+\cdots,\qquad 0\le d_i<b.$$
Jeder Rest \(d_i\) ist eine Ziffer der Basis-\(b\)-Darstellung. Um festzuhalten, welche Ziffern vorkommen, setzt man Bit \(d_i\) in einer Maske. Mathematisch definieren wir
$$S_b(x)=\bigvee_i 2^{d_i},$$
wobei \(\vee\) das bitweise OR bezeichnet. Die Vollmaske für Basis \(b\) ist
$$M_b=2^b-1.$$
Genau dann ist der Kandidat in Basis \(b\) pandigital, wenn
$$S_b(x)=M_b.$$
Dieses Kriterium ist exakt, weil Ziffer \(j\) genau dann mindestens einmal vorkommt, wenn Bit \(j\) gesetzt ist. Außerdem erlaubt es einen frühen Abbruch: Sobald die Maske \(M_b\) erreicht hat, können die restlichen Ziffern ignoriert werden.
Jeder Kandidat aus der minimalen Schicht ist konstruktionsbedingt bereits 12-pandigital. Es bleiben also nur die kleineren Basen zu prüfen. Ein Kandidat ist also genau dann 12-super-pandigital, wenn
$$\forall b\in\{2,3,\dots,11\},\ S_b(x)=2^b-1.$$
Die Implementierungen testen diese Basen von groß nach klein und brechen beim ersten Fehlschlag sofort ab. Das ist mathematisch korrekt, weil die Bedingung eine Konjunktion ist: Eine einzige fehlende Basis genügt für die Verwerfung.
Jeder minimale Kandidat hat die Form
$$x=a_{11}12^{11}+a_{10}12^{10}+\cdots+a_1 12+a_0,$$
wobei \((a_{11},a_{10},\dots,a_0)\) eine Permutation von \(0,1,\dots,11\) und \(a_{11}\ne 0\) ist.
Bei fester Länge und fester Basis stimmt die lexikographische Reihenfolge der Zifferntupel mit der numerischen Reihenfolge überein. Die erste abweichende höherwertige Ziffer entscheidet. Deshalb liefert ein lexikographischer Permutationsdurchlauf die Kandidaten bereits von klein nach groß.
Dadurch sind zwei praktische Regeln gerechtfertigt: Permutationen mit führender \(0\) werden übersprungen, und nach 10 Treffern kann die Suche beendet werden.
Die optimierte Suche für den 12er-Fall startet nicht für jeden Arbeitsblock wieder am Anfang. Stattdessen benutzt sie Faktoradiken, also eine Abbildung von einem Index \(k\) auf die \(k\)-te Permutation in lexikographischer Reihenfolge.
Da die ersten \(11!\) lexikographischen Permutationen mit der Ziffer \(0\) beginnen, ist das relevante Intervall
$$11!\le k<12!.$$
So lässt sich der Suchraum leicht in Blöcke zerlegen. Die C++-Implementierung teilt ihn in Abschnitte der Größe
$$9!,$$
jeder Arbeiter dekodiert die erste Permutation seines Blocks und läuft dann innerhalb dieses Blocks lexikographisch weiter. Da die Blöcke disjunkt sind, verändert Parallelisierung nur die Laufzeit, nicht die mathematische Korrektheit.
Ein nützlicher kleiner Kontrollwert ist die kleinste 5-super-pandigitale Zahl \(978\). Ihre Darstellungen sind
$$978=12403_5=33102_4=1100020_3=1111010010_2.$$
In Basis \(5\) kommen die Ziffern \(0,1,2,3,4\) alle vor. In Basis \(4\) kommen \(0,1,2,3\) alle vor. In Basis \(3\) kommen \(0,1,2\) alle vor. In Basis \(2\) erscheinen sowohl \(0\) als auch \(1\). Also ist \(978\) in jeder Basis von \(2\) bis \(5\) pandigital und damit 5-super-pandigital.
Die Implementierungen in C++, Python und Java folgen alle demselben mathematischen Plan. Sie durchsuchen die minimale basis-12-pandigitale Schicht, wandeln jede Permutation in ihren Zahlenwert um und testen dann die Basen \(11\) bis \(2\) mit dem Bitmasken-Kriterium.
Der allgemeine Test pro Basis extrahiert wiederholt einen Rest, setzt das zugehörige Bit, dividiert durch die Basis und vergleicht die aktuelle Maske mit der Vollmaske. Die C++-Implementierung fügt für den endgültigen 12er-Fall zwei technische Optimierungen hinzu. Für Basis \(8\) wird die Ziffernextraktion zu
$$x\bmod 8=x\,\&\,7,\qquad \left\lfloor\frac{x}{8}\right\rfloor=x\gg 3,$$
also zu reinen Bitoperationen. Außerdem erlauben faktoradische Blockanfänge, dass mehrere Arbeiter disjunkte Blöcke parallel durchsuchen, bevor die Treffer zusammengeführt und sortiert werden.
Die Java-Implementierung benutzt dieselbe Mathematik, führt die Permutationssuche aber sequentiell mit direkter Index-zu-Permutation-Dekodierung aus. Die Python-Implementierung delegiert an die kompilierte Suche und übernimmt dadurch dieselbe Kandidatenreihenfolge und dieselben Pandigitaltests.
Die minimale Schicht enthält \(12!-11!\) Kandidaten. Für jeden Kandidaten müssen höchstens 10 weitere Basen geprüft werden. Ein Basistest benötigt Zeit proportional zur Anzahl der Ziffern des Kandidaten in dieser Basis, und diese Anzahl ist hier durch kleine Konstanten beschränkt, weil \(n=12\) fest ist.
Damit wird die Worst-Case-Laufzeit in diesem Problem im Wesentlichen vom Durchlaufen der Permutationsschicht bestimmt und ist effektiv \(O(12!)\), wobei frühe Verwerfungen, basisabhängige Fast Paths und parallele Blockverarbeitung die Konstanten stark verbessern. Der Speicherbedarf ist \(O(1)\) pro Arbeiter zuzüglich eines kleinen Puffers für die erfolgreichen Treffer.
Pozitif bir tamsayıya, \(b\) tabanındaki gösterimi \(0,1,\dots,b-1\) rakamlarının her birini en az bir kez içeriyorsa \(b\)-pandigital diyelim. Sayı, \(2 \le b \le n\) aralığındaki her taban için bu özelliği sağlıyorsa \(n\)-super-pandigital olur. Amaç, en küçük 10 adet 12-super-pandigital sayıyı bulup toplamaktır.
Asıl nokta şudur: en küçük çözümler rastgele tamsayılar arasından gelmez. Her 12-super-pandigital sayı, önce taban 12'de pandigital olmak zorundadır; bu da arama uzayını son derece katı bir yapıya indirir.
Uygulamaların kullandığı yöntem beş fikre dayanır: aramayı en küçük mümkün taban-12 uzunluğuna indirgemek, rakam kapsamasını bit maskesiyle test etmek, bir taban başarısız olur olmaz adayı elemek, permütasyonları leksikografik sırada dolaşarak sayısal sırayı korumak ve faktoriyel sayı sistemiyle doğrudan blok başlarına sıçramak.
Eğer \(x\) 12-super-pandigital ise, taban 12 gösterimi \(0,1,\dots,11\) rakamlarının hepsini içermek zorundadır. Bu nedenle en az 12 basamaklı olmalıdır.
En küçük mümkün adaylar tam olarak taban 12'de 12 basamaklı olan sayılardır. Bu durumda gerekli her rakam tam bir kez görünür; dolayısıyla basamak dizisi
$$\{0,1,2,\dots,11\}$$
kümesinin bir permütasyonudur. İlk basamak \(0\) olamaz; aksi halde gösterim gerçekte 11 basamaklı olur. Demek ki en küçük arama katmanı, rakamları \(0,1,\dots,11\)'in bir permütasyonu olan ve ilk rakamı sıfır olmayan bütün taban-12 sayılarından oluşur.
Bu adayların sayısı
$$12!-11!=11\cdot 11!$$
kadardır. Aramanın uygulanabilir olmasını sağlayan nokta tam da budur: program bu 12 basamaklı katman içinde 10 geçerli sayı bulduğunda, bunlar otomatik olarak genel sıralamadaki en küçük 10 sonuçtur; çünkü taban 12'de 12'den fazla basamağı olan her sayı, bu katmandaki her elemandan büyüktür.
Sabit bir \(b\) tabanı alalım. Tekrarlı bölme ile
$$x=d_0+d_1b+d_2b^2+\cdots,\qquad 0\le d_i<b$$
yazabiliriz. Her kalan \(d_i\), taban-\(b\) gösterimindeki bir rakamdır. Hangi rakamların görüldüğünü kaydetmek için, maske içinde \(d_i\). biti açılır. Matematiksel olarak
$$S_b(x)=\bigvee_i 2^{d_i}$$
tanımını yapalım; burada \(\vee\) bit düzeyinde OR anlamına gelir. Taban \(b\) için tam maske
$$M_b=2^b-1$$
olur. Buna göre aday tam olarak
$$S_b(x)=M_b$$
olduğunda taban \(b\)'de pandigitaldir.
Bu ölçüt tam doğrudur; çünkü rakam \(j\) en az bir kez görülüyorsa ve ancak o zaman maskenin \(j\). biti 1 olur. Ayrıca erken çıkış da sağlar: maske \(M_b\)'ye ulaştığı anda kalan basamaklar artık önemsizdir.
En küçük katmandaki her aday yapı gereği zaten taban 12'de pandigitaldir. Dolayısıyla sadece daha küçük tabanları kontrol etmek gerekir. Adayın 12-super-pandigital olması için gerekli ve yeterli koşul
$$\forall b\in\{2,3,\dots,11\},\ S_b(x)=2^b-1.$$
Uygulamalar bu tabanları büyükten küçüğe doğru dener ve ilk başarısızlıkta hemen durur. Bunun matematiksel nedeni basittir: koşul bir bütünleyici "ve" ifadesidir; tek bir başarısızlık adayı elemek için yeterlidir.
Her minimal aday
$$x=a_{11}12^{11}+a_{10}12^{10}+\cdots+a_1 12+a_0$$
biçimindedir; burada \((a_{11},a_{10},\dots,a_0)\), \(0,1,\dots,11\)'in bir permütasyonudur ve \(a_{11}\ne 0\)'dır.
Sabit uzunlukta ve sabit tabanda, rakam dizilerinin leksikografik sırası ile sayısal büyüklük sırası aynıdır. Üst basamaklarda ilk fark oluştuğu anda karşılaştırma belirlenir. Bu nedenle permütasyonları leksikografik sırada gezmek, adayları küçükten büyüğe gezmek demektir.
Bu da iki pratik kuralı gerekçelendirir: ilk basamağı \(0\) olan tüm permütasyonlar atlanır ve 10 sonuç bulunduğunda arama durdurulur.
12 durumu için yapılan optimize arama, her işçi için baştan başlamak yerine faktoradik indeksleme kullanır. Bu gösterim, bir \(k\) tam sayısını leksikografik sıradaki \(k\). permütasyona doğrudan eşler.
İlk \(11!\) leksikografik permütasyonun başında \(0\) bulunduğu için, anlamlı aralık
$$11!\le k<12!$$
olur. Böylece arama uzayını bloklara ayırmak kolaylaşır. C++ uygulaması bu aralığı
$$9!$$
büyüklüğünde parçalara böler, her işçi kendi bloğunun ilk permütasyonunu açar ve sonra o blok içinde leksikografik olarak ilerler. Bloklar ayrık olduğu için paralellik sadece çalışma süresini değiştirir; matematiksel doğruluk aynen korunur.
Küçük ama faydalı bir kontrol değeri, en küçük 5-super-pandigital sayı olan \(978\)'dir. Bu sayının gösterimleri
$$978=12403_5=33102_4=1100020_3=1111010010_2$$
şeklindedir. Taban \(5\)'te \(0,1,2,3,4\) rakamlarının hepsi görülür. Taban \(4\)'te \(0,1,2,3\) rakamlarının hepsi görülür. Taban \(3\)'te \(0,1,2\) rakamlarının hepsi vardır. Taban \(2\)'de hem \(0\) hem \(1\) bulunur. Bu nedenle \(978\), \(2\)'den \(5\)'e kadar her tabanda pandigitaldir; dolayısıyla 5-super-pandigitaldir.
C++, Python ve Java uygulamalarının hepsi aynı matematiksel planı izler. Önce minimal taban-12 pandigital katmanı taranır, her permütasyon sayıya dönüştürülür ve ardından \(11\)'den \(2\)'ye kadar olan tabanlar kapsama maskesiyle sınanır.
Genel taban testi, tekrar tekrar kalan alır, ilgili biti açar, tabana böler ve mevcut maskeyi tam maskeyle karşılaştırır. C++ uygulaması son 12 durumunda iki ek mühendislik optimizasyonu kullanır. Taban \(8\) için rakam çıkarma
$$x\bmod 8=x\,\&\,7,\qquad \left\lfloor\frac{x}{8}\right\rfloor=x\gg 3$$
biçimine indirgenir; yani işlem saf bit operasyonlarına dönüşür. Ayrıca faktoradik blok başları sayesinde birden fazla işçi ayrık blokları paralel tarar; sonra bulunan adaylar birleştirilip sıralanır.
Java uygulaması aynı matematiksel aramayı sürdürür, fakat permütasyon taramasını doğrudan indeks->permütasyon açılımı ile sıralı olarak yapar. Python uygulaması ise derlenmiş aramayı çağırdığı için aynı aday sırasını ve aynı pandigital testlerini miras alır.
Minimal katmanda \(12!-11!\) adet aday vardır. Her aday için en fazla 10 ek taban testi gerekir. Tek bir taban testi, sayının o tabandaki basamak sayısı ile orantılı zaman alır; fakat burada \(n=12\) sabit olduğu için bu uzunluklar küçük sabitlerle sınırlıdır.
Bu nedenle problem özelinde en kötü durum süresi esas olarak permütasyon katmanını taramaktan gelir ve pratikte \(O(12!)\) olarak düşünülebilir. Erken eleme, tabana özel hızlandırmalar ve paralel blok işleme sabit katsayıları belirgin biçimde azaltır. Bellek kullanımı her işçi için \(O(1)\) ve başarılı sonuçlar için küçük bir tampon kadardır.
Llamemos \(b\)-pandigital a un entero positivo cuya representación en base \(b\) contiene cada dígito \(0,1,\dots,b-1\) al menos una vez. Un número es \(n\)-super-pandigital si esto ocurre para toda base \(b\) con \(2 \le b \le n\). El objetivo es hallar los 10 menores números 12-super-pandigitales y sumar esos 10 valores.
La observación clave es que las soluciones más pequeñas no provienen de recorrer enteros arbitrarios. Cualquier 12-super-pandigital ya debe ser pandigital en base 12, y eso fuerza una estructura muy rígida que vuelve viable la búsqueda ordenada.
El método se apoya en cinco ideas: restringir la búsqueda a la longitud mínima posible en base 12, comprobar la cobertura de dígitos con una máscara de bits, descartar un candidato en cuanto falle una base, aprovechar que el orden lexicográfico de las permutaciones coincide con el orden numérico, y saltar directamente a bloques de permutaciones usando el sistema factorial.
Si \(x\) es 12-super-pandigital, entonces su escritura en base 12 debe contener todos los dígitos \(0,1,\dots,11\). Por tanto necesita al menos 12 cifras en base 12.
Los candidatos más pequeños posibles son exactamente los que tienen 12 cifras en base 12. En ese caso cada dígito requerido aparece una vez, así que la cadena de cifras es una permutación de
$$\{0,1,2,\dots,11\}.$$
La primera cifra no puede ser \(0\), porque entonces la representación real tendría solo 11 cifras. Así, la capa mínima de búsqueda está formada por todos los números de base 12 cuyas cifras son una permutación de \(0,1,\dots,11\) con primera cifra no nula.
El número de esos candidatos es
$$12!-11!=11\cdot 11!.$$
Esa es la razón por la que la búsqueda es manejable: una vez que el programa encuentra 10 números válidos dentro de esa capa de 12 cifras, necesariamente son los 10 menores en total, porque cualquier número con más de 12 cifras en base 12 es mayor que cualquier elemento de la capa mínima.
Fijemos una base \(b\). Mediante divisiones sucesivas se escribe
$$x=d_0+d_1b+d_2b^2+\cdots,\qquad 0\le d_i<b.$$
Cada resto \(d_i\) es una cifra de la representación en base \(b\). Para registrar qué cifras aparecen, se activa el bit \(d_i\) en una máscara. En forma matemática, definimos
$$S_b(x)=\bigvee_i 2^{d_i},$$
donde \(\vee\) representa el OR a nivel de bits. La máscara completa para la base \(b\) es
$$M_b=2^b-1.$$
Entonces el candidato es pandigital en base \(b\) exactamente cuando
$$S_b(x)=M_b.$$
El criterio es exacto porque el dígito \(j\) aparece al menos una vez si y solo si el bit \(j\) queda activado. Además permite cortar pronto: cuando la máscara ya vale \(M_b\), las cifras restantes no pueden cambiar la respuesta.
Todo candidato de la capa mínima ya es 12-pandigital por construcción, así que solo faltan las bases más pequeñas. Por tanto, la condición necesaria y suficiente es
$$\forall b\in\{2,3,\dots,11\},\ S_b(x)=2^b-1.$$
Las implementaciones comprueban esas bases de mayor a menor y se detienen en el primer fallo. Eso es matemáticamente correcto porque la condición es una conjunción: basta una sola base fallida para descartar el candidato.
Cada candidato mínimo tiene la forma
$$x=a_{11}12^{11}+a_{10}12^{10}+\cdots+a_1 12+a_0,$$
donde \((a_{11},a_{10},\dots,a_0)\) es una permutación de \(0,1,\dots,11\) y \(a_{11}\ne 0\).
Para longitud fija y base fija, el orden lexicográfico de las tuplas de cifras coincide con el orden numérico. La primera cifra distinta en una posición alta domina todas las posiciones inferiores. Por eso, recorrer las permutaciones en orden lexicográfico equivale a recorrer los enteros candidatos de menor a mayor.
Eso justifica dos reglas prácticas: omitir toda permutación cuyo primer dígito sea \(0\) y detenerse en cuanto se hayan reunido 10 aciertos.
La búsqueda optimizada del caso \(12\) no vuelve a empezar desde el principio para cada trabajador. En su lugar emplea la numeración factorial, que asocia un índice \(k\) con la \(k\)-ésima permutación en orden lexicográfico.
Como las primeras \(11!\) permutaciones lexicográficas empiezan por \(0\), el intervalo útil es
$$11!\le k<12!.$$
Esto hace muy sencilla la división en bloques. La implementación en C++ parte el intervalo en trozos de tamaño
$$9!,$$
cada trabajador decodifica la primera permutación de su bloque y luego avanza lexicográficamente dentro de ese mismo bloque. Como los bloques son disjuntos, el paralelismo solo cambia el tiempo de ejecución; no cambia la matemática del algoritmo.
Un pequeño punto de control muy útil es el menor número 5-super-pandigital, que es \(978\). Sus representaciones son
$$978=12403_5=33102_4=1100020_3=1111010010_2.$$
En base \(5\) aparecen \(0,1,2,3,4\). En base \(4\) aparecen \(0,1,2,3\). En base \(3\) aparecen \(0,1,2\). En base \(2\) aparecen ambos dígitos \(0\) y \(1\). Por tanto, \(978\) es pandigital en todas las bases de \(2\) a \(5\), así que es 5-super-pandigital.
Las implementaciones en C++, Python y Java siguen el mismo plan matemático. Recorren la capa mínima pandigital en base 12, convierten cada permutación en su valor numérico y luego prueban las bases \(11\) a \(2\) con el criterio de la máscara de cobertura.
La prueba genérica por base extrae restos repetidamente, activa el bit correspondiente, divide por la base y compara la máscara actual con la máscara completa. La implementación en C++ añade dos optimizaciones de ingeniería para el caso final de base 12. Para la base \(8\), la extracción de dígitos se reduce a
$$x\bmod 8=x\,\&\,7,\qquad \left\lfloor\frac{x}{8}\right\rfloor=x\gg 3,$$
de modo que el bucle usa operaciones de bits muy baratas. Además, los inicios de bloque obtenidos con el sistema factorial permiten que varios trabajadores inspeccionen bloques disjuntos en paralelo antes de mezclar y ordenar los aciertos.
La implementación en Java realiza la misma búsqueda matemática, pero recorre la capa mínima de forma secuencial mediante decodificación directa de índice a permutación. La implementación en Python delega la ejecución en la búsqueda compilada, por lo que hereda el mismo orden de candidatos y las mismas comprobaciones pandigitales.
La capa mínima contiene \(12!-11!\) candidatos. Para cada uno, como mucho hay que comprobar 10 bases adicionales. Una comprobación en una base requiere un número de extracciones de dígitos proporcional a la longitud de la representación en esa base, pero en este problema esas longitudes están acotadas por constantes pequeñas porque \(n=12\) es fijo.
En consecuencia, el tiempo en el peor caso queda dominado por el barrido de la capa de permutaciones y es efectivamente \(O(12!)\), con mejoras de constante importantes gracias al descarte temprano, las rutas rápidas para ciertas bases y el procesamiento paralelo por bloques. El consumo de memoria es \(O(1)\) por trabajador, más un pequeño buffer para los aciertos válidos.
如果一个正整数在 \(b\) 进制表示中把数字 \(0,1,\dots,b-1\) 每个都至少出现一次,就称它是 \(b\)-pandigital。如果它对所有满足 \(2 \le b \le n\) 的进制都成立,就称它是 \(n\)-super-pandigital。本题要求找出最小的 10 个 12-super-pandigital 数,并求它们的和。
真正的难点不在于单次判定,而在于如何把搜索空间压缩到一个可枚举的范围。任何 12-super-pandigital 数都必须先在 12 进制下是 pandigital,这一点会强迫最小解落在一个非常规则的集合里。
实现所依据的思路可以拆成五步:先把搜索限制到最短的 12 进制长度层,再用位掩码判断某个进制是否覆盖了全部数字,然后把“super”条件写成可提前失败的连锁判定,接着利用排列的字典序与数值大小一致这一事实来按从小到大的顺序搜索,最后借助阶乘数系统直接跳到排列块的起点。
若 \(x\) 是 12-super-pandigital,那么它的 12 进制表示必须包含数字 \(0,1,\dots,11\) 的每一个。因此它至少需要 12 个 12 进制数字。
最小可能的候选数,恰好就是那些在 12 进制下有 12 位 的数。因为一共只允许 12 位,而又必须覆盖全部 12 个数字,所以每个数字只能出现一次。于是它的 12 进制数字串必然是集合
$$\{0,1,2,\dots,11\}$$
的一个排列。首位又不能是 \(0\),否则这实际上只是一个 11 位数。因此,最小搜索层就是所有“12 个数字恰好各出现一次且首位非零”的 12 进制数。
这一层的候选个数是
$$12!-11!=11\cdot 11!.$$
这就是搜索能够落地的根本原因。一旦程序在这一层中已经找到了 10 个合法值,它们就必然是全局最小的 10 个,因为任何 12 进制位数超过 12 的数,都比这层里的所有数更大。
固定一个进制 \(b\)。通过不断除以 \(b\),可以把 \(x\) 写成
$$x=d_0+d_1b+d_2b^2+\cdots,\qquad 0\le d_i<b.$$
这里每个余数 \(d_i\) 都是 \(x\) 的一个 \(b\) 进制数字。要记录哪些数字出现过,可以维护一个位掩码:如果数字 \(d_i\) 出现,就把第 \(d_i\) 位设为 1。数学上可以写成
$$S_b(x)=\bigvee_i 2^{d_i},$$
其中 \(\vee\) 表示按位 OR。对于进制 \(b\),理想的“全覆盖掩码”是
$$M_b=2^b-1.$$
因此,判断条件可以直接写成
$$S_b(x)=M_b.$$
也就是说,当且仅当覆盖掩码等于完整掩码时,\(x\) 在 \(b\) 进制下才是 pandigital。
它之所以精确,是因为数字 \(j\) 至少出现一次,当且仅当掩码的第 \(j\) 位被置为 1。这个表示法还有一个重要优点:一旦当前掩码已经等于 \(M_b\),剩余更高位数字就不可能再改变结论,可以立即提前返回。
由于最小搜索层中的每个候选数本身就是 12 进制的全排列,所以它们已经自动满足“12 进制 pandigital”。剩下只需要检查更小的进制。于是,充要条件就是
$$\forall b\in\{2,3,\dots,11\},\ S_b(x)=2^b-1.$$
实现中会从较大的进制开始往下检查,只要某个进制失败,当前候选就立刻淘汰。这在数学上完全成立,因为上式是一个合取条件;只要有一个基数不满足,整体就不成立。
每个最小层候选都可以写成
$$x=a_{11}12^{11}+a_{10}12^{10}+\cdots+a_1 12+a_0,$$
其中 \((a_{11},a_{10},\dots,a_0)\) 是 \(0,1,\dots,11\) 的一个排列,且 \(a_{11}\ne 0\)。
对于同一进制、同一长度的表示,数字串的字典序和对应整数的大小顺序是一致的。原因是两个数字串一旦在某个高位第一次不同,高位上的较小数字必然压倒所有低位之和。因此,只要按字典序遍历排列,就等于按从小到大的顺序遍历候选整数。
这带来两个直接结论:首位为 \(0\) 的排列全部可以跳过;一旦收集到 10 个合法值,就可以停止。
在最终的 12 情况中,优化版搜索不会让每个工作线程都从头走一遍排列。它采用阶乘数系统,把一个整数索引 \(k\) 直接映射到字典序下的第 \(k\) 个排列。
由于最前面的 \(11!\) 个排列都以数字 \(0\) 开头,所以真正需要搜索的索引区间是
$$11!\le k<12!.$$
这样就能自然地把区间切成彼此独立的块。C++ 实现把这个区间划分为大小为
$$9!$$
的块,让每个工作线程先解出自己那一块的首个排列,再在块内按字典序继续前进。因为各块互不重叠,所以并行化只会改变运行时间,不会改变数学正确性。
实现里用到的一个小型校验值是最小的 5-super-pandigital 数 \(978\)。它在几个相关进制下的表示为
$$978=12403_5=33102_4=1100020_3=1111010010_2.$$
在 5 进制下,数字 \(0,1,2,3,4\) 全部出现;在 4 进制下,数字 \(0,1,2,3\) 全部出现;在 3 进制下,数字 \(0,1,2\) 全部出现;在 2 进制下,数字 \(0\) 与 \(1\) 都出现。因此 \(978\) 对所有 \(2\) 到 \(5\) 的进制都满足 pandigital 条件,所以它就是 5-super-pandigital。
C++、Python 和 Java 实现遵循的是同一套数学方案。它们先枚举最小的 12 进制 pandigital 层,把每个排列转换成对应的整数值,再对 \(11\) 到 \(2\) 的各个进制应用覆盖位掩码判定。
通用的单进制检查方式是:不断取余得到当前最低位数字,设置对应的掩码位,再整除掉这一位,并把当前掩码与完整掩码比较。C++ 版本在最终的 12 情况下还加入了两个工程上的优化。对 8 进制,有
$$x\bmod 8=x\,\&\,7,\qquad \left\lfloor\frac{x}{8}\right\rfloor=x\gg 3,$$
因此取数字可以退化成非常便宜的位运算。除此之外,排列空间还会按阶乘数系统分块,让多个工作线程并行扫描互不相交的区间,最后把命中的结果合并并排序。
Java 实现使用相同的数学逻辑,但通过“索引直接解码为排列”的方式顺序扫描最小层。Python 实现则把执行委托给编译后的搜索核心,因此它继承了完全相同的候选顺序和相同的 pandigital 检查过程。
最小搜索层共有 \(12!-11!\) 个候选。对每个候选,最多还要检查 10 个更小的进制。单个进制检查的耗时与该数在此进制下的位数成正比,而在本题里 \(n=12\) 是固定的,所以这些位数都只是较小常数。
因此,本题的最坏时间主要由排列层扫描主导,可以把它视为有效的 \(O(12!)\)。实际运行中,提前失败、某些进制的专门快速路径以及分块并行都会显著降低常数因子。空间方面,每个工作线程只需要 \(O(1)\) 级别的局部状态,再加上一个很小的成功结果缓冲区。
Положительное целое число будем называть \(b\)-pandigital, если его запись в системе счисления по основанию \(b\) содержит каждую цифру \(0,1,\dots,b-1\) хотя бы один раз. Число называется \(n\)-super-pandigital, если это верно для каждого основания \(b\), где \(2 \le b \le n\). Нужно найти 10 наименьших 12-super-pandigital чисел и сложить их.
Главная идея состоит в том, что минимальные решения не нужно искать среди всех натуральных чисел подряд. Любое 12-super-pandigital число обязано уже быть pandigital в основании 12, а это резко ограничивает пространство поиска и делает упорядоченный перебор возможным.
Используемый метод опирается на пять шагов: ограничение поиска минимальным возможным слоем в основании 12, проверка покрытия цифр битовой маской, немедленное отбрасывание кандидата при первом провале по основанию, совпадение лексикографического порядка перестановок с числовым порядком, а также прямой переход к блокам перестановок через факториальную систему счисления.
Если \(x\) является 12-super-pandigital, то его запись по основанию 12 должна содержать все цифры \(0,1,\dots,11\). Значит, такая запись имеет как минимум 12 разрядов.
Наименьшие возможные кандидаты — это ровно числа с 12 разрядами в основании 12. В этом случае каждая обязательная цифра встречается ровно один раз, а сама запись является перестановкой множества
$$\{0,1,2,\dots,11\}.$$
Старший разряд не может быть равен \(0\), иначе запись на самом деле имела бы только 11 разрядов. Следовательно, минимальный поисковый слой состоит из всех чисел в основании 12, чьи цифры образуют перестановку \(0,1,\dots,11\) при ненулевой первой цифре.
Число таких кандидатов равно
$$12!-11!=11\cdot 11!.$$
Именно это делает задачу выполнимой: как только в этом 12-разрядном слое найдено 10 подходящих чисел, они автоматически являются 10 наименьшими вообще, потому что любое число с более чем 12 разрядами в основании 12 заведомо больше любого элемента минимального слоя.
Зафиксируем основание \(b\). Последовательные деления дают представление
$$x=d_0+d_1b+d_2b^2+\cdots,\qquad 0\le d_i<b.$$
Каждый остаток \(d_i\) — это одна из цифр записи числа в основании \(b\). Чтобы запомнить, какие цифры встретились, будем устанавливать бит с номером \(d_i\). Математически это можно записать так:
$$S_b(x)=\bigvee_i 2^{d_i},$$
где \(\vee\) обозначает побитовое OR. Полная маска для основания \(b\) равна
$$M_b=2^b-1.$$
Тогда кандидат является pandigital в основании \(b\) ровно в том случае, когда
$$S_b(x)=M_b.$$
Критерий точен, потому что цифра \(j\) встречается хотя бы один раз тогда и только тогда, когда установлен бит \(j\). Кроме того, возможен ранний выход: как только маска стала равна \(M_b\), дальнейшие цифры уже не влияют на ответ.
Каждый кандидат из минимального слоя уже по построению является 12-pandigital. Значит, остаётся проверить только меньшие основания. Итак, необходимое и достаточное условие имеет вид
$$\forall b\in\{2,3,\dots,11\},\ S_b(x)=2^b-1.$$
Реализации проверяют основания от больших к меньшим и немедленно останавливаются при первом провале. Это полностью корректно, потому что условие представляет собой конъюнкцию: одного неудачного основания достаточно для отбрасывания кандидата.
Каждый кандидат из минимального слоя имеет вид
$$x=a_{11}12^{11}+a_{10}12^{10}+\cdots+a_1 12+a_0,$$
где \((a_{11},a_{10},\dots,a_0)\) — перестановка чисел \(0,1,\dots,11\), причём \(a_{11}\ne 0\).
При фиксированной длине и фиксированном основании лексикографический порядок кортежей цифр совпадает с числовым порядком самих чисел. Первая отличающаяся старшая цифра перевешивает все младшие разряды. Поэтому лексикографический проход по перестановкам одновременно является проходом по кандидатам от меньших к большим.
Отсюда следуют два практических правила: все перестановки с первой цифрой \(0\) можно пропустить, а как только найдено 10 попаданий, поиск можно завершить.
Оптимизированный поиск для случая \(12\) не заставляет каждый рабочий поток начинать с нуля. Вместо этого применяется факториальная нумерация, которая сопоставляет индексу \(k\) непосредственно \(k\)-ю перестановку в лексикографическом порядке.
Поскольку первые \(11!\) лексикографических перестановок начинаются с цифры \(0\), рабочий диапазон индексов имеет вид
$$11!\le k<12!.$$
Это позволяет естественно разбить поиск на независимые блоки. В реализации на C++ диапазон делится на куски размера
$$9!,$$
каждый рабочий поток декодирует первую перестановку своего блока и затем продвигается внутри блока в лексикографическом порядке. Блоки не пересекаются, поэтому распараллеливание меняет только время работы, а не корректность алгоритма.
Полезный маленький контрольный пример — наименьшее 5-super-pandigital число \(978\). Его представления таковы:
$$978=12403_5=33102_4=1100020_3=1111010010_2.$$
В основании \(5\) присутствуют все цифры \(0,1,2,3,4\). В основании \(4\) присутствуют \(0,1,2,3\). В основании \(3\) присутствуют \(0,1,2\). В основании \(2\) есть и \(0\), и \(1\). Следовательно, \(978\) является pandigital во всех основаниях от \(2\) до \(5\), а значит, это 5-super-pandigital число.
Реализации на C++, Python и Java следуют одному и тому же математическому плану. Они перебирают минимальный pandigital-слой в основании 12, преобразуют каждую перестановку в числовое значение и затем проверяют основания от \(11\) до \(2\) с помощью маски покрытия цифр.
Общий тест для одного основания многократно извлекает остаток, устанавливает соответствующий бит, делит число на основание и сравнивает текущую маску с полной маской. Реализация на C++ добавляет две инженерные оптимизации для финального случая \(12\). Для основания \(8\) извлечение цифр сводится к формулам
$$x\bmod 8=x\,\&\,7,\qquad \left\lfloor\frac{x}{8}\right\rfloor=x\gg 3,$$
то есть к дешёвым побитовым операциям. Кроме того, стартовые точки блоков вычисляются через факториальную систему счисления, благодаря чему несколько рабочих потоков просматривают непересекающиеся участки параллельно, а затем найденные числа объединяются и сортируются.
Реализация на Java использует ту же математику, но проходит минимальный слой последовательно через прямое декодирование индекса в перестановку. Реализация на Python передаёт выполнение скомпилированному поисковому ядру, поэтому наследует тот же порядок кандидатов и те же проверки pandigital-свойства.
Минимальный слой содержит \(12!-11!\) кандидатов. Для каждого из них требуется проверить не более 10 дополнительных оснований. Стоимость одной проверки пропорциональна числу цифр записи кандидата в данном основании, но в этой задаче \(n=12\) фиксировано, так что все такие длины ограничены малыми константами.
Поэтому в худшем случае время работы фактически определяется обходом слоя перестановок и для данной задачи ведёт себя как \(O(12!)\). На практике ранние отказы, быстрые пути для отдельных оснований и параллельная обработка блоков заметно уменьшают константу. Память равна \(O(1)\) на один рабочий поток плюс небольшой буфер для чисел, прошедших все проверки.
لنسمِّ العدد الصحيح الموجب \(b\)-pandigital إذا كان تمثيله في الأساس \(b\) يحتوي كل رقم من \(0,1,\dots,b-1\) مرة واحدة على الأقل. ويكون العدد \(n\)-super-pandigital إذا تحقق ذلك لكل أساس \(b\) حيث \(2 \le b \le n\). المطلوب هو إيجاد أصغر 10 أعداد 12-super-pandigital ثم حساب مجموعها.
الفكرة الحاسمة هي أن أصغر الحلول لا تأتي من فحص الأعداد الموجبة عشوائيًا. فكل عدد 12-super-pandigital لا بد أن يكون pandigital في الأساس 12 أولًا، وهذا يفرض بنية صارمة جدًا على فضاء البحث.
تعتمد الطريقة على خمس أفكار مترابطة: حصر البحث في أصغر طول ممكن في الأساس 12، واختبار تغطية الأرقام بقناع بتات، ورفض المرشح فور فشل أي أساس، والاستفادة من أن الترتيب المعجمي للترتيبات يطابق الترتيب العددي هنا، ثم استخدام النظام العاملي للقفز مباشرة إلى بدايات الكتل.
إذا كان \(x\) عددًا 12-super-pandigital، فتمثيله في الأساس 12 يجب أن يحتوي كل الأرقام \(0,1,\dots,11\). لذلك لا بد أن يملك 12 خانة على الأقل في الأساس 12.
أصغر المرشحين الممكنين هم بالضبط الأعداد التي لها 12 خانة في الأساس 12. عندئذ يظهر كل رقم مطلوب مرة واحدة فقط، وبالتالي تكون سلسلة الخانات ترتيبًا لعناصر المجموعة
$$\{0,1,2,\dots,11\}.$$
ولا يجوز أن تكون الخانة الأولى هي \(0\)، لأن ذلك يعني أن التمثيل الحقيقي أقصر من 12 خانة. إذن طبقة البحث الدنيا تتكون من جميع أعداد الأساس 12 التي خاناتها ترتيب للأرقام \(0,1,\dots,11\) مع شرط أن تكون الخانة الأولى غير صفرية.
عدد هذه المرشحات هو
$$12!-11!=11\cdot 11!.$$
وهذا هو السبب في أن البحث يصبح ممكنًا عمليًا. فما إن نجد 10 أعداد صحيحة داخل هذه الطبقة ذات 12 خانة، حتى تكون هي أصغر 10 حلول على الإطلاق، لأن أي عدد يملك أكثر من 12 خانة في الأساس 12 سيكون أكبر من أي عنصر في هذه الطبقة الدنيا.
ثبّت أساسًا \(b\). بالقسمة المتكررة نستطيع كتابة \(x\) على الصورة
$$x=d_0+d_1b+d_2b^2+\cdots,\qquad 0\le d_i<b.$$
كل باقٍ \(d_i\) يمثل خانة من خانات العدد في الأساس \(b\). ولتسجيل الأرقام التي ظهرت، نضع البت رقم \(d_i\) في القناع. رياضيًا نعرّف
$$S_b(x)=\bigvee_i 2^{d_i},$$
حيث ترمز \(\vee\) إلى OR على مستوى البتات. أما القناع الكامل في الأساس \(b\) فهو
$$M_b=2^b-1.$$
وعندئذ نحصل على معيار دقيق:
$$S_b(x)=M_b.$$
أي إن العدد يكون pandigital في الأساس \(b\) إذا وفقط إذا ساوى قناع التغطية القناع الكامل.
هذا صحيح تمامًا لأن الرقم \(j\) يظهر مرة واحدة على الأقل إذا وفقط إذا كان البت \(j\) مفعّلًا. كما أن هذه الصياغة تسمح بخروج مبكر: بمجرد أن يصبح القناع مساويًا لـ \(M_b\)، لن تغيّر الخانات الباقية النتيجة.
كل مرشح في الطبقة الدنيا هو أصلًا 12-pandigital بحكم طريقة بنائه، لذا لا يبقى إلا فحص الأسس الأصغر. وبالتالي يكون الشرط اللازم والكافي هو
$$\forall b\in\{2,3,\dots,11\},\ S_b(x)=2^b-1.$$
تقوم التطبيقات بفحص هذه الأسس من الأكبر إلى الأصغر وتتوقف فور أول فشل. وهذا سليم رياضيًا لأن الشرط عبارة عن اقتران؛ ففشل أساس واحد يكفي لرفض المرشح كله.
كل مرشح من الطبقة الدنيا يأخذ الشكل
$$x=a_{11}12^{11}+a_{10}12^{10}+\cdots+a_1 12+a_0,$$
حيث \((a_{11},a_{10},\dots,a_0)\) ترتيب للأرقام \(0,1,\dots,11\) مع \(a_{11}\ne 0\).
عندما يكون الطول ثابتًا والأساس ثابتًا، فإن الترتيب المعجمي لسلاسل الخانات يساوي الترتيب العددي للأعداد نفسها. فالخانة العليا الأولى التي تختلف هي التي تحسم المقارنة. لذلك فإن المرور على الترتيبات معجميًا يعطينا المرشحين من الأصغر إلى الأكبر مباشرة.
ومن هنا تنتج قاعدتان عمليتان: كل ترتيب يبدأ بـ \(0\) يمكن تجاوزه، ويمكن التوقف فور جمع 10 إصابات صحيحة.
في الحالة النهائية \(12\)، لا تجعل النسخة المحسّنة كل عامل يبدأ من الصفر. بدلًا من ذلك تستخدم الفهرسة العاملية التي تربط الفهرس الصحيح \(k\) مباشرة بالترتيب رقم \(k\) في الترتيب المعجمي.
وبما أن أول \(11!\) ترتيبًا معجميًا يبدأ بالرقم \(0\)، فإن المجال المفيد هو
$$11!\le k<12!.$$
وهذا يجعل تقسيم الفضاء إلى كتل مستقلة أمرًا طبيعيًا. تقسم نسخة C++ هذا المجال إلى كتل حجم كل منها
$$9!,$$
ثم يفك كل عامل أول ترتيب في كتلته ويتابع داخلها بالترتيب المعجمي. ولأن هذه الكتل منفصلة، فإن التوازي يغيّر زمن التنفيذ فقط ولا يغيّر صحة الخوارزمية.
هناك نقطة تحقق صغيرة مفيدة هي أن أصغر عدد 5-super-pandigital يساوي \(978\). وتمثيلاته هي
$$978=12403_5=33102_4=1100020_3=1111010010_2.$$
في الأساس \(5\) تظهر الأرقام \(0,1,2,3,4\) كلها. وفي الأساس \(4\) تظهر الأرقام \(0,1,2,3\) كلها. وفي الأساس \(3\) تظهر الأرقام \(0,1,2\) كلها. وفي الأساس \(2\) يظهر الرقمان \(0\) و\(1\). لذلك يحقق \(978\) شرط pandigital في كل أساس من \(2\) إلى \(5\)، ومن ثم فهو 5-super-pandigital.
تتبع تطبيقات C++ وPython وJava الخطة الرياضية نفسها. فهي تعدد الطبقة الدنيا من الأعداد pandigital في الأساس 12، وتحول كل ترتيب إلى قيمته العددية، ثم تفحص الأسس من \(11\) إلى \(2\) باستخدام معيار قناع التغطية.
الاختبار العام لأساس واحد يستخرج البواقي تباعًا، ويفعّل البت الموافق، ثم يقسم على الأساس، ويقارن القناع الحالي بالقناع الكامل. تضيف نسخة C++ تحسينين هندسيين مهمين في حالة 12 النهائية. ففي الأساس \(8\) تصبح عملية استخراج الخانات
$$x\bmod 8=x\,\&\,7,\qquad \left\lfloor\frac{x}{8}\right\rfloor=x\gg 3,$$
أي أنها تتحول إلى عمليات بتية سريعة جدًا. كذلك تُستخدم بدايات الكتل المحسوبة بالنظام العاملي لكي تفحص عدة خيوط كتلًا متباينة بالتوازي قبل دمج النتائج الصحيحة وترتيبها.
أما تنفيذ Java فيستخدم الفكرة الرياضية نفسها لكنه يمر على الطبقة الدنيا تسلسليًا من خلال فك مباشر من الفهرس إلى الترتيب. وتنفيذ Python يفوّض التنفيذ إلى البحث المترجم، لذلك يرث الترتيب نفسه للمرشحين والاختبارات نفسها لخاصية pandigital.
تحتوي الطبقة الدنيا على \(12!-11!\) مرشحًا. ولكل مرشح يجب فحص ما يصل إلى 10 أسس إضافية. ويستغرق فحص أساس واحد زمنًا يتناسب مع عدد خانات تمثيل المرشح في ذلك الأساس، لكن هذه الأطوال هنا محدودة بثوابت صغيرة لأن \(n=12\) ثابت.
لذلك فإن زمن التنفيذ في أسوأ حالة يهيمن عليه المرور على طبقة الترتيبات، ويمكن اعتباره عمليًا \(O(12!)\)، مع تحسن واضح في الثوابت بسبب الرفض المبكر، والمسارات السريعة لبعض الأسس، والمعالجة المتوازية على مستوى الكتل. أما الذاكرة فهي \(O(1)\) لكل عامل، إضافة إلى مخزن صغير للاحتفاظ بالنتائج التي اجتازت جميع الاختبارات.