Eingabe: Zwei Ganzzahlen n und k in jeder für Ihren Code geeigneten Form
Ausgabe Eine zufällige nicht abnehmende Folge von k ganzen Zahlen im Bereich von 1 bis n. Die Stichprobe sollte einheitlich aus allen nicht abnehmenden Folgen von k ganzen Zahlen mit ganzen Zahlen im Bereich von 1 bis n ausgewählt werden.
Die Ausgabe kann in jedem vernünftigen Format erfolgen, das Sie für zweckmäßig halten.
Sie können jeden Pseudozufallsgenerator verwenden, den Ihre bevorzugte Bibliothek / Sprache bereitstellt.
Wir können annehmen, dass die ganzen Zahlen n, k> 0 sind.
Beispiel
Sagen wir n, k = 2. Die nicht abnehmenden Folgen sind
1,1
1,2
2,2
Jede Sequenz sollte eine Ausgabewahrscheinlichkeit von 1/3 haben.
Beschränkung
Ihr Code sollte für k = 20 und n = 100 nicht länger als ein paar Sekunden ausgeführt werden.
Was geht nicht
Wenn Sie einfach jede Ganzzahl zufällig aus dem Bereich von 1 bis n abtasten und dann die Liste sortieren, erhalten Sie keine gleichmäßige Verteilung.
quelle
Antworten:
Eigentlich ,
1412 BytesDiese Antwort basiert auf der 05AB1E-Antwort von Emigna und den Antworten auf diese Math.SE-Frage . Golfvorschläge willkommen! Probieren Sie es online!
Ungolfing
quelle
Python, 89 Bytes
Es ist einfach, eine aufsteigende und keine absteigende Folge zu erzeugen: Dies ist nur eine zufällige Teilmenge von
k
Zahlen zwischen1
undn
, sortiert.Wir können jedoch eine aufsteigende Folge in eine nicht absteigende umwandeln, indem wir jede Lücke zwischen aufeinanderfolgenden Zahlen um 1 verkleinern. Eine Lücke von 1 wird also zu einer Lücke von 0, was gleiche Zahlen ergibt. Verringern Sie dazu den
i
'größten Wert umi
Damit das Ergebnis von
1
bis istn
, muss die Eingabe von1
bis seinn+k-1
. Dies ergibt einen Unterschied zwischen nicht abnehmenden Zahlenfolgen zwischen1
undn
und zunehmenden Folgen zwischen1
undn+k-1
. Dieselbe Bijektion wird im Argument mit den Sternen und Balken zum Zählen solcher Sequenzen verwendet.Der Code verwendet die Python-Funktion
random.sample
, diek
ersatzlose Samples aus der Eingabeliste entnimmt . Sortieren ergibt die aufsteigende Reihenfolge.quelle
import*
1 Byte speichern)05AB1E , 13 Bytes
Probieren Sie es online!
Erläuterung
quelle
Python, 87 Bytes
Die Wahrscheinlichkeit, dass der maximal mögliche Wert
n
enthalten ist, ist gleichk/(n+k-1)
. Um es einzuschließen, setzen Sie es an das Ende der Liste und dekrementieren Sie die verbleibenden Zahlenk
. Um dies auszuschließen, dekrementieren Sie die Obergrenzen
. Dann wiederholen, bis keine Werte mehr benötigt werden (k==0
).Pythons
random
scheint keine eingebaute Bernoulli-Variable zu haben: 1 mit einer gewissen Wahrscheinlichkeit und 0 mit einer anderen Wahrscheinlichkeit. Dies prüft also, ob ein durch erzeugter Zufallswert zwischen 0 und 1random
unterschritten wirdk/(n+k-1)
. Python 2 würde das Verhältnis als float Teilung, so dass wir stattdessen mehrfach durch den Nenner:k>random()*(n+k-1)
.quelle
numpy.random
, was zu lang ist.JavaScript (Firefox 30+), 74 Byte
Erläuterung
xnors ausgezeichnete Python-Antwort enthält eine sehr gute Zusammenfassung, wie / warum die hier verwendete Technik funktioniert. Der erste Schritt besteht darin, den Bereich [1, 2, ..., n + k - 1] zu erstellen :
Als nächstes müssen wir k zufällige Gegenstände aus diesem Bereich nehmen. Dazu müssen wir jeden Artikel mit der Wahrscheinlichkeit s / q auswählen , wobei s die Anzahl der noch benötigten Artikel und q die Anzahl der im Bereich verbleibenden Artikel ist. Da wir ein Array-Verständnis verwenden, ist dies ziemlich einfach:
Dies gibt uns eine gleichmäßig verteilte, zunehmende Folge von Zahlen. Dies kann durch Subtrahieren der Anzahl der zuvor gefundenen Elemente j behoben werden :
Schließlich durch Speichern von k in können wir j
k--
in den Ausdruck einbauen und ein paar Bytes sparen:quelle
TI-BASIC, 54 Bytes
Folgen Sie der Logik von xnor mit einer kleinen Einschränkung. Wir könnten ein Byte theoretisch so rasieren:
Aber rand (ist reserviert, um eine Liste von Zufallszahlen zu erstellen, sodass wir nicht in der Lage wären, die gewünschte implizite Multiplikation durchzuführen, um ein Byte zu speichern.
Dies sollte mit 84+ pro Einschränkung anständig schnell gehen, aber ich werde überprüfen, ob ich es kann.
quelle
PHP,
777573 BytesLaufen Sie wie folgt:
Erläuterung
Optimierungen
end()
Anrufs und Festlegen gespeichert$argv[2]
zu ,$k
anstatt zu shorten Zugriff auf Argumente$i
Erhöhe stattdessen jede Iterationquelle