Erstellen Sie eine Funktion, die eine Reihe unterschiedlicher Zufallszahlen aus einem Bereich ausgibt. Die Reihenfolge der Elemente in der Menge ist unwichtig (sie können sogar sortiert werden), aber es muss möglich sein, dass der Inhalt der Menge bei jedem Aufruf der Funktion unterschiedlich ist.
Die Funktion erhält 3 Parameter in beliebiger Reihenfolge:
- Anzahl der Zahlen im Ausgabesatz
- Untergrenze (einschließlich)
- Obergrenze (einschließlich)
Angenommen, alle Zahlen sind Ganzzahlen im Bereich von 0 (einschließlich) bis 2 31 (exklusiv). Die Ausgabe kann beliebig zurückgegeben werden (Schreiben an die Konsole, als Array usw.)
Richten
Kriterien sind die 3 Rs
- Laufzeit - getestet auf einem Quad-Core-Windows 7-Computer mit einem beliebigen Compiler, der frei oder leicht verfügbar ist (ggf. einen Link bereitstellen)
- Robustheit - Behandelt die Funktion Eckfälle oder fällt sie in eine Endlosschleife oder führt zu ungültigen Ergebnissen - eine Ausnahme oder ein Fehler bei ungültiger Eingabe ist gültig
- Zufälligkeit - Es sollten zufällige Ergebnisse erzielt werden, die mit einer zufälligen Verteilung nicht leicht vorhersehbar sind. Die Verwendung des eingebauten Zufallszahlengenerators ist in Ordnung. Es sollte jedoch keine offensichtlichen Vorurteile oder offensichtlichen vorhersehbaren Muster geben. Muss besser sein als der Zufallszahlengenerator, der von der Buchhaltungsabteilung in Dilbert verwendet wird
Wenn es robust und zufällig ist, kommt es auf die Laufzeit an. Wenn sie nicht robust oder zufällig sind, schadet dies ihrer Position erheblich.
code-challenge
fastest-code
number
random
Jim McKeeth
quelle
quelle
Antworten:
Python
Ich habe wahrscheinlich gerade einen bekannten Algorithmus neu erfunden, aber die Idee ist, (konzeptionell) ein partielles Fisher-Yates-Shuffle des Bereichs durchzuführen
lower..upper
, um das Längenpräfixn
eines gleichmäßig gemischten Bereichs zu erhalten.Das Speichern des gesamten Sortiments wäre natürlich ziemlich teuer, daher speichere ich nur die Orte, an denen die Elemente ausgetauscht wurden.
Auf diese Weise sollte der Algorithmus sowohl in dem Fall, in dem Sie Zahlen aus einem engen Bereich abtasten (z. B. 1000 Zahlen im Bereich 1..1000), als auch in dem Fall, in dem Sie Zahlen aus einem großen Bereich abtasten, eine gute Leistung erbringen .
Ich bin mir nicht sicher über die Qualität der Zufälligkeit des in Python integrierten Generators, aber es ist relativ einfach, einen Generator auszutauschen, der aus einem bestimmten Bereich einheitliche Ganzzahlen erzeugen kann.
quelle
Python 2.7
Ich bin mir nicht sicher, worauf du stehst, wenn du eingebaute Zufallsmethoden verwendest, aber hier geht es trotzdem. nett und kurz
edit: habe gerade bemerkt, dass range () keine großen Listen erstellt. führt zu einem Speicherfehler. werde sehen, ob es einen anderen Weg gibt, dies zu tun ...
edit2: range war die falsche funktion, xrange funktioniert. Die maximale Ganzzahl ist eigentlich
2**31-1
für PythonPrüfung:
quelle
C.
Gibt ein Array zurück, das x eindeutige zufällige Ints zwischen min und max enthält. (Anrufer muss frei sein)
Funktioniert, indem x aufeinanderfolgende zufällige Ganzzahlen im Bereich generiert und dann gemischt werden. Fügen Sie
seed(time)
irgendwo im Anrufer eine hinzu, wenn Sie nicht bei jedem Lauf die gleichen Ergebnisse erzielen möchten.quelle
Ruby> = 1.8.7
quelle
R.
quelle
Die Frage ist nicht richtig. Benötigen Sie eine einheitliche Probenahme oder nicht? Für den Fall, dass eine einheitliche Stichprobe erforderlich ist, habe ich den folgenden Code in R, der die durchschnittliche Komplexität O ( s log s ) aufweist, wobei s die Stichprobengröße ist.
Natürlich kann man es für eine bessere Leistung in C umschreiben. Die Komplexität dieses Algorithmus wird diskutiert in: Rouzankin, PS; Voytishek, AV Über die Kosten von Algorithmen für die zufällige Auswahl. Monte-Carlo-Methoden Appl. 5 (1999), no. 1, 39-54. http://dx.doi.org/10.1515/mcma.1999.5.1.39
In diesem Artikel können Sie nach einem anderen Algorithmus mit derselben durchschnittlichen Komplexität suchen.
Wenn Sie jedoch keine einheitliche Stichprobe benötigen und nur alle Stichprobenzahlen unterschiedlich sein müssen, ändert sich die Situation dramatisch. Es ist nicht schwer, einen Algorithmus mit durchschnittlicher Komplexität O ( s ) zu schreiben .
Siehe auch für eine einheitliche Stichprobe: P. Gupta, GP Bhattacharjee. (1984) Ein effizienter Algorithmus für die ersatzlose Zufallsauswahl. Internationales Journal für Computermathematik 16: 4, Seiten 201-209. DOI: 10.1080 / 00207168408803438
Teuhola, J. und Nevalainen, O. 1982. Zwei effiziente Algorithmen für die ersatzlose Zufallsauswahl. / IJCM /, 11 (2): 127–140. DOI: 10.1080 / 00207168208803304
Im letzten Artikel verwenden die Autoren Hash-Tabellen und behaupten, dass ihre Algorithmen O ( s ) -Komplexität haben. Es gibt einen weiteren schnellen Hash-Tabellen-Algorithmus, der in Kürze in pqR (ziemlich schnelles R) implementiert wird: https://stat.ethz.ch/pipermail/r-devel/2017-October/075012.html
quelle
APL,
1822 BytesDeklariert eine anonyme Funktion, die zwei Argumente
⍺
und akzeptiert⍵
.⍺
ist die Anzahl der gewünschten Zufallszahlen,⍵
ist ein Vektor, der die unteren und oberen Grenzen in dieser Reihenfolge enthält.a?b
wählt ersatzlosa
Zufallszahlen zwischen 0 undb
0 aus. Durch die Aufnahme erhalten⍵[1]-⍵[0]
wir die Bereichsgröße. Dann wählen wir⍺
Zahlen (siehe unten) aus diesem Bereich und fügen die Untergrenze hinzu. In C wäre dies⍺
mal ersatzlos. Klammern werden nicht benötigt, da APL von rechts nach links arbeitet.Vorausgesetzt, ich habe die Bedingungen richtig verstanden, verfehlt dies die Kriterien für die Robustheit, da die Funktion fehlschlägt, wenn falsche Argumente angegeben werden (z. B. Übergabe eines Vektors anstelle eines Skalars als⍺
).Für den Fall, dass
⍺
es sich eher um einen Vektor als um einen Skalar handelt,1↑⍺
wird das erste Element von übernommen⍺
. Für einen Skalar ist dies der Skalar selbst. Für einen Vektor ist es das erste Element. Dadurch sollte die Funktion die Robustheitskriterien erfüllen.Beispiel:
quelle
{⍵+⍺?⎕-⍵}
Dies sollte ausreichen, wenn die Eingabeaufforderung für die Obergrenze und das rechte Argument für die Untergrenze stehtScala
kompilieren und ausführen:
In der zweiten Zeile werden 200 Tests mit 15 Werten von 0 bis 100 ausgeführt, da Scala einen schnellen Bytecode erzeugt, jedoch einige Startzeit benötigt. 200 Starts mit 15 Werten von 0 bis 100 würden also mehr Zeit in Anspruch nehmen.
Probe auf einem 2 GHz Single Core:
Logik:
Verwenden Sie die eingebauten zufälligen und rekursiv ausgewählten Zahlen im Bereich (max-min), fügen Sie min hinzu und prüfen Sie, ob die Größe des Satzes der erwarteten Größe entspricht.
Kritik:
quelle
Planen
Ich bin mir nicht sicher, warum 3 Parameter übergeben werden müssen oder warum ich einen Bereich annehmen muss ...
quelle
R.
quelle
C ++
Dieser Code eignet sich am besten zum Zeichnen vieler Proben aus dem Bereich.
quelle
max-min
sei denn, es ist viel größer alsn
. Außerdem nimmt die Ausgabesequenz monoton zu, sodass Sie eine Zufälligkeit von sehr geringer Qualität erhalten, aber dennoch die Kosten für dasrand()
mehrfache Anrufen pro Ergebnis bezahlen . Ein zufälliges Mischen des Arrays wäre wahrscheinlich die zusätzliche Laufzeit wert.Q (19 Zeichen)
Verwenden Sie dann f [x; y; z] als [Anzahl der Zahlen im Ausgabesatz; Startpunkt; Größe des Bereichs]
Beispiel: f [5; 10; 10] gibt 5 verschiedene Zufallszahlen zwischen 10 und einschließlich 19 aus.
Die obigen Ergebnisse zeigen die Leistung bei 100.000 Iterationen der Auswahl von 100 Zufallszahlen zwischen 1 und 10.000.
quelle
R, 31 oder 40 Bytes (abhängig von der Bedeutung des Wortes "Bereich")
Wenn der Eingang 3 Zahlen hat
a[1], a[2], a[3]
und mit "Bereich" "eine ganzzahlige Folge von [2] bis [3]" gemeint ist, haben Sie Folgendes:Wenn Sie ein Array haben,
n
von dem Sie ein Resample durchführen möchten, das jedoch unter der Einschränkung der unteren und oberen Grenzen steht, z. B. "Resample-Werte des angegebenen Arraysn
aus dem Bereicha[1]...a[2]
", verwenden Sie Folgendes :Ich bin ziemlich überrascht, warum das vorherige Ergebnis angesichts der eingebauten Probe mit Ersatzeinrichtungen nicht Golf gespielt wurde! Wir erstellen einen Vektor, der die Bereichsbedingung erfüllt, und tasten ihn erneut ab.
quelle
0:(2^31)
verursacht eineError: cannot allocate a vector of size 16.0 Gb
Javascript (mit externer Bibliothek) (64 Bytes / 104 Bytes ??)
Link zur Bibliothek: https://github.com/mvegh1/Enumerable/
Code-Erklärung: Der Lambda-Ausdruck akzeptiert min, max und zählt als Argumente. Erstellen Sie eine Sammlung der Größe n und ordnen Sie jedes Element einer Zufallszahl zu, die den Min / Max-Kriterien entspricht. In ein natives JS-Array konvertieren und zurückgeben. Ich habe dies auch mit einer Eingabe der Größe 5.000.000 ausgeführt und nach dem Anwenden einer bestimmten Transformation immer noch 5.000.000 Elemente angezeigt. Wenn vereinbart wird, dass dies nicht sicher genug ist, um die Unterscheidbarkeit zu gewährleisten, werde ich die Antwort aktualisieren
Ich habe einige Statistiken in das Bild unten aufgenommen ...
BEARBEITEN: Das folgende Bild zeigt Code / Leistung, die garantiert, dass jedes Element anders ist. Es ist viel viel langsamer (6,65 Sekunden für 50.000 Elemente) als der ursprüngliche Code oben für dieselben Argumente (0,012 Sekunden).
quelle
K (oK) , 14 Bytes
Lösung:
Probieren Sie es online aus!
Beispiel:
Erläuterung:
Nimmt 3 implizite Eingaben pro Spezifikation vor:
x
, Anzahl der Zahlen im Ausgabesatz,y
, untere Grenze (einschließlich)z
, Obergrenze (einschließlich)Anmerkungen:
Auch ein Polyglot in
q/kdb+
mit einem zusätzlichen Satz von Klammern:{y+((-)x)?1+z-y}
(16 Bytes).quelle
Axiom + seine Bibliothek
Die obige Funktion f () gibt als Fehler die leere Liste zurück, im Fall f (n, a, b) mit a> b. In anderen Fällen ungültiger Eingaben wird es nicht mit einer Fehlermeldung im Axiom-Fenster ausgeführt, da das Argument nicht vom richtigen Typ ist. Beispiele
quelle