Berechnen Sie die p-adische Norm einer rationalen Zahl
Schreiben Sie eine Funktion oder ein Programm, das 3 Ganzzahlen m,n,p
(wobei p
eine positive Primzahl ist) als Eingabe verwendet und die p-adische Norm (bezeichnet mit |m/n|_p
) als (vollständig reduzierten) Bruch ausgibt . Es ist bekannt, dass Fermat nur sehr kleine Ränder hat, aber was eher unbekannt ist, ist, dass er nur einen sehr kleinen Computerbildschirm hatte. Versuchen Sie also, den Code so kurz wie möglich zu halten, damit er auf den Bildschirm von Fermat passt!
Definition
Bei einer gegebenen Primzahl p
kann jeder Bruch m/n
eindeutig als (a/b)* p^e
solcher geschrieben werden (wobei die Vorzeichen ignoriert werden) , der e
eine ganze Zahl ist und p
weder a
noch teilt b
. Die p-adische Norm von m/n
ist p^-e
. Es gibt einen Sonderfall, wenn der Bruch 0 ist : |0|_p = 0
.
Das Ausgabeformat muss sein x/y
(z 1/3
. B. für ganze Zahlen ist beides 10
oder gleichwertig 10/1
zulässig, für negative Zahlen muss ein führendes Minus vorhanden sein, z. B. -1/3
)
Einzelheiten
Das Programm muss stdin / stdout verwenden oder nur aus einer Funktion bestehen, die die rationale Zahl oder Zeichenfolge zurückgibt. Sie müssen davon ausgehen, dass die Eingabe m/n
nicht vollständig reduziert ist. Sie können davon ausgehen, dass dies p
eine Primzahl ist. Das Programm muss Ganzzahlen zwischen -2^28
bis zu 2^28
10 Sekunden verarbeiten können und sollte nicht länger als 10 Sekunden dauern.
Eingebaute Faktorisierungs- und Prime-Checking-Funktionen sind nicht zulässig, ebenso wie eingebaute Basiskonversationen und eingebaute Funktionen, die die p-adische Bewertung oder Norm berechnen.
Beispiele (aus Wikipedia gestohlen ):
x = m/n = 63/550 = 2^-1 * 3^2 * 5^-2 * 7 * 11^-1
|x|_2 = 2
|x|_3 = 1/9
|x|_5 = 25
|x|_7 = 1/7
|x|_11 = 11
|x|_13 = 1
Interessante Trivia
(Nicht notwendig, um diese Herausforderung zu kennen / zu lesen, aber vielleicht schön als Motivation zu lesen.)
(Bitte korrigieren Sie mich, wenn ich die falschen Wörter verwende oder etwas anderes nicht stimmt. Ich bin es nicht gewohnt, auf Englisch darüber zu sprechen.)
Wenn Sie die rationalen Zahlen als Feld betrachten, induziert die p-adische Norm die p-adische Metrik d_p(a,b) = |a-b|_p
. Dann können Sie füllen Sie dieses Feld im Hinblick auf diese Metrik, das bedeutet Sie ein neues Feld erstellen können , in der alle Cauchyfolgen zusammenlaufen, was eine nette topologische Eigenschaft ist zu haben. (Was zB die rationalen Zahlen nicht haben, aber die Realzahlen.) Diese p-adischen Zahlen werden, wie Sie vielleicht vermutet haben, häufig in der Zahlentheorie verwendet.
Ein weiteres interessantes Ergebnis ist der Satz von Ostrowski, der im Grunde besagt, dass jeder absolute Wert (wie unten definiert) für die rationalen Zahlen einer der folgenden drei ist:
- Das Triviale:
|x|=0 iff x=0, |x|=1 otherwise
- Der Standard (echt):
|x| = x if x>=0, |x| = -x if x<0
- Das p-adic (wie wir es definiert haben).
Ein absoluter Wert / eine Metrik ist nur die Verallgemeinerung dessen, was wir als Entfernung betrachten . Ein absoluter Wert |.|
erfüllt folgende Bedingungen:
|x| >= 0 and |x|=0 if x=0
|xy| = |x| |y|
|x+y| <= |x|+|y|
Beachten Sie, dass Sie Metriken leicht aus absoluten Werten erstellen können und umgekehrt: |x| := d(0,x)
oder d(x,y) := |x-y|
, sie sind also fast gleich, wenn Sie addieren / subtrahieren / multiplizieren können ( dh in integralen Domänen). Ohne diese Struktur können Sie natürlich eine Metrik für allgemeinere Mengen definieren.
quelle
PadicNorm
Funktion ist auch aus? : P|x|_11 = 11
, oder? Oder ist alles in11
Ordnung? Und muss es denx=0
Fall behandeln?x=0
Fall und für dieses Beispiel können Sie die Ausgabe11
als auch11/1
, aber Sie nicht drucken müssen|x|_11
.Antworten:
Julia,
948075 BytesHinweis: Die Verwendung von Zeilenvorschüben anstelle von Semikolons zur besseren Lesbarkeit funktioniert in beiden Fällen genauso.
Dies ist ganz einfach: Die
g(m,n)
Funktion verwendet Rekursion und Rest (%
), um denp^n
Faktor standardmäßig aus der Eingabe zu extrahieren und dann bei jedem Schritt der Rekursionm
mit zun=1
multiplizierenp
, sodass die Ausgabe erfolgtp^n
. Der Code wendet dies aufn/gcd(m,n)
und dann anm/gcd(m,n)
, um den entsprechenden Ausdruck zu erhalten.k=gcd(m,n)
wird verwendet, um diegcd(m,n)
doppelte Berechnung zu vermeiden und Zeichen zu speichern.m!=0
ist ein Test, um den Fall zu behandeln, in demx=0
.Der Ausgang ist von der Form
N/1
oder1/N
gegebenenfalls , woN
istp^e
.quelle
J,
3534 BytesDies ist ein binäres Verb, das die Primzahl
p
als linkes Argument und das Arraym n
als rechtes Argument verwendet. Es druckt immer den Schrägstrich/
und gibt0/1
if zurückm = 0
. Verwenden Sie es so:Erläuterung
Das
x:
schaltet erweiterte Präzision ein, da wir sehr große Zahlen verarbeiten. Der Rest des Codes funktioniert wie folgt:quelle
CJam, 42 Bytes
Dies endet mit einem Fehler (nach dem Drucken von 0) für Eingabe 0. Versuchen Sie es online im CJam-Interpreter .
quelle
Stax , 32 Bytes
Führen Sie es aus und debuggen Sie es
Sollte es kürzer machen können. Die native Unterstützung für Fraktion durch Stax ist ziemlich ordentlich.
ASCII-Äquivalent:
quelle