Wenn eine Primzahl P
größer als ist 10
, muss Ihr Programm oder Ihre Funktion die Teilungsregel ermitteln x
, die als Ganzzahl mit dem kleinsten absoluten Wert definiert ist und ein Vielfaches der ursprünglichen Primzahl ergibt, wenn sie mit der letzten Ziffer der Primzahl multipliziert und zum Rest des Originals addiert wird prime.
Beispiel
Bei einer Eingabe 31
ist die letzte Ziffer 1
und der Rest der Zahl 3
. Daher muss Ihr Programm die Ganzzahl x
mit dem minimalen absoluten Wert finden, der 1*x + 3
ein Vielfaches von ist 31
. In diesem Fall x=-3
funktioniert, so dass das Programm oder die Funktion zurückkehren würde -3
.
Bei einer Eingabe 1000003
ist die letzte Ziffer 3
und der Rest der Zahl 100000
. So würde dein Programm x=300001
denn finden, 3*300001+100000 = 1000003
was ein Vielfaches von ist 1000003
.
Mathematischer Hintergrund
Der Wert von x
kann als Teilbarkeitstest verwendet werden. Wenn eine Zahl N
durch teilbar ist P
, ergibt das Addieren x
der letzten Ziffer von N
zum Rest von N
ein Vielfaches von P
nur dann, wenn sie überhaupt N
durch teilbar ist P
.
Denn P=11
wir erhalten x=-1
, was der bekannten Teilbarkeitsregel für äquivalent ist 11
: Eine Zahl ist teilbar durch 11
wechselnde Differenz ihrer Ziffern ist teilbar durch 11
.
Regeln
- Die Ausgabe kann in jeder Form erfolgen, die sowohl das Vorzeichen als auch den Wert der Ausgabe eindeutig codiert.
- Die Eingangsprimzahl liegt zwischen 10 und 2 ^ 30.
- Sie müssen nicht damit umgehen, wenn der Eingang keine Primzahl ist oder nicht im Bereich liegt.
- Sie müssen nicht behandeln, wenn beide
x
und-x
gültige Ausgaben sind (sollte nicht passieren). - Brute Force ist erlaubt, aber kreativere Lösungen werden geschätzt.
- Das ist Code-Golf , also gewinnt der kürzeste Code in jeder Sprache ! Lassen Sie sich von Antworten in Golfsprachen nicht davon abhalten, in anderen Sprachen zu posten.
Testfälle
Input Output
11 -1
13 4
17 -5
19 2
23 7
29 3
31 -3
37 -11
41 -4
43 13
47 -14
53 16
59 6
61 -6
67 -20
71 -7
73 22
79 8
83 25
89 9
97 -29
101 -10
103 31
107 -32
109 11
113 34
127 -38
131 -13
1000003 300001
2000003 600001
2999999 300000
9999991 -999999
quelle
x
absoluten Wert, der10*x-1
durch die Eingabe teilbar ist.(3 / (n % 5 * 2 - 5) * n + 1) / 10
und(n % 5 * 2 - 5^2) * n / 10 + 1
in der Lage, einen minimalen absoluten Wert für so etwas zu finden? Meine erste Intuition wäre gewesen, das kleinste gemeinsame Vielfache unter Verwendung des größten gemeinsamen Divisors zu berechnen, der mit dem Algorithmus von Euclid berechnet wurde.x
, hinzufügen und trotzdem eine durch teilbare Zahl erhaltenn
. Wenn wir dann die neue Zahl mit 10 multiplizieren und die ursprüngliche Zahl subtrahieren, bleibt sie weiterhin teilbar durchn
. xnors Kommentar folgt dann aus einer Algebra. Der nächste Schritt ist die Formel neu zu ordnen , so dass es gibtx
in Bezug aufn
: x =(k*n+1)/10
. Wir wollen , dass die kleinste absolutex
so damit wir den kleinsten absoluten wollenk
, und dies muss je nachdem , was man von-3
,-1
,1
oder3
(je nachn
‚s letzte Stelle), die die Teilung genau macht.Antworten:
JavaScript (ES6),
322523 Byte3/(n%5*2-5)
würde geschrieben werden,9/n(mod -10)
wenn ich Zugang zu einer ausgeglichenen Modulo-Division hätte. Bearbeiten: 2 Bytes dank @EgorSkriptunoff gespeichertquelle
n=>((n%10*2%14-3)*n+1)/10
durchn=>(3/(n%5*2-5)*n+1)/10
Python 2 , 27 Bytes
Probieren Sie es online!
Die Operationen werden von links nach rechts durchgeführt:
(((n%5)*2)-5)^2
.Ich habe meinen arithmetischen Brute Forcer verwendet, um den Ausdruck
n%5*2-5^2
zu finden, der ausgeführt werden{1:-1,3:3,2:-3,4:1}[k]
soll. Dabei habe ich die negative Inverse eines Residuen-Mods 5 in den Bereich aufgenommen[-2..2]
.quelle
3/(n%5*2-5)
ist die gleiche Länge wie(n%5*2-5^2)
.)n%5*2-6^3
. Ich habe nur bis zur Länge des Ausdrucks ohne Parens nachgeschaut, wobei3/(n%5*2-5)
zwei Zeichen länger sind, aber aufgrund der Rangfolge äußere Parens eingespart werden. Das Suchen nach Ausdrücken dieser Länge sollte eine Weile dauern. Dieser Anwendungsfall schlägt eine Option vor, nur Ausdrücke zu finden, die in einem bestimmten Kontext über ihre äußerste Operation mit einer ausreichend hohen Priorität verwendet werden können.Gelee ,
108 BytesProbieren Sie es online!
Erklärungen
quelle
Brachylog , 14 Bytes
Probieren Sie es online!
quelle
Python 2 ,
695453 BytesEdit: -15 Bytes dank @ Mr.Xcoder
Bearbeiten: -1 Byte unter Verwendung von Rekursion
Probieren Sie es online!
quelle
Python 2 ,
31 2927 BytesProbieren Sie es online!
quelle
Japt ,
169 BytesDank einer Beobachtung von @xnor viel zu viele Bytes gespeichert
Testen Sie es online! Bei größeren Eingängen kann dies einige Sekunden dauern.
Erläuterung
quelle
Java 8,
2321 BytesPort der Antwort von @Neil auf JavaScrip (ES6) , aber -2 Byte dank @Nevay aufgrund impliziter Ganzzahlen.
Probieren Sie es hier aus.
quelle
n->3/(n%5*2-5)*++n/10
Pyke , 12 Bytes
Probieren Sie es hier aus!
quelle
Pyth , 14 Bytes
Probieren Sie es hier aus.
quelle
Python 2 ,
4443 Bytes( Durchgestrichene 44 sind immer noch 44.) Danke an Fireflame241 für das Speichern eines Bytes!
Probieren Sie es online!
Es gibt genau eine Zahl zwischen
0
undP-1
die ist eine Umkehrung von10
. Wenn diese Inverseu
jedoch größer als istP/2
,(u-P)
ist sie auch invers und hat einen kleineren absoluten Wert alsu
. Es stellt sich also heraus, dass wir wirklich nach der eindeutigen Zahlx
zwischen-P/2
und suchen, dieP/2
umgekehrt ist10
.Der obige Code tut genau das, beginnend bei (dem Boden von)
P/2
und schrittweise nach unten, bis eine Umkehrung erreicht ist. Dies muss für eine Zahl geschehen, die größer als ist-P/2
, solangeP
eine Primzahl größer als ist10
. Genauer gesagt, es wird genau dann beendet, wennP
Coprime an ist10
.Edit: Es stellt sich tatsächlich heraus, dass
x
es garantiert zwischen-P/3
und liegtP/3
, also beginnt die aktuelle Version beiP/3
und 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
P
eine Primzahl, größer als10
, deren letzte Ziffer istb
. SomitP = 10a + b
wo
a > 0
und0 <= b < 10
. In der Tatb
ist entweder1
,3
,7
, oder9
, weil eine Primzahl größer als10
Muss Ende in einen dieser Stellen.Nun nimm an
bx + a = 0 (mod P)
. Danna = -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 Zahlenmod P
eine integrale Domäne . Also entwederb = 0 (mod P)
oder1 - 10x = 0 (mod P)
.Wir wissen
0 <= b < 10 < P
, also wennb = 0 (mod P)
dannb = 0
. Aber wir sagten ,b
ist entweder1
,3
,7
, oder9
, so dass dies unmöglich ist. Deshalb1 - 10x = 0 (mod P)
so10x = 1 (mod P)
. Mit anderen Worten,x
ist das Gegenteil von10
ModuloP
.Angenommen, es
N
handelt sich um eine nichtnegative Ganzzahl, deren letzte Ziffer lautetd
.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
durchdx + c
) in der Praxis tatsächlich produktiv sein würde. Oder zumindest, ersetzt es zuverlässigN
durch eine Zahl, die kleiner alsN
(in absoluten Zahlen ) ist?Angenommen
N = 10c + d
, woc >= 0
und0 <= d < 10
. Deshalb10c = 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 gegebenP
wir durch die Berechnung beginnen2P
,3P
...,6P
zusammen mitx
. Dann führenN
wir den Teilbarkeitstest wiederholt durch, bis wir eine Zahl kleiner oder gleich erreichen6P
, und prüfen, ob das Ergebnis eine der Zahlen0
ist.P
,2P
, ...,6P
.(Wenn wir eine negative Zahl erreichen, ersetzen wir sie natürlich durch ihren absoluten Wert. Das ist in Ordnung, da
q
esP
nur dann teilbar ist, wenn dies der Fall(-q)
ist.)Verbesserte Bindung
Mir ist aufgefallen, dass das
|x|/P
nie nah zu sein schien1/2
. Tatsächlich schien es immer weniger zu sein als1/3
... oder bei näherer Betrachtung war es immer sehr nah an entweder1/10
oder3/10
. Der größte, den es je gab, schien zu sein4/13
(was passiert, wennP=13
undx=4
). Warum sollte das so sein?Lassen Sie
u
eine ganze Zahl sein , und nehmen wir an, dass10u = kP + 1
für eine ganze Zahlk
, sou
ist eine Umkehrung von10
ModuloP
. Dann wissen wir auch, dass diesk
relativ primär ist10
, dak(-P)
es gleichbedeutend mit1
Modulo ist10
.Jetzt wissen wir, dass sich die Inversen von
10
ModuloP
alle um ein Vielfaches vonP
unterscheiden. Wir können also die ganze Zahl nehmenu
und ein Vielfaches vonP
nach Belieben addieren oder subtrahieren , und das Ergebnis ist immer noch eine Inverse von10
ModuloP
. Nehmen wir an, wir subtrahierenP
vonu
: wir bekommen10(u - P) = 10u - 10P = kP + 1 - 10P
10(u - P) = (k - 10)P + 1
Mit anderen Worten, das Verringern (bzw. Erhöhen)
u
umP
entspricht dem Verringern (Erhöhen)k
um10
. Wir möchten ein Vielfaches vonP
von addieren / subtrahieren,u
bis 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 ,k
bis die rechte Seite wird in Absolutwert minimiert.Aber wir wissen , dass dies geschehen wird , wenn
k
zwischen-5
und5
, und daher (dak
relativ prim zu10
) bedeutet diesk
entweder-3
,-1
,1
, oder3
. (Dies ist der Inhalt von @ Neils Kommentar unter dem OP. Danke, Neil! )Wenn somit
|u|
minimiert wird (dhu=x
), wir habenx/P = u/P = k/10 + 1/(10P)
, wok
entweder-3
,-1
,1
, oder3
. Deshalb|x|/P <= 3/10 + 1/(10P)
. Äquivalent|x| <= (3P + 1)/10
.Außerdem ist diese Ungleichung streng
P=11
, weilP=11
wirx=-1
und habenk=-1
. Das kleinste,P
für das Gleichheit gilt, istP=13
(wox=4
undk=3
).Daher ist der größte, der
|x|/P
jemals erhalten wird3/10 + 1/(10*13)
, weilP=13
es die erste Primzahl ist, für die wir habenk=3
, und unter denen mitk=3
, ist der1/(10P)
Begriff am größten, wenn erP
am kleinsten ist (dh beiP=13
). DeshalbP
haben 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/3
anstatt bei beginnen zu müssenP/2
.Weiter die Grenzen im Nützlichen obigen Abschnitt jetzt verbessert werden.
Lemma : Lass
N = 10c + d
woc > 0
und0 <= d <= 9
. Dannc + d|x| < N/10 + 9(3P + 1)/10
. (Beachten Sie die strikte Ungleichung.)Beweis von Lemma: durch Fälle. Fall I:
d = 0
AlsoN = 10c
. Dannc + d|x| = c = N/10 < N/10 + 9(3P + 1)/10
.Fall II:
0 < d <= 9
. Dann10c = N - d < N
alsoc < N/10
. Deshalbc + d|x| < N/10 + d|x| <= N/10 + 9|x| <= N/10 + 9(3P + 1)/10
. QED.Also, wenn
N > 3P
(undN = 10c + d
wie zuvor), dann3P + 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 > 3P
dannc + d|x| < N
.Deshalb müssen wir nur finden
P
,2P
und3P
, zusammen mitx
. GegebenN > 0
, währendN > 3P
wir ersetzenN
durch|c + dx|
, die abnimmtN
. Irgendwann werden wir bekommenN <= 3P
; stoppen und prüfen , ob an diesem Punkt unsN
auf eine der Zahlen gleich0
,P
,2P
, oder3P
.Wir können es nicht besser machen als
3P
im Allgemeinen. Nehmen wir zum Beispiel an,P = 13
undN = 39
sox = 4
. DannN
durch unverändertedx + c = 9(4) + 3
Blätter ersetzenN
.quelle
-1
außerhalb der Klammer bewegen : 43 ByteLeerzeichen , 92 Bytes
Beachten Sie, dass die Syntax dieser Sprache nur aus Leerzeichen besteht. Daher wurde jedem Leerzeichen hier S, T oder L vorangestellt (entsprechend Leerzeichen, Tabulator bzw. Zeilenvorschub). Diese können entfernt werden, ohne dass die Funktionalität verloren geht. Sie sind jedoch hier enthalten, damit sie korrekt angezeigt werden.
Probieren Sie es online!
quelle
Japt , 14 Bytes
Inspiriert von Neils Lösung .
Online testen!
Erläuterung:
quelle
Pyke , 10 Bytes
Probieren Sie es hier aus!
quelle
Excel, 27 Bytes
Könnte in Cell als eingegeben werden
für 25 Bytes, aber Excel-Auto-Updates.
quelle