( Durchgestrichene 44 sind immer noch 44.) Danke an Fireflame241 für das Speichern eines Bytes!
P=input();i=P/3
while i*10%P-1:i-=1
print i
Probieren Sie es online!
Es gibt genau eine Zahl zwischen 0und P-1die ist eine Umkehrung von 10. Wenn diese Inverse ujedoch größer als ist P/2, (u-P)ist sie auch invers und hat einen kleineren absoluten Wert als u. Es stellt sich also heraus, dass wir wirklich nach der eindeutigen Zahl xzwischen -P/2und suchen, die P/2umgekehrt ist 10.
Der obige Code tut genau das, beginnend bei (dem Boden von) P/2und schrittweise nach unten, bis eine Umkehrung erreicht ist. Dies muss für eine Zahl geschehen, die größer als ist -P/2, solange Peine Primzahl größer als ist 10. Genauer gesagt, es wird genau dann beendet, wenn PCoprime an ist 10.
Edit: Es stellt sich tatsächlich heraus, dass xes garantiert zwischen -P/3und liegt P/3, also beginnt die aktuelle Version bei P/3und geht von dort aus weiter. Eine Erklärung hierzu finden Sie im Abschnitt Verbesserte Bindung .
Mathematische Erklärung
Mir war nicht sofort klar, warum der Teilbarkeitstest funktioniert hat. Hier ist eine Erklärung für den Fall, dass sich jemand anderes wundert.
Sei Peine Primzahl, größer als 10, deren letzte Ziffer ist b. Somit
P = 10a + b
wo a > 0und 0 <= b < 10. In der Tat bist entweder 1, 3, 7, oder 9, weil eine Primzahl größer als 10Muss Ende in einen dieser Stellen.
Nun nimm an bx + a = 0 (mod P). Dann
a = -bx (mod P)
10a + b = 10(-bx) + b (mod P)
0 = 10(-bx) + b (mod P)
0 = b(1 - 10x) (mod P)
Schon seit P es sich um eine Primzahl handelt, sind die ganzen Zahlen mod Peine integrale Domäne . Also entweder b = 0 (mod P)oder 1 - 10x = 0 (mod P).
Wir wissen 0 <= b < 10 < P, also wenn b = 0 (mod P)dann b = 0. Aber wir sagten , bist entweder 1, 3, 7, oder9 , so dass dies unmöglich ist. Deshalb 1 - 10x = 0 (mod P)so 10x = 1 (mod P). Mit anderen Worten, xist das Gegenteil von 10Modulo P.
Angenommen, es Nhandelt sich um eine nichtnegative Ganzzahl, deren letzte Ziffer lautet d. N = 10c + d. Wir haben also eine Kette von äquivalenten Anweisungen:
10c + d = 0 (mod P)
<==> 10xc + dx = 0 (mod P)
<==> c + dx = 0 (mod P)
QED.
Nützlichkeit?
Ich habe mich auch gefragt, ob der Teilbarkeitstest (gegeben N = 10c + d, ersetzt)N durch dx + c) in der Praxis tatsächlich produktiv sein würde. Oder zumindest, ersetzt es zuverlässig Ndurch eine Zahl, die kleiner als N(in absoluten Zahlen ) ist?
Angenommen N = 10c + d, wo c >= 0und 0 <= d < 10. Deshalb 10c = N - d <= N. Durch das Dreieck Ungleichung
|c + dx| <= |c| + |dx| = c + d|x| <= N/10 + d|x|
< N/10 + 10|x| <= N/10 + 10P/2 = N/10 + 5P
Also wenn 5P <= 9N/10 , dann |c + dx| < N.
Insbesondere wenn N >= 6P, dann |c + dx| < N. Somit gegeben Pwir durch die Berechnung beginnen 2P, 3P..., 6Pzusammen mit x. Dann führen Nwir den Teilbarkeitstest wiederholt durch, bis wir eine Zahl kleiner oder gleich erreichen 6P, und prüfen, ob das Ergebnis eine der Zahlen 0ist.P , 2P, ..., 6P.
(Wenn wir eine negative Zahl erreichen, ersetzen wir sie natürlich durch ihren absoluten Wert. Das ist in Ordnung, da qes Pnur dann teilbar ist, wenn dies der Fall (-q)ist.)
Verbesserte Bindung
Mir ist aufgefallen, dass das |x|/Pnie nah zu sein schien 1/2. Tatsächlich schien es immer weniger zu sein als 1/3... oder bei näherer Betrachtung war es immer sehr nah an entweder 1/10oder 3/10. Der größte, den es je gab, schien zu sein 4/13(was passiert, wenn P=13und x=4). Warum sollte das so sein?
Lassen Sie ueine ganze Zahl sein , und nehmen wir an, dass 10u = kP + 1für eine ganze Zahl k, so uist eine Umkehrung von 10Modulo P. Dann wissen wir auch, dass dies krelativ primär ist 10, da k(-P)es gleichbedeutend mit 1Modulo ist 10.
Jetzt wissen wir, dass sich die Inversen von 10Modulo Palle um ein Vielfaches von Punterscheiden. Wir können also die ganze Zahl nehmen uund ein Vielfaches von Pnach Belieben addieren oder subtrahieren , und das Ergebnis ist immer noch eine Inverse von 10Modulo P. Nehmen wir an, wir subtrahieren Pvon u: wir bekommen
10(u - P) = 10u - 10P = kP + 1 - 10P
10(u - P) = (k - 10)P + 1
Mit anderen Worten, das Verringern (bzw. Erhöhen) uum Pentspricht dem Verringern (Erhöhen) kum 10. Wir möchten ein Vielfaches von Pvon addieren / subtrahieren, ubis der absolute Wert der linken Seite minimiert ist. Die linke Seite wird jedoch genau dann minimiert, wenn die rechte Seite minimiert wird, und daher möchten wir addieren / subtrahieren10 aus , kbis die rechte Seite wird in Absolutwert minimiert.
Aber wir wissen , dass dies geschehen wird , wenn kzwischen -5und 5, und daher (da krelativ prim zu 10) bedeutet dies kentweder -3, -1, 1, oder3 . (Dies ist der Inhalt von @ Neils Kommentar unter dem OP. Danke, Neil! )
Wenn somit |u|minimiert wird (dh u=x), wir haben x/P = u/P = k/10 + 1/(10P), wo kentweder -3, -1, 1, oder 3. Deshalb|x|/P <= 3/10 + 1/(10P) . Äquivalent |x| <= (3P + 1)/10.
Außerdem ist diese Ungleichung streng P=11, weil P=11wir x=-1und haben k=-1. Das kleinste, Pfür das Gleichheit gilt, ist P=13(wo x=4und k=3).
Daher ist der größte, der |x|/Pjemals erhalten wird 3/10 + 1/(10*13), weil P=13es die erste Primzahl ist, für die wir haben k=3, und unter denen mit k=3, ist der 1/(10P)Begriff am größten, wenn er Pam kleinsten ist (dh bei P=13). Deshalb Phaben wir für alle auch|x|/P <= 3/10 + 1/130 = 4/13 < 1/3 . Dies erklärt, warum wir im obigen Code bei initialisieren können, i = P/3anstatt bei beginnen zu müssen P/2.
Weiter die Grenzen im Nützlichen obigen Abschnitt jetzt verbessert werden.
Lemma : Lass N = 10c + dwo c > 0und0 <= d <= 9 . Dann c + d|x| < N/10 + 9(3P + 1)/10. (Beachten Sie die strikte Ungleichung.)
Beweis von Lemma: durch Fälle. Fall I: d = 0AlsoN = 10c . Dann c + d|x| = c = N/10 < N/10 + 9(3P + 1)/10.
Fall II: 0 < d <= 9. Dann 10c = N - d < Nalso c < N/10. Deshalb c + d|x| < N/10 + d|x| <= N/10 + 9|x| <= N/10 + 9(3P + 1)/10. QED.
Also, wenn N > 3P(und N = 10c + dwie zuvor), dann
3P + 1 <= N
9(3P + 1)/10 <= 9N/10
N/10 + 9(3P + 1)/10 <= N
c + d|x| < N/10 + 9(3P + 1)/10 <= N
Also, wenn N > 3Pdann c + d|x| < N.
Deshalb müssen wir nur finden P, 2Pund 3P, zusammen mit x. Gegeben N > 0, während N > 3Pwir ersetzen Ndurch |c + dx|, die abnimmt N. Irgendwann werden wir bekommen N <= 3P; stoppen und prüfen , ob an diesem Punkt uns Nauf eine der Zahlen gleich 0, P, 2P, oder 3P.
Wir können es nicht besser machen als 3Pim Allgemeinen. Nehmen wir zum Beispiel an, P = 13und N = 39so x = 4. Dann Ndurch unveränderte dx + c = 9(4) + 3Blätter ersetzen N.
xabsoluten Wert, der10*x-1durch die Eingabe teilbar ist.