Aufgabe
Bei einer positiven Ganzzahl, die n
kleiner als 2^30
die von Ihnen als Eingabe angegebene ist, sollte Ihr Code eine zufällige Ganzzahl zwischen 0
und n
einschließlich ausgeben . Die von Ihnen generierte Zahl sollte einheitlich und zufällig gewählt werden . Das heißt, jeder Wert von 0
bis n
muss mit gleicher Wahrscheinlichkeit auftreten (siehe Regeln und Vorsichtsmaßnahmen).
Regeln und Vorsichtsmaßnahmen
Ihr Code kann davon ausgehen, dass jeder in Ihre Sprache oder Standardbibliothek eingebaute Zufallszahlengenerator, der behauptet, gleichmäßig zufällig zu sein, tatsächlich gleichmäßig ist. Das heißt, Sie müssen sich keine Gedanken über die Qualität der von Ihnen verwendeten Zufallsquelle machen. Jedoch,
- Sie müssen feststellen, dass Ihr Code eine einheitliche Zufallszahl von
0
bis korrekt ausgibt, wenn die von Ihnen verwendete Zufallsquelle einheitlich istn
. - Alle Argumente beim Aufrufen einer eingebauten oder einer zufälligen Bibliotheksfunktion müssen konstant sein. Das heißt, sie müssen völlig unabhängig vom Eingabewert sein.
- Ihr Code wird möglicherweise mit Wahrscheinlichkeit 1 beendet, anstatt garantiert zu werden, dass er beendet wird.
Anmerkungen
randInt(0,n)
ist ungültig, da die Eingabe als Argument für eine eingebaute Funktion oder eine Bibliotheksfunktion verwendet wird.rand()%n
wird im Allgemeinen keine einheitliche Zufallszahl geben. Wennintmax == 15
undn = 10
, als ein Beispiel von betseg, dann werden Sie viel wahrscheinlicher bekommen0-5
als6-10
.floor(randomfloat()*(n+1))
gibt auch im Allgemeinen keine einheitliche Zufallszahl an, da es endlich viele verschiedene mögliche Gleitkommawerte zwischen 0 und 1 gibt.
code-golf
number
random
probability-theory
total menschlich
quelle
quelle
rng()
bietet0
-100
, wennn = 75
und Funktion istrng()%75
, dann 0-25 wird häufiger ...)Antworten:
x86-Maschinen mit
rdrand
Anweisung, 10 BytesMaschinensprache
Der Eingang befindet sich im Register
rdi
und der Ausgang inrax
.Dies respektiert die SYS V AMD64 ABI, so dass der Code effektiv eine C-Funktion implementiert
mit 32-Bit-Ints.
Die Anleitung
rdrand
wird von Intel beschriebenDer Umgang mit CSRNG impliziert, dass die Verteilung ohnehin einheitlich ist, wobei der NIST SP 800-90A zitiert wird:
Die Prozedur generiert eine Zufallszahl und wenn sie nicht unbedingt größer als die Eingabe ist, wird sie zurückgegeben.
Andernfalls wird der Vorgang wiederholt.
Da
eax
es sich um 32-Bit handelt, wirdrdrand
eine Zahl zwischen 0 und 2 32 -1 zurückgegeben, sodass für jedes n in [0, 2 32 -1] die Anzahl der erwarteten Iterationen 2 32 / (n + 1) beträgt, die für alle n definiert sind in [0, 2 30 ).quelle
jnc
?rdrand
legt fest,CF
ob die zurückgegebenen Daten gültig sind. Daten sind möglicherweise ungültig, weil zu viele Anforderungen den Entropiepool geleert haben. Siehe den manuellen Eintrag für rdrand und dies .Gelee ,
76 BytesVielen Dank an @JonathanAllan für das Abschlagen von 1 Byte!
Kann nicht auf TIO ausgeführt werden, da (16!)! ist eine riesige Zahl.
Wie es funktioniert
quelle
Mathematica, 29 Bytes
Basierend auf Dennis 'Jelly-Antwort .
Ich würde nicht empfehlen, dies tatsächlich auszuführen.
2e9!
ist eine ziemlich große Zahl ...Es erweist sich als am kürzesten, eine riesige Zahl zu generieren, die durch alle möglichen Eingaben teilbar ist, und das Ergebnis mit einem einfachen Modulo auf den gewünschten Bereich abzubilden.
Ablehnungsabtastung, 34 Bytes
Mein alter Ansatz, der zu etwas interessanterem Code führte:
Grundlegende Stichprobenentnahme bei Ablehnung. Wir initialisieren die Ausgabe auf 13! (das ist größer als die maximale Eingabe 2 30 ) und ersetzen Sie es dann wiederholt durch eine zufällige ganze Zahl zwischen 0 und 13! solange der Wert größer als die Eingabe ist.
quelle
Brachylog , 9 Bytes
Probieren Sie es online!
Dies wird
13!
wie in Martin Enders Antwort verwendet (13ḟ
ist ein Byte weniger als2^₃₀
).ṙ
implementiert wird mitrandom_between/3
, der beim Ausgraben seiner Quelle verwendet,random_float/0
welche mitrandom/1
welcher verknüpft ist, den für unsere Zwecke einheitlichen Mersenne-Twister-Algorithmus verwendet.Erläuterung
quelle
Prolog (SWI) , 38 Bytes
Funktioniert durch Ablehnungsabtastung.
Erzeugen Sie eine Zufallszahl zwischen 0 und 2 ^ 31-1 = 2147483647 bis eine kleiner oder gleich der Eingabe ist.
Ich habe das Gefühl, dass ich in der Lage sein sollte, einen Schnitt anstelle des anderen zu verwenden, aber ich kann nicht sehen, wie.
quelle
repeat
, aber es endet damit, dass es 3 Bytes länger ist. Ich bin mir nicht sicher, ob es einen kürzeren Weg gibt, unendlich viele Auswahlpunkte zu haben als zu wiederholen.,!.
, um einen Backtrack zu erzwingen, aber entweder erinnere ich mich daran, dass es falsch war, oder es ist für diese Lösung nicht anwendbar.Labyrinth , 63 Bytes
(Danke an @MartinEnder für die Hilfe beim heftigen Golfen hier.)
Labyrinth ist eine 2D-Sprache und die einzige Quelle für Zufälligkeiten ist eine Situation wie die folgende:
Angenommen, der Anweisungszeiger befindet sich auf
x
und bewegt sich nach unten. Es landet als nächstes auf dem<
, was, wenn der obere Teil des Stapels 0 ist (was im obigen Programm immer der Fall ist), die aktuelle Zeile um 1 nach links verschiebt:Der Befehlszeiger befindet sich jetzt auf der
<
unten. An einer Kreuzung dreht sich das Labyrinth basierend auf der Stapelspitze - Negativ ist links, Positiv ist rechts und Null ist vorwärts. Wenn die Spitze des Stapels zu diesem Zeitpunkt immer noch Null ist, können wir uns nicht vorwärts oder rückwärts bewegen, da es keinen Pfad gibt, sodass Labyrinth mit gleicher Wahrscheinlichkeit zwischen Links- und Rechtskurven zufällig wechselt.Im Wesentlichen verwendet das obige Programm die Zufallsfunktion, um 100-Bit-Zahlen (100, die
#00
hier angegeben sind) zu generieren und die Schleife fortzusetzen, bis eine Zahl generiert wird<= n
.Zum Testen wird es wahrscheinlich hilfreich sein,
#0"
stattdessen 10-Bit-Zahlen zu verwenden, wobei"
es sich um einen No-Op-Pfad handelt. Probieren Sie es online!Grobe Erklärung:
quelle
Python, 61 Bytes
Bearbeiten: Aktualisiert, um verbotene Form zu vermeiden
Edit2: 2 Bytes gespeichert, danke @ JonathanAllan
Edit3: Bezahlt 2 Bytes für eine voll funktionsfähige Lösung - Nochmals vielen Dank an JonathanAllan
Edit4: entfernt
f=
, spart 2 BytesEdit5: 1 weiteres Byte dank @ gespeichert JonathanAllan
Edit6: 2 weitere Bytes dank @ gespeichert JonathanAllan
Inzwischen wies mich die Schuld auf die schlechten Dinge und JonathanAllan auf das, was hilft.
Edit7: Wenn es regnet, gießt es - weitere 2 Bytes
Edit8: Und noch 2 Bytes
quelle
n
, aber Sie können zwei Bytes sparen, wenn Sie dies beheben, indem Sie das verwendenfrom random import*
und löschenr.
....*(-~n*1.0/2**30))
nicht...*((n+1)*1.0/2**30))
randrange
scheint ein Float zu akzeptieren, alsolambda n,x=2.**30:int(randrange(x)*-~n/x)
spart noch zwei [edit ...] vier!Python 2 , 61 Bytes
Pseudozufällig wählt Ganzzahlen zwischen 0 und k für alle Werte von k zwischen 0 und 2 31 - 2 aus und nimmt dann die Ganzzahl entsprechend k = n .
quelle
Batch, 64 Bytes
%random%
gibt nur 15 Bits der Zufälligkeit, also muss ich zwei Zufallszahlen kombinieren. Schleifen, bis der Zufallswert im gewünschten Bereich liegt, also langsam für niedrign
; 98 Bytes für eine schnellere Version:quelle
n
?call
kein Batch-Skript aufrufen, wird das aktuelle Skript beendet.MATL , 12 Bytes
Vielen Dank an @AdmBorkBork und @Suever , die mir mitgeteilt haben , wie der TIO-Cache deaktiviert werden kann.
Probieren Sie es online! .
Hierbei wird eine Ablehnungsmethode verwendet : Erzeugen Sie eine zufällige Ganzzahl von
0
bis2^30-1
und wiederholen Sie diese, solange sie die Eingabe überschreitetn
. Dies wird garantiert mit einer Wahrscheinlichkeit enden1
, aber die durchschnittliche Anzahl von Iterationen ist2^30/n
und daher dauert es sehr lange, bis esn
erheblich kleiner ist als2^30
.quelle
JavaScript (ES6),
5554 ByteErzeugt Ganzzahlen im Bereich [0 ... 2 k - 1] , wobei k die kleinste Ganzzahl ist, sodass 2 k größer als n ist . Wiederholt sich, bis das Ergebnis in [0 ... n] fällt .
Warum?
Dies basiert auf folgenden Annahmen:
Intern die von der JS-Engine generierten pseudozufälligen Ganzzahlwerte zum Feeden
Math.random()
über ein beliebiges Intervall [0 ... 2 k -1] (mit k <32 ) einheitlich .Einmal mit einer exakten Potenz von 2 multipliziert, sind die von zurückgegebenen IEEE 754-Gleitkommawerte
Math.random()
über solche Intervalle hinweg immer noch einheitlich.Wenn jemand diese Hypothesen bestätigen oder widerlegen kann, lassen Sie es mich bitte in den Kommentaren wissen.
Demo
Erzeugt 1 Million Werte in [0 ... 2] und zeigt die Ergebnisstatistik an.
Code-Snippet anzeigen
quelle
Bash (+ Coreutils), 44 Bytes
/ dev / urandom basierte Lösung
Liest vorzeichenlose 32-Bit-Ganzzahlen aus
/dev/urandom
und filtert sie heraus,awk
bis eine innerhalb eines bestimmten Bereichs gefunden wird. Anschließendsed q
wird die Pipe abgebrochen.quelle
Haskell, 70 Bytes
Kein sehr effizienter Algorithmus, aber er funktioniert. Es generiert eine unendliche Liste von Ganzzahlen (oder Gleitkommazahlen, falls erforderlich, aufgrund des Haskell-Typensystems), die durch [0,2 ^ 30] begrenzt sind, und nimmt die erste Zahl kleiner oder gleich n. Für kleine n kann dies lange dauern. Die Zufallszahlen sollten gleichmäßig verteilt sein, wie in der Dokumentation für randomR angegeben, damit alle Zahlen im Intervall [0,2 ^ 30] die gleiche Wahrscheinlichkeit haben (1 / (2 ^ 30 + 1)), also alle Zahlen in [ 0, n] haben die gleiche Wahrscheinlichkeit.
Alternative Version:
Diese Version ist schrecklich, spart aber ein ganzes Byte.
randoms
Verwendet einen willkürlichen Bereich, der vom Typ definiert wird, um eine unendliche Liste von Zahlen zu generieren. Dies kann Negative beinhalten, daher müssen wir es mit abbildenabs
, um sie positiv (oder null) zu machen. Dies ist extrem langsam für alle Werte von n, die nicht absurd groß sind. BEARBEITEN : Ich habe später festgestellt, dass diese Version nicht gleichmäßig verteilt ist, da die Wahrscheinlichkeit, 0 zu erhalten, aufgrund der Verwendung von schlechter als die anderen Zahlen istabs
. Um eine Zahl zu erzeugenm
, könnte der Generator eine Zahl erzeugenm
oder-m
aber im Fall von 0 funktioniert nur 0 selbst, daher ist seine Wahrscheinlichkeit die Hälfte der anderen Zahlen.quelle
Gelee , 9 Bytes
Probieren Sie es online!- Der obige Code wird nicht auf TIO ausgeführt, da es sich um einen Bereich der Größe 16 handelt! muss zuerst erstellt werden (ganz zu schweigen von der Tatsache, dass sie dann gemischt und dann gefiltert werden müssen!), so ist dies dasselbe in einem viel kleineren Maßstab, der 30 Mal für eine Eingabe von 3 mit einer Schranke von 10 wiederholt wird.
Wie?
Hinweis: Es wäre mehr als tausend Mal effizienter, wenn man
ȷ⁵
bei gleicher Byteanzahl das tun würde, was man naiv erwarten würde, und zehn zu zehn zurückgeben würde. Dies ist jedoch nicht der Fall, da die⁵
nicht als zu verwendende wörtliche Zehn ausgewertet wird Nach dem Zahlenliteral werdenȷ...
jedoch zwei separate Literale analysiert,ȷ
wobei der Standardexponent von drei eintausend und⁵
zehn ergibt.quelle
JDK 9 auf jshell,
7559 BytesVerwendung
OptionalInt
. Die Regeln legen nicht fest, dass der Rückgabetyp ein Grundelement sein muss, und ich halte eineOptionalInt
für eine gültige Darstellung des Ergebnisses.quelle
Optional
akzeptiert wird. Ich würde mit dem Plakat bestätigen, wenn ich du wäre. Es ist auch nicht erforderlich, die gesamte Aufgabe zu zählen. nur der Lambda-Ausdruck ist ausreichend.n
und entfernennew Random()
.PHP, 30 Bytes
Laufen Sie mit
echo <N> | php -Rn '<code>'
.wählt eine Zufallszahl zwischen 0 und
getrandmax()
(2 ** 31-1 auf meiner 64-Bit-Maschine);wiederholt sich, während das größer als die Eingabe ist.
Dies kann eine Weile dauern ... mein AMD C-50 (1 GHz) benötigte zwischen 0,3 und 130 Sekunden für
N=15
.Ein schnellerer Weg für den Durchschnitt
N
( 46 Bytes ):oder
nimmt
N+1
zufällige ganze Zahlen, summiert sie und nimmt das Modulo mitN+1
.Der C-50 benötigt ca. 8 Sekunden für 1 Million Läufe.
Eine ungültige Lösung für 19 Bytes :
quelle
PowerShell , 35 Byte
Probieren Sie es online!
Eine weitere Methode zur Probenahme bei Ablehnung. Hierbei handelt es sich um eine
for
Endlosschleife, bei der der Wert von$a
alsRandom
Ganzzahl zwischen0
und1gb
(= 1073741824 = 2^30
) festgelegt wird. Die Schleife wird so lange-g
fortgesetzt, wie diese Ganzzahl ant
der Eingabe anliegt$args
. Sobald die Schleife abgeschlossen ist, setzen wir einfach$a
die Pipeline ein und die Ausgabe ist implizit.Hinweis: Dies dauert lange, wenn die Eingabe eine kleine Zahl ist.
quelle
Python 2 ,
7269 Bytes-3 Bytes dank xnor (überschreibe die
id
eingebaute als Variable)Probieren Sie es online!
randrange(2**30)
erzeugt eine pseudo-gleichmäßig verteilte Zahl (Mersenne Twister 2 19937-1 ) aus dem Bereich [0,2 30 ) . Dan
garantiert weniger als 2 30 ist, kann dies einfach wiederholt aufgerufen werden, bis es nicht mehr als die Eingabe ist. Bei sehr niedrigen Werten von dauert es eine lange erwartete Zeitn
, funktioniert jedoch normalerweise innerhalb einer Minute, selbst bei Eingaben von nur 50.quelle
r=''
als "unendlich" initialisieren . Oder, noch besser, initialisieren Sie es nichtr
und verwenden Sie es stattdessenid
überall fürr
.Perl 6 , 29 Bytes
Inspiriert von Martin Enders Mathematica-Lösung .
Erzeugt eine träge unendliche Folge von Zufallszahlen zwischen 0 und 2 ^ 30-1 und übernimmt die erste, die zwischen 0 und der Eingabe liegt.
Probieren Sie es online!
quelle
05AB1E , 11 Bytes
Probieren Sie es online!
Erläuterung
Da die Liste
[0 ... 2147483648]
für TIO zu groß ist, wird1.000.000
stattdessen der Link verwendet .Alternative (im Durchschnitt) viel schnellere 11-Byte-Lösung
Probieren Sie es online aus
Erläuterung
quelle
žJL.R%
für 6, es sei denn, ich vermisse etwas riesiges. Drücken Sie 2 ^ 32, Liste von 0 bis 2 ^ 32, zufällige Auswahl. Modulo-Eingang. Wird absolut die Effizienz schrauben, die Sie haben.I
dort ein für 7 Bytes, um die Argumente für Modul in der richtigen Reihenfolge (und vielleichtÝ
stattL
) zu erhalten, aber ansonsten ist das sicherlich eine kürzere Lösung. Ich sah Dennis das in seiner Gelee-Antwort tun, aber da dies meine erste Idee war, behielt ich dies bei. Da sich dieser Ansatz von diesem unterscheidet, können Sie ihn als separate Antwort veröffentlichen.DI‹Ï
würde die Schleife vermeiden.0
fast immer zu einer nahezu unendlichen Schleife führen, was das Beenden erschwert. Obwohl die Lösung die Möglichkeit bietet, in allen Szenarien zu kündigen, wird dies aufgrund von Zufälligkeiten nicht garantiert.Python 2, 89 Bytes
Erläuterung
Dies ist sehr ineffizient, da 2 ^ 31 Ganzzahlen erstellt, gemischt und gefiltert werden.
Ich sehe keinen Grund darin, einen TIO-Link zu teilen, über den so große Listen erstellt werden. Deshalb hier ein TIO-Link für
n
= 100.Probieren Sie es online!
quelle
Java 8,
8483807162 Bytes-1 Byte danke an @ OliverGrégoire .
-3 Bytes dank @Jakob .
-9 Bytes Konvertieren von Java 7 nach Java 8.
-9 Bytes durch Ändern
java.util.Random().nextInt(1<<30)
in(int)(Math.random()*(1<<30))
.Erläuterung:
Probieren Sie es hier aus.
HINWEIS: Bei kleinen Eingaben kann dies offensichtlich sehr lange dauern.
Beispielausgabe:
quelle
2^30
=1073741824
. Du hast es vorgezogen-1>>>1
(=2147483647
) zu verwenden. Aber das gibt es:1<<30
was genau gleich ist2^30
; und ist 1 Byte kürzer.int c(int n){int r;for(;(r=new java.util.Random().nextInt(1<<30))>n;);return r;}
?Math.random()
anstelle von verwendet habejava.util.Random().nextInt
.Python 3, 51 Bytes
Hier ist eine Python-Lösung mit einer unorthodoxen Zufallsquelle.
Probieren Sie es online!
Also, um das aufzubrechen.
Ruft die eingegebene Nummer ab und fügt
1
sie hinzu.Erstellt den Satz
{0, 1, 2, 3, 4, ... n}
für alle möglichen Ergebnisse.Nimmt das Set, konvertiert es in eine Liste und greift nach dem ersten Objekt.
Dies funktioniert, weil in Python 3 die Reihenfolge von
set()
durch PYTHONHASHSEED festgelegt wird ( kann nicht abgerufen werden , wird aber bei der Skriptausführung festgelegt).Zugegeben, ich vermute, dass dies eine gleichmäßige Verteilung ist, da der
hash()
Wert zufällig zugewiesen wird und ich den Wert mit einem bestimmten zufällig auswählehash()
, anstatt nur den Werthash(input())
selbst zurückzugeben.Wenn jemand weiß, ob es sich um eine Gleichverteilung handelt oder wie ich das testen könnte, kommentieren Sie bitte.
quelle
C #, 57 Bytes
Anonyme Funktion, die eine Ganzzahl zwischen 0 und n einschließlich zurückgibt.
Je kleiner die eingegebene Zahl ist, desto länger dauert es, einen Zufallswert zurückzugeben.
Volles Programm:
quelle
Next
ist nicht statisch.Bash + Coreutils, 20 Bytes
Golf gespielt
seq 0 $ 1 | shuf | sed 1q
Shuf wird den folgenden Code verwenden : um Permutationen zu generieren:
was endet in
randint_genmax
Dies wiederum liest ein paar Bytes der Zufallsdaten aus der Quelle der Zufälligkeit auf niedriger Ebene:
dh auf der niedrigen Ebene gibt es keine direkte Abhängigkeit zwischen dem
shuf
Eingabewert und den aus der Zufallsquelle gelesenen Daten (abgesehen von der Berechnung der erforderlichen Byte-Pufferkapazität).quelle
jot will arrange for all the values in the range to appear in the output with an equal probability
(das ist wahrscheinlich grenzwertig, aber immer noch).SmileBASIC, 38 Bytes
Erzeugt Zufallszahlen, bis eine kleiner als die Eingabe ist.
quelle
Ruby,
23 15 23 3229 BytesWie es funktioniert:
1while [...];
Führt die Anweisung mindestens einmal aus:1
beforewhile
fungiert als NOPquelle
Ohm, 26 Bytes
Erläuterung:
quelle
Gehen,
6361 BytesBenutze es so:
Testen Sie es live auf dem Go-Spielplatz
quelle
Golang,
847871 BytesEinfache Rückweisungsentnahme.
Hinweis: Da der Startwert für math / rand eine konstante 1 ist, muss der Aufrufer den Startwert festlegen, es sei denn, ein konstantes Ergebnis wird gewünscht.
Test: https://play.golang.org/p/FBB4LKXo1rAuf einem 64-Bit-System praktisch nicht mehr testbar, da es 64-Bit-Zufälligkeit zurückgibt und Ablehnungstests verwendet.quelle
import."math/rand"
dann verwenden,Int31
ist es im globalen Namespace verfügbar und Sie können 4 Bytes speichern, es sind auchint
mindestens 32 Bits garantiert, wodurch Sie weitere 6 Bytes sparen:=
Syntax für weitere 3 BytesInt()
Funktion im Rand-Paket, außerdem können Sie das Leerzeichen nachher entfernenimport