Schreiben Sie eine Funktion, die eine einzelne positive ganze Zahl n annimmt und die Periode der Dezimaldarstellung von 1 / n zurückgibt .
Testfälle:
1 -> 1 # 1/1 = 1.0000...... = 1._0
2 -> 1 # 1/2 = 0.5000...... = 0.5_0
3 -> 1 # 1/3 = 0.3333...... = 0._3
7 -> 6 # 1/7 = 0.14285714.. = 0._142857
13 -> 6
14 -> 6
123 -> 5
345 -> 22
654 -> 108
12345 -> 822
67890 -> 120
Das ist Code-Golf . Eingebaute oder Bibliotheken, die den Zeitraum direkt zurückgeben, sind nicht zulässig. Nummern bis zu mindestens 100000 sollten in angemessener Zeit (höchstens einige Minuten) funktionieren.
code-golf
number-theory
Howard
quelle
quelle
1.00000000000000000000000000000000000
Antworten:
APL, 19 Zeichen / Byte *
Nars2000 . Die vorherige Version war bei einigen Nummern falsch, dies sollte richtig sein. Ich habe es manuell auf allen Nummern bis zu 50 überprüft.
Auch hier gebührt Ben Reich die Ehre, sich mit der Zeit auseinanderzusetzen
10^i (mod x)
Explosionszeichnung
Beispiele
⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯⎯ *: APL kann in einem eigenen (Legacy-) Einzelbyte -Zeichensatz geschrieben werden, der APL-Symbole den oberen 128-Byte-Werten zuordnet
. Aus diesem Grund kann ein Programm mit N Zeichen , das nur ASCII-Zeichen und APL-Symbole verwendet, als N Byte lang betrachtet werden.
quelle
20
. Können Sie das bitte überprüfen?4
scheint, dass es auch die falsche Antwort geben würde, weil10 != 100 (mod 4)
.GolfScript (
4227)Benchmark-Zeit: 5 Sekunden Benchmarking-Code:
Wir danken Ben Reich für die Kernidee, die Periode von zu betrachten
10^i (mod x)
.Erläuterung
Die Periode
p
ist definiert als die kleinste positive ganze Zahl, diei
wir für alle ausreichend großen habenfrac(10^i * 1/x) = frac(10^(i+p) * 1/x)
. Wir können das etwas vereinfachenfrac(10^i / x) = frac(10^(i+p) / x)
. Nun,frac(a / x) = frac(b / x)
genau dann , wenna == b (mod x)
, so dass wir für die kleinste positive ganze Zahl , so suchen , dass für alle hinreichend großeni
:10^i == 10^(i+p) (mod x)
.Angenommen
10^i == 10^(i+p) (mod x)
. Dann10^(i+1) == 10 * 10^i == 10 * 10^(i+p) == 10^(i+p+1) (mod x)
; Sobald wir also eine Wiederholung bekommen, befinden wir uns in einem unzerbrechlichen Zyklus.Es gibt nur
x
unterschiedliche Werte(mod x)
, so dass wir nach dem Taubenschlagprinzip eine Wiederholung in den erstenx + 1
Werten von erhalten müssen10^i (mod x)
.Der obige Code berechnet also die
x + 2
Werte von10^i (mod x)
*. Dann ist die letzte garantiert eine Wiederholung, und indem ich die Liste umdrehe und danach suche, kann ich das jüngste Vorkommen finden. Darüber hinaus ist dies pseudolineare Zeit, da ich nur die eine Suche durchführe.* Die Extra ist der Sonderfall zu behandeln
x = 1
, weil ich nicht reduzieren10^0 (mod x)
für ein und so suchen würde ich mich0
in[1]
.quelle
Golfscript - 26 Bytes
Bearbeiten: aktualisiert, um auszugeben,
1
wenn die Dezimalstelle endet, anstatt die Länge der Dezimalstellendarstellung.Eine ziemlich effiziente Version. Der Wert 67890 wird in ungefähr 10 Sekunden und 99991 in ungefähr 20 Sekunden ausgeführt. Es ist etwas langsamer als zuvor (ungefähr halb so schnell), da der Bereich, der iteriert wird, verdoppelt wurde, wobei die erste Hälfte ignoriert wird.
Alternativ auch 26 Bytes
Dieser durchläuft die Zeichenfolge
"\n"*(2*i+1)
, wobeii
der Wert an die Funktion übergeben wird. Der Wert an den Block jedes Mal vergangen ist , der Ordnungswert"\n"
, das ist 10 .Das
)^^
ist ein bisschen ein Workaround. Wenn Sie Uncons ein Zeichen aus einer Zeichenkette, ist das Ergebnis der Ordnungswert des Zeichens entfernt, wie oben erwähnt. Wenn Sie diesen Wert jedoch wieder anhängen, wird die Zeichenfolgendarstellung dieser Zahl angehängt und nicht das Zeichen - ziemlich unsymmetrisches Verhalten - und meiner Meinung nach ein Konstruktionsfehler. Wenn Sie das tatsächlich tun wollten, würde das erste Zeichenfolgen nur ein Byte kosten.Eine zusätzliche Kopie des endgültigen Werts befindet sich bereits auf dem Stapel.
)
Daher entferne ich den endgültigen Wert erneut , xoder mit der Zeichenfolge und xoder erneut, sodass alle Zeichen, die vom ersten xoder hinzugefügt oder entfernt wurden, wiederhergestellt werden. Wennint op string
als Zeichen statt als Zeichenfolgendarstellung behandelt würde,)^^
könnte dies durch ersetzt werden|
.Beachten Sie, dass während Strings (die in Golfscript als Array von Ints gespeichert sind) den Wert jedes Zeichens mod 256 anzeigen , die Werte jedes Zeichens selbst möglicherweise außerhalb dieses Bereichs liegen. Beim Testen auf Eindeutigkeit (über festgelegte Operationen) oder Eindeutigkeit (über)
?
wird der tatsächliche Wert verglichen und nicht der Anzeigewert.Eine Patch-Datei für den aktuellen Golfscript-Interpreter :
Das Obige wirkt sich nur auf das Verhalten von
string op int
(und umgekehrt) aus, woop
eines davon ist+-|&^
. Alles andere bleibt unberührt, auch das Verhalten vonGint`
.Die folgende 24-Byte- Lösung wird dann gültig:
Und das behebt auch viele andere wirklich hässliche Workarounds .
Python - 48 Bytes
Nicht die effizienteste Lösung, aber für Werte unter 100000 angemessen .
FWIW, das Kernelement ist identisch mit meiner Lösung zum Generieren zyklischer Zahlen in Dezimalzahl .
Eine effizientere Version desselben Codes ( 70 Byte ):
Der Wert 99991 dauert weniger als eine Sekunde.
quelle
or
das Array auf eine leere Zeichenfolge. Da es sich um eine festgelegte Operation handelt, werden alle Duplikate zuvor entfernt..|
.string int +
würde viele Programme zum Absturz bringen. Ich bin mir nicht sicher, wie oft die anderen Ops für dieses Typpaar verwendet werden.[]+''+
vs''+
. Anfügen int, wie char, string:[]++
vs+
. Apend int, als String - Darstellung, um string:+
vs`+
. In seiner aktuellen Implementierungint''+
ist das synonym zuint`
, was angesichts der Ausführlichkeit, Array zu erzwingen, und dann zu einer Zeichenfolge zu erzwingen, wenn Sie das ASCII-Zeichen möchten, verschwenderisch erscheint.GolfScript,
484746Vielen Dank an @PeterTaylor für das Abschneiden von zwei Zeichen.
Ich habe versucht, J zu verwenden, aber es brachte mir immer wieder seltsame Ergebnisse.
Online testen
Dies dividiert im Grunde genommen 2 und 5 durch die Zahl (2 und 5 sind die Primfaktoren von 10, und ihre Hin- und Herbewegungen enden und füllen den Algorithmus auf), dann die niedrigste ganze Zahl n, so dass die resultierende Zahl 10 ^ n - 1 dividiert die Periode.
quelle
{...}:d;...d
Sie sparen 1 Zeichen mit...{...}:d~
f
habe, dass er nicht auf dem Stapel bleibt, merke ich, dass du es auch tust. Sie sollten wirklich eine hinzufügen,;
um die Funktion für einen fairen Vergleich mit anderen Sprachen zu aktivieren.int array ,)\;
kann auf gekürzt werdenint array +,
.Perl, 52 Zeichen
Dies ist eine unkomplizierte Umsetzung des direkten Ansatzes. (Glücklicherweise ist der direkte Ansatz auch ziemlich effizient: Dank Modulo-Arithmetik muss die Mathematik nie mehr als das Zehnfache des Eingabewerts verarbeiten.)
Da die Herausforderung eine Funktion spezifizierte, fühlte ich mich gezwungen, meine Variablen (neu) zu initialisieren, was ich für ein komplettes Programm nicht tun würde. Ebenso ist die
~~
in der abschließenden Anweisung nicht erforderlich, wenn die Funktion sicher ist, dass sie in einem skalaren Kontext aufgerufen wird.quelle
20
wo sie das falsche Ergebnis liefert.Clojure,
102, 117, 115106unformatiert:
formatiert:
Die Laufzeit skaliert mit der Periode. Fast sofort auf meinem Computer für die Beispielwerte.
Im Grunde berechnet dies das Ergebnis der Subtraktion nach jedem Schritt in der langen Division. Ein Zyklus wird erkannt, wenn diese Zahl an einem beliebigen Punkt mit der zuvor berechneten übereinstimmt.
quelle
20
. Können Sie das bitte überprüfen?(nicht konkurrierende) Pyth
Verwendet den Turtle-and-Hare-Algorithmus ( weitere Informationen ).
Beobachte, wie es jeden Test besteht.
quelle