Ihre Aufgabe ist es, ein Programm zu erstellen, das eine Ganzzahl aufnimmt n > 1
und den Wurf eines einseitigen n
Würfels ausgibt. Dieser Würfel folgt jedoch den Regeln für die Würfelexplosion .
Wenn Sie den Würfel werfen, überprüfen Sie, welchen Wert Sie gewürfelt haben. Wenn Sie das Maximum für diese Art von Würfel haben (auf einem Standard-W4 wären das 4 oder 6 auf einem W6 usw.), würfeln Sie erneut und addieren Sie den neuen Würfel zu dieser Summe. Jeder Wurf erhöht die Gesamtsumme so lange, bis Sie die maximale Anzahl nicht mehr erhöhen. Diese letzte Zahl wird jedoch noch hinzugefügt.
Ihr Programm sollte eine einzelne Ganzzahl aufnehmen n
und den explodierenden n
Würfel werfen. Hier ist eine Beispielverteilung, um zu zeigen, wie es aussehen sollte n=4
. Beachten Sie, dass Sie niemals ein Vielfaches von ausgeben solltenn
, da diese immer explodieren.
Sie können davon ausgehen, dass die Stapelgröße für jede von Ihnen ausgeführte Rekursion unendlich ist, und Ihre Zufallsfunktion muss unseren Standards für die Zufälligkeit entsprechen (integrierter Zufallsgenerator oder Uhrzeit / Datum ). Ihre Zufallsfunktion sollte auch so gleichmäßig wie möglich sein, im Gegensatz zu einer geometrischen Verteilung, da es sich um Würfel handelt.
Antworten:
x86-Maschinencode (für Intel Ivy Bridge und höher), 17 Byte
Die obigen Code-Bytes definieren eine Funktion, die einen explodierenden Chip simuliert. Es wird eine einzige Eingabe in das
ESI
Register übernommen, die die maximale Anzahl der Chips angibt. Es wird ein einzelner Wert in der zurückgegebenECX
Register zurück, der das Ergebnis der Rollen ist.Intern verwendet es die
RDRAND
Anweisung , um eine Zufallszahl zu generieren. Dies verwendet einen Zufallszahlengenerator (RNG), der in die Hardware von Intel Ivy Bridge-Prozessoren und höher integriert ist (einige AMD-CPUs unterstützen diesen Befehl ebenfalls).Die Logik der Funktion ist ansonsten recht einfach. Die generierte Zufallszahl wird mit der Standardtechnik auf den gewünschten Bereich skaliert (
(rand % dieSize) + 1
) so Anschließend wird geprüft, ob sie eine Explosion verursachen soll. Das Endergebnis wird in einem Akkumulatorregister gespeichert.Hier ist eine kommentierte Version, die die Assembler-Mnemonik zeigt:
Ich betrüge ein bisschen . Alle standardmäßigen x86-Aufrufkonventionen geben das Ergebnis einer Funktion im
EAX
Register zurück. In echtem Maschinencode gibt es jedoch keine Aufrufkonventionen. Sie können beliebige Register für die Ein- / Ausgabe verwenden. MitECX
für das Ausgangsregister hat mir 1 Byte gespart. Wenn Sie verwenden möchtenEAX
, fügen SieXCHG eax, ecx
unmittelbar vor derret
Anweisung eine 1-Byte- Anweisung ein. Dies tauscht die Werte der RegisterEAX
und ausECX
, kopiert das Ergebnis effektiv vonECX
nachEAX
und verwirft esECX
mit dem alten Wert vonEAX
.Probieren Sie es online!
Hier ist die äquivalente Funktion, die in C unter Verwendung der
__builtin_ia32_rdrand32_step
von GCC, Clang und ICC unterstützten intrinsischen Funktion transkribiert wurde, um denRDRAND
Befehl zu generieren :Interessanterweise wandelt GCC mit dem
-Os
Flag dies in fast genau denselben Maschinencode um . Es übernimmt die EingabeEDI
stattESI
, was völlig willkürlich ist und nichts Substanzielles am Code ändert. Es muss das Ergebnis in zurückgebenEAX
, wie ich bereits erwähnt habe, und es verwendet die effizientere (aber umfangreichere)MOV
Anweisung, um dies unmittelbar vor dem zu tunRET
. Ansonsten samezies. Es macht immer Spaß, wenn der Prozess vollständig umkehrbar ist: Schreiben Sie den Code in Assembly, transkribieren Sie ihn in C, führen Sie ihn durch einen C-Compiler und bringen Sie Ihre ursprüngliche Assembly wieder heraus!quelle
Python 2 ,
666461 Bytes-3 Bytes dank xnor
Probieren Sie es online!
Die vorherige Rolle wird in gespeichert
c
, sodass wir mehrmals darauf zugreifen können, ohne sie in einer Variablen speichern zu müssen, was in einem Python-Lambda nicht möglich ist. Bei jeder Rekursion prüfen wir, ob wir explodierende Würfel gewürfelt haben.c
wird auf Null initialisiert, alsoc%n
ist Falschgeld dort. In den nächsten Iterationen wird es nur falsch sein, wenn explodierende Würfel gewürfelt wurden.Python 2 , 55 Bytes
Probieren Sie es online!
Meine andere Antwort scheint etwas überarbeitet zu sein, da dies auch zu funktionieren scheint ... Ich lasse es trotzdem.
quelle
c*(c<n)
kann seinc%n
.R , 39 Bytes
Probieren Sie es online!
quelle
sample
die Standards für Zufälligkeit aufgrund seiner Voreingenommenheit ?sample
führt zu einem Mangel an Gleichmäßigkeit, der ein Verhältnis von maximaler zu minimaler Wahrscheinlichkeit von 1,03 ergibt ... Schockierend, nicht wahr ?!sample
Perl 6 , 26 Bytes
Probieren Sie es online!
Erläuterung
quelle
{sum roll(*,1..$_)...$_>*}
J ,
1611 BytesProbieren Sie es online!
Erläuterung
TL; DR
1+?
führt den Würfelwurf aus und(+$:)^:=
wiederholt ihn nur, wenn er der Eingabe entspricht.Die Funktion ist eine Folge von 4 Verben:
Ein Zug ist, wenn 2 oder mehr Verben verkettet sind. Hier ist die Antwort von der Form
f g h j
:Ein sogenannter "4-Zug" wird wie ein Haken und eine Gabel analysiert:
Die Antwort ist also äquivalent zu:
Haken:
(f g) x
undx (f g) y
Ein monadischer (Einargument-) Haken aus zwei Verben mit einem gegebenen Argument
x
hat die folgende Entsprechung:Zum Beispiel wird
(* -) 5
ausgewertet bis5 * (- 5)
, was ausgewertet bis_25
.Dies bedeutet, dass unser 4-Zug, ein Haken von
f
und(g h j)
, äquivalent ist zu:Aber was macht
f
man hier?(+$:)^:=
ist eine Konjunktion von zwei Verben mit der Potenz- Konjunktion^:
: ein weiterer Haken ((+$:)
) und ein Verb (=
). Hinweis hier , dasf
ist dyadic -e hat zwei Argumente (x
und(g h j) x
). Wir müssen uns also ansehen, wie sich das^:
verhält. Die Potenzkonjunktionf^:o
nimmt ein Verbf
und entweder ein Verb oder ein Substantivo
(ein Substantiv ist nur ein Datenelement) und wendetf
o
Zeiten an. Nehmen wir zum Beispielo = 3
. Folgende Äquivalenzen gelten:Wenn
o
es sich um ein Verb handelt, wird die Potenzkonjunktion einfacho
über die Argumente ausgewertet und das Nomenergebnis als Wiederholungszahl verwendet.Für unser Verb
o
ist=
das Gleichheitsverb. Es wird0
für unterschiedliche Argumente und1
für gleiche Argumente ausgewertet . Wir wiederholen den Haken(+$:)
einmal für gleiche und nicht für unterschiedliche Argumente. Zur Vereinfachung der Notation für die Erklärung seiy ⇔ ((g h j) x)
. Denken Sie daran, dass unser erster Hook dem folgenden entspricht:Wenn Sie die Konjunktion erweitern, wird dies zu:
Wenn
x
und gleichy
sind, wird dies:Andernfalls wird dies:
Jetzt haben wir monadische Gabeln gesehen. Hier haben wir eine dyadische Gabel:
Also, wenn
x
undy
sind die gleichen, bekommen wir:Was ist
$:
? Es bezieht sich auf das gesamte Verb selbst und ermöglicht eine Rekursion. Das heißt, wannx
und yare the same, we apply the verb to
yand add
x` dazu.Gabeln:
(g h j) x
Was macht nun die innere Gabel? Dies war
y
in unserem letzten Beispiel. Für eine monadische Abzweigung von drei Verben gilt bei gegebenem Argumentx
die folgende Äquivalenz:Aus diesem nächsten Beispiel : Angenommen , wir Verben genannt haben
SUM
,DIVIDE
undLENGTH
, was tun , was Sie annehmen , sie könnten. Wenn wir die drei zu einer Gabel verketten, erhalten wir:Diese Gabel ergibt den Durchschnitt von
x
(vorausgesetzt, esx
handelt sich um eine Liste von Zahlen). In J würden wir dies tatsächlich als Beispiel schreiben+/ % #
.Eine letzte Sache über Gabeln. Wenn die linke "Zacke" (in unserem obigen symbolischen Fall
g
) ein Substantiv ist, wird sie als konstante Funktion behandelt, die diesen Wert zurückgibt.Mit all dem können wir nun die obige Gabelung verstehen:
?
Alles zusammen
Angesichts all dieser Dinge ist unser Verb gleichbedeutend mit:
Dies drückt die gewünschte Funktionalität aus.
quelle
(+$:)^:=1+?
Gelee , 7 Bytes
Probieren Sie es online!
Verwendet die Rekursion. Führt das Programm erneut aus (
ß
) und fügt (+
) hinzu, wenn (¡
) die ZufallszahlX
(=
) der Programmeingabe entspricht ( ).}
Aktiviertß
die Programmeingabe und¥
kombiniert sie+ß}
zu einem einzigen Link, um sie¡
zu konsumieren.Hier eine Verteilung von 1000 Ausgaben für n = 6, die ich mit diesem Programm gesammelt habe . Gezeichnet mit Python / Matplotlib.
Hier sind 5000 Datenpunkte von n = 3 auf einem Semilog-Plot, der die (ungefähr?) Exponentialverteilung zeigt.
quelle
Pyth -
1211 BytesVerwendet funktionale während. Ich denke, es sollte eine intelligentere Antwort geben, die nur die Verteilung simuliert.
Probieren Sie es online aus .
quelle
Python 3 , 80 Bytes
Probieren Sie es online!
quelle
r.random()
auftritt1-r.random()
, wenn 0 zurückgegeben wird. Sollte funktionieren.import ... as _
kürzeste ist!05AB1E , 10 Bytes
Probieren Sie es online aus oder überprüfen Sie die Listen .
10-Byte-Alternative:
Probieren Sie es online aus oder überprüfen Sie die Listen .
Obwohl ich die Top-Version mehr mag, weil sie das 'Wort' enthält
DIÊ
, das zu der Herausforderung passt.Erläuterung:
quelle
.Γ
etwas zu benutzen oder so.Wolfram Language (Mathematica) , 50 Byte
Probieren Sie es online!
quelle
R ,
4742 BytesProbieren Sie es online!
Verdienst des Ansatzes von ArBo .
Noch ein Byte länger als Robin Ryders , gehen upvote sein!
quelle
if
für 46 Bytes, bekam aber eine 52 auf einmal, was mit n = 4 nicht möglich sein sollte, sodass ich nicht weiß, ob es eine seltsame Sache mit niedriger Rekursionsgrenze gibt, aber ich denke, es könnte fehlerhaft sein. Probieren Sie es online!Ruby , 35 Bytes
Probieren Sie es online!
quelle
x
Variable löschenAPL (Dyalog Unicode) ,
15 bis14 ByteProbieren Sie es online!
quelle
Haskell ,
7776 BytesProbieren Sie es online!
Danke an killmous für ein Byte.
Wenn
<|>
wir im Vorspiel wären, könnten wir es besser machen mitMonadComprehensions
:Haskell , nicht konkurrierend, 66 Bytes
Probieren Sie es online!
quelle
Python 2 , 53 Bytes
Probieren Sie es online!
Verwendet die
or
Kurzschlussidee aus der Antwort von ArBo . Der Ausdruckrandom()*n//1
erzeugt eine Zahl von0
bisn-1
,0
wobei eine Rolle von ersetzt wirdn
. Dasor
nimmt die Zahl, außer wenn es Null ist (Falsey), geht es weitern+f(n)
.quelle
Japt , 13 Bytes
Versuch es
Antwort von Port of Arnauld . Herausgefunden, wie man einen rekursiven Aufruf macht;)
Transpiled JS:
quelle
N.g(f)
:)U
. Das Überspringen einer Zeile scheint ebenfalls zu funktionieren. Das ist ein guter Trick :)Japt , 12 Bytes
Es mag kürzer sein als Danas Lösung, aber es ist verdammt viel hässlicher. Ich poste es nur, weil es für immer scheint, seit wir eine Japt-Lösung hatten, die mit einer leeren Zeile begann.
Versuch es
quelle
PowerShell , 49 Byte
Probieren Sie es online!
Iterative Methode. Setzt die Eingabe
$args
auf$a
und den$l
Ast-Roll (damit wir die Schleife mindestens einmal betreten). Solange der letzte Wurf-eq
dem Eingang entspricht, rollen wir weiter. Innerhalb der Schleife akkumulieren wir$o
die letzte Rolle, die aktualisiert wird, indem ein Bereich von1
bis zur Eingabe erstellt$a
und einRandom
Element davon ausgewählt wird. (Ehrlich gesagt, ich bin ein wenig überrascht, dass das$o+=$l=
funktioniert.) Sobald wir die Schleife verlassen haben, bleiben wir$o
in der Pipeline und die Ausgabe ist implizit.quelle
Viertens (gviertens) , 72 Bytes
Probieren Sie es online!
Code Erklärung
quelle
Batch, 70 Bytes
Übernimmt die Eingabe
n
als Befehlszeilenparameter%1
.d
ist die aktuelle Rolle,t
die kumulative Summe. Einfach weiter rollen bisd
ungleich istn
.quelle
Gelee , 9 Bytes
Probieren Sie es online!
Eine Alternative ohne diese Einschränkung ist:
Gelee , 10 Bytes
Probieren Sie es online!
Beachten Sie, dass beide TIO-Links 400 Zahlen generieren, um die Verteilung anzuzeigen.
quelle
Python 3 ,
8172 BytesProbieren Sie es online!
-9 Bytes dank ArBo
Erläuterung
quelle
from random import*
stattdessen verwenden.TI-BASIC,
2823 Bytes-5 Bytes dank diesem Meta-Post!
Eingang ist in
Ans
.Die Ausgabe erfolgt in
Ans
und wird implizit gedruckt.Beispiele:
Erläuterung:
Anmerkungen:
quelle
startTmr
nicht mehr erforderlich ist, funktioniert diese Übermittlung jetzt für Versionen von TI-BASIC, die vor dem TI-84 +SmileBASIC 3, 49 Bytes
Die Funktion
D N OUT R
implementiert das rekursive Zerlegen von Würfeln.Ungolfed
Beachten Sie, dass Funktionen in SmileBASIC mehrere Rückgabewerte haben können. Wenn eine Funktion einen Rückgabewert hat
fun in OUT var
undvar = fun(in)
genau derselbe ist, können wir die Funktion in derOUT
Form definieren und sie auch in einem Ausdruck im Funktionskörper selbst aufrufen. Wenn ich die Funktion so definiertDEF D(N)
hätte, wie ich sie im Funktionskörper explizit angeben müssteRETURN R
; Das Mischen beider Syntaxen hat mir Bytes erspart.quelle
PowerShell , 43 Byte (iterative Methode)
Probieren Sie es online!
PowerShell , 48 Byte (rekursive Methode)
Probieren Sie es online!
quelle
Gelee , 7 Bytes
Ein monadischer Link, der eine Ganzzahl akzeptiert
n
, die eine Ganzzahl ergibt.Wie?
quelle
SmileBASIC, 41 Bytes
Nach dem Lesen:
Mir wurde klar, dass es kein Würfelwurf war
n
, einfach wiederholen kann, während die Summe ein Vielfaches von istn
.quelle
AnyDice , 36 Bytes
Fast ein eingebautes in der Sprache:
Damit dies korrekt ist, muss ich die Annahme der unendlichen Rekursionstiefe missbrauchen. AnyDice begrenzt die Rekursionstiefe mit einer maximalen Funktionstiefe für globale Eigenschaften. Das Explode Builtin verwendet jedoch ein eigenes; Explodiertiefe - der Standardwert ist 2.
Würde weitere 25 Bytes hinzufügen; und würde nicht wirklich den Anforderungen entsprechen, da es theoretisch möglich ist, dass ein Würfel mehr als 99 Mal explodiert.
Die Ausgabe der Funktion ist ein Die, dh. Ein in AnyDice integrierter Typ, der die Ergebnisse und Wahrscheinlichkeiten des Ergebnisses zusammenfasst.
quelle
CJam , 19 Bytes
Erläuterung:
Oder im Pseudocode:
Als Flussdiagramm:
Probieren Sie es online!
quelle
Excel VBA, 46 Bytes
Vielen Dank an @TaylorScott
Wird im Befehlsfenster ausgeführt.
Als benutzerdefinierte Funktion.
Excel VBA,
10867 Bytesquelle
do
erheblichloop while
reduzieren, indem Sie eine .. -Schleife verwenden und die Funktion in eine Sofortfensterfunktion konvertieren. -Do:v=-Int(-[A1]*Rnd):t=t+v:Loop While[A1]=v:?t
- 46 Bytes