Intro
Betrachten Sie den Prozess, bei dem eine positive ganze Zahl n in einer Basis b genommen und jede Ziffer durch ihre Darstellung in der Basis der Ziffer rechts ersetzt wird.
- Wenn die Ziffer rechts eine 0 ist, verwenden Sie die Basis b .
- Wenn die Ziffer rechts eine 1 ist, verwenden Sie unär mit Nullen als Strichmarkierungen.
- Wenn sich rechts keine Ziffer befindet (dh Sie befinden sich an der richtigen Stelle), wechseln Sie zur höchstwertigen Ziffer.
Als Beispiel sei n = 160 und b = 10. Das Ausführen des Prozesses sieht folgendermaßen aus:
The first digit is 1, the digit to the right is 6, 1 in base 6 is 1.
The next digit is 6, the digit to the right is 0, 0 is not a base so use b, 6 in base b is 6.
The last digit is 0, the digit to the right (looping around) is 1, 0 in base 1 is the empty string (but that's ok).
Concatenating '1', '6', and '' together gives 16, which is read in the original base b = 10.
Das genau gleiche Verfahren, aber das Bewegen nach links statt nach rechts kann auch durchgeführt werden:
The first digit is 1, the digit to the left (looping around) is 0, 0 is not a base so use b, 1 in base b is 1.
The next digit is 6, the digit to the left is 1, 6 in base 1 is 000000.
The last digit is 0, the digit to the left is 6, 0 in base 6 is 0.
Concatenating '1', '000000', and '0' together gives 10000000, which is read in the original base b = 10.
Daher haben wir zwei Zahlen für 160 (für b = 10) erstellt: 16 und 10000000.
Wir werden n als eine listige Zahl definieren, wenn sie mindestens eine der beiden in diesem Prozess erzeugten Zahlen gleichmäßig in zwei oder mehr Teile aufteilt
Im Beispiel ist n schlau, weil 160 10000000 genau 62500 mal teilt.
203 ist NICHT schlau, da die resultierenden Zahlen 2011 und 203 selbst sind, die 203 nicht gleichmäßig in zwei oder mehr Male passen können.
Herausforderung
(Für den Rest des Problems betrachten wir nur b = 10.)
Die Herausforderung besteht darin, ein Programm zu schreiben, das die höchste schlauen Zahl findet, die auch eine Primzahl ist.
Die ersten 7 schlauen Primzahlen (und alles, was ich bisher gefunden habe) sind:
2
5
3449
6287
7589
9397
93557 <-- highest so far (I've searched to 100,000,000+)
Ich bin mir offiziell nicht sicher, ob es noch mehr gibt, aber ich gehe davon aus, dass dies der Fall ist. Wenn Sie beweisen können, dass es endlich viele gibt (oder nicht), gebe ich Ihnen +200 Kopfgeld-Repräsentanten.
Der Gewinner wird die Person sein, die die höchste schlauen Primzahl liefern kann, vorausgesetzt, es ist offensichtlich, dass sie bei der Suche aktiv war und nicht absichtlich Ruhm von anderen nimmt.
Regeln
- Sie können alle gewünschten Suchwerkzeuge verwenden.
- Sie können probabilistische Primetester verwenden.
- Sie können den Code anderer Personen mit Namensnennung wiederverwenden . Dies ist eine gemeinsame Anstrengung. Cutthroat-Taktiken werden nicht toleriert.
- Ihr Programm muss aktiv nach der Primzahl suchen. Sie können Ihre Suche am höchsten bekannten schlauen Prime beginnen.
- Ihr Programm sollte in der Lage sein, alle bekannten schlauen Primzahlen innerhalb von 4 Stunden nach Amazon EC2 t2.medium-Instanzen zu berechnen (entweder vier auf einmal oder eine für vier Stunden oder etwas dazwischen). Ich werde es nicht wirklich an ihnen testen und du musst es bestimmt nicht. Dies ist nur ein Maßstab.
Hier ist mein Python 3-Code, den ich zum Generieren der obigen Tabelle verwendet habe: (läuft in ein oder zwei Sekunden)
import pyprimes
def toBase(base, digit):
a = [
['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'],
['', '0', '00', '000', '0000', '00000', '000000', '0000000', '00000000', '000000000' ],
['0', '1', '10', '11', '100', '101', '110', '111', '1000', '1001'],
['0', '1', '2', '10', '11', '12', '20', '21', '22', '100'],
['0', '1', '2', '3', '10', '11', '12', '13', '20', '21'],
['0', '1', '2', '3', '4', '10', '11', '12', '13', '14'],
['0', '1', '2', '3', '4', '5', '10', '11', '12', '13'],
['0', '1', '2', '3', '4', '5', '6', '10', '11', '12'],
['0', '1', '2', '3', '4', '5', '6', '7', '10', '11'],
['0', '1', '2', '3', '4', '5', '6', '7', '8', '10']
]
return a[base][digit]
def getCrafty(start=1, stop=100000):
for p in pyprimes.primes_above(start):
s = str(p)
left = right = ''
for i in range(len(s)):
digit = int(s[i])
left += toBase(int(s[i - 1]), digit)
right += toBase(int(s[0 if i + 1 == len(s) else i + 1]), digit)
left = int(left)
right = int(right)
if (left % p == 0 and left // p >= 2) or (right % p == 0 and right // p >= 2):
print(p, left, right)
if p >= stop:
break
print('DONE')
getCrafty()
quelle
Antworten:
Mathematica findet 93.557 in 0,3 s (keine weiteren schlauen Primzahlen unter 2 * 10 10 )
Dies ist nur eine naive erschöpfende Suche durch alle Primzahlen. Zunächst werden alle 55 Sekunden etwa 1.000.000 Primzahlen überprüft (was mit zunehmender Primzahl zwangsläufig langsamer wird).
Ich verwende eine Reihe von Hilfsfunktionen:
Und dann führt diese Schleife die eigentliche Suche durch:
Ich werde den Beitrag weiter aktualisieren, wenn ich Primzahlen finde oder mir Optimierungen vorstellen kann.
Derzeit werden alle Primzahlen bis zu 100.000.000 in etwa 5,5 Minuten überprüft.
Bearbeiten: Ich habe mich entschlossen, dem Beispiel des OP zu folgen und bin zur Basiskonvertierung zu einer Nachschlagetabelle gewechselt. Das ergab eine Beschleunigung von ungefähr 30%.
Crafty Numbers im Allgemeinen
Ich stoppe jetzt meine Suche nach schlauen Primzahlen, da ich mehrere Tage brauchen würde, um zu erfahren, wo die Perl-Antwort bereits angekommen ist. Stattdessen fing ich an, nach allen schlauen Zahlen zu suchen. Vielleicht hilft ihre Verteilung, einen Beweis dafür zu finden, dass die Anzahl der schlauen Primzahlen endlich oder unendlich ist.
Ich definiere rechtsbastelnde Zahlen, die die zugehörige Zahl teilen, die durch Interpretieren der Ziffer rechts als neue Basis erhalten wird, und linksbastelnde Zahlen entsprechend. Es wird wahrscheinlich helfen, diese einzeln für einen Beweis anzugehen.
Hier sind alle links schlauen Zahlen bis zu 2.210.000.000:
Und hier sind alle richtigen Zahlen in diesem Bereich:
Beachten Sie, dass es unendlich viele links und rechts geschickte Zahlen gibt, da es verschiedene Möglichkeiten gibt, sie aus vorhandenen zu generieren:
0
s an jede linksbastelnde Zahl anhängen, deren niedrigstwertige Ziffer größer als ihre höchstwertige Ziffer ist, um eine andere linksbastelnde Zahl zu erhalten.0
s an jede rechtschaffene Zahl anhängen, deren niedrigstwertige Ziffer kleiner als ihre höchstwertige Ziffer ist. Dies (und die vorherige Aussage) ist darauf zurückzuführen, dass die0
sowohl an die schlauen als auch an die zugehörige Nummer angehängt wird, wodurch beide effektiv mit 10 multipliziert werden.2
s oder5
s ist schlau.777
s ist schlau.28
durch0
s verbundenen, wie28028028
immer schlau ist.Andere Dinge zu beachten:
125
. Es könnte sich lohnen, diese zu untersuchen, um eine andere Produktionsregel zu finden.Ich nehme an, diese Liste wäre interessanter, wenn ich diejenigen weglassen würde, deren Existenz durch eine kleinere schlauen Zahl impliziert wird, zumal dies nach den bisher entdeckten Konstruktionsregeln niemals Primzahlen sind. Hier sind also alle schlauen Primzahlen, die nicht mit einer der oben genannten Regeln konstruiert werden können:
Beachten Sie auch, dass es einige doppelt listige Zahlen gibt (diejenigen, die in beiden Listen erscheinen und daher beide verwandten Zahlen teilen):
Es gibt auch unendlich viele davon.
Aber wie Sie sehen können, mit AusnahmeDas Gegenbeispiel gefunden16
,28
,68
bestehen alle diese nur aus einer einzigen (Wiederholung) Ziffer. Es wäre auch interessant zu beweisen, ob größere Zahlen ohne diese Eigenschaft doppelt schlau sein können, aber dies könnte als Folge eines Beweises für einfach geschickte Zahlen herausfallen.1944919449
.quelle
100540625, 100540625
in Ihrer Liste der richtigen Handwerker haben?Perl (1e5 in 0,03 s, 1e8 in 21 s). Max 93557 bis 1e11.
Sehr ähnlich dem Original. Änderungen umfassen:
Führt die ersten 1e8-Primzahlen in 21 Sekunden auf meiner schnellen Maschine aus, 3,5 Minuten für 1e9, 34 Minuten für 1e10. Ich bin ein wenig überrascht, dass es für kleine Eingaben überhaupt schneller ist als der Python-Code. Wir könnten parallelisieren (Pari / GPs neues
parforprime
wäre schön dafür). Da es sich um eine Suche handelt, können wir vermutlich von Hand parallelisieren (forprimes
kann zwei Argumente annehmen ).forprimes
ist im Grunde wie bei Pari / GPsforprime
- es macht intern segmentierte Siebe und ruft den Block mit jedem Ergebnis auf. Es ist praktisch, aber für dieses Problem denke ich nicht, dass es ein Leistungsbereich ist.quelle
C ++ 11 mit Threads und GMP
Timing (auf einem MacBook Air):
Bedarf:
g++ crafty.cpp -o crafty --std=c++11 -ffast-math -lprimesieve -O3 -lgmpxx -lgmp -Wall -Wextra
Ausgabe:
quelle
C, mit GMP, Multithread (1e8 in 17s für 1 Thread)
Ähnlich im Konzept wie die anderen, wahrscheinlich mit ein paar Optimierungen hier und da.
Kompilieren:
gcc -I/usr/local/include -Ofast crafty.c -pthread -L/usr/local/lib -lgmp && ./a.out
Bitte spenden Sie Ihre CPU-Leistung. Ich habe keinen schnellen Computer.
1e8 in 17 Sekunden mit 1 Thread auf meinem MacBook Air.
quelle
Python findet 93557 in 0,28s
Sehr ähnlich zu OPs Code, da er auch verwendet
pyprimes
. Ich habe das selbst geschrieben, obwohl xDEs wird auch die Zeit seit dem Start ausgedruckt, zu der eine Nummer gefunden wurde.
Ausgabe:
Format ist
number left right time
. Zum Vergleich: OPs Code findet 93557 in etwa0.37
.quelle