Explodierende Würfel simulieren

31

Ihre Aufgabe ist es, ein Programm zu erstellen, das eine Ganzzahl aufnimmt n > 1und den Wurf eines einseitigen nWü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 nund den explodierenden nWü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.

Rɪᴋᴇʀ
quelle
1
muss das programm perfekt sein Wie kann seine Verteilung um einen extrem geringen Betrag verschoben sein?
Maltysen
An: Riker; RE: @ Maltysens Kommentar oben; oder extrem hohe menge?
Artemis unterstützt Monica

Antworten:

36

x86-Maschinencode (für Intel Ivy Bridge und höher), 17 Byte

31 C9 0F C7 F0 31 D2 F7 F6 42 01 D1 39 F2 74 F2 C3

Die obigen Code-Bytes definieren eine Funktion, die einen explodierenden Chip simuliert. Es wird eine einzige Eingabe in das ESIRegister ü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 RDRANDAnweisung , 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:

           unsigned int RollExplodingDie(unsigned int dieSize)
31 C9        xor     ecx, ecx    ; zero-out ECX, which accumulates the final result
           Roll:
0F C7 F0     rdrand  eax         ; generate a random number in EAX
31 D2        xor     edx, edx    ; zero-out EDX (in preparation for unsigned division)
F7 F6        div     esi         ; divide EDX:EAX by ESI (the die size)
                                 ;   EAX receives the quotient; EDX receives the remainder
42           inc     edx         ; increment the remainder
01 D1        add     ecx, edx    ; add this roll result to the accumulator
39 F2        cmp     edx, esi    ; see if this roll result should cause an explosion
74 F2        jz      Roll        ; if so, re-roll; otherwise, fall through
C3           ret                 ; return, with result in ECX register

Ich betrüge ein bisschen . Alle standardmäßigen x86-Aufrufkonventionen geben das Ergebnis einer Funktion im EAXRegister zurück. In echtem Maschinencode gibt es jedoch keine Aufrufkonventionen. Sie können beliebige Register für die Ein- / Ausgabe verwenden. Mit ECXfür das Ausgangsregister hat mir 1 Byte gespart. Wenn Sie verwenden möchten EAX, fügen Sie XCHG eax, ecxunmittelbar vor der retAnweisung eine 1-Byte- Anweisung ein. Dies tauscht die Werte der Register EAXund aus ECX, kopiert das Ergebnis effektiv von ECXnach EAXund verwirft es ECXmit dem alten Wert von EAX.

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 den RDRANDBefehl zu generieren :

#include <immintrin.h>

unsigned int RollExplodingDie(unsigned int dieSize)
{
    unsigned int result = 0;
Roll:
    unsigned int roll;
    __builtin_ia32_rdrand32_step(&roll);
    roll    = ((roll % dieSize) + 1);
    result += roll;
    if (roll == dieSize)   goto Roll;
    return result;
}

Interessanterweise wandelt GCC mit dem -OsFlag dies in fast genau denselben Maschinencode um . Es übernimmt die Eingabe EDIstatt ESI, was völlig willkürlich ist und nichts Substanzielles am Code ändert. Es muss das Ergebnis in zurückgeben EAX, wie ich bereits erwähnt habe, und es verwendet die effizientere (aber umfangreichere) MOVAnweisung, um dies unmittelbar vor dem zu tun RET. 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!

Cody Gray
quelle
12

Python 2 , 66 64 61 Bytes

-3 Bytes dank xnor

f=lambda n,c=0:c%n or c+f(n,randint(1,n))
from random import*

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.

cwird auf Null initialisiert, also c%nist Falschgeld dort. In den nächsten Iterationen wird es nur falsch sein, wenn explodierende Würfel gewürfelt wurden.

Python 2 , 55 Bytes

f=lambda n:randint(1,n)%n or n+f(n)
from random import*

Probieren Sie es online!

Meine andere Antwort scheint etwas überarbeitet zu sein, da dies auch zu funktionieren scheint ... Ich lasse es trotzdem.

ArBo
quelle
2
Rekursive Funktionen, bei denen die Unterbrechungsbedingung auf Zufälligkeit basiert, haben immer eine von Null verschiedene Wahrscheinlichkeit eines Stapelüberlaufs. Statistisch unbedeutende Chance, aber immer noch ...
mypetlion
3
In der Regel wird angenommen, dass die Stapelgröße bei Code-Golf-Herausforderungen nach meiner Erfahrung unendlich ist. Wenn die Stapelgröße unendlich ansteigt, konvergiert die Wahrscheinlichkeit eines Stapelüberlaufs schnell gegen Null.
ArBo
ArBo do @mypetlion, bevor Sie Ihren Kommentar eingeben, damit Sie den Benutzer anpingen können
MilkyWay90
1
Ich denke c*(c<n)kann sein c%n.
13.
@ Xnor Natürlich bin ich ein Idiot ...
ArBo
12

R , 39 Bytes

n=scan();n*rgeom(1,1-1/n)+sample(n-1,1)

Probieren Sie es online!

nn1nGeometric(11n)nUniform(1,2,,n1)

Robin Ryder
quelle
Sehr schön! Ich muss die eingebauten Distributionen für zufällige Herausforderungen lieben !
Giuseppe
Erfüllt es sampledie Standards für Zufälligkeit aufgrund seiner Voreingenommenheit ?
Xi'an
Ziemlich sicher @ Xi'an es tut : es ist der eingebaute in Zufallsgenerator für diskrete Zufallsvariablen.
Robin Ryder
Ich weiß, ich weiß, aber überprüfen Sie den von mir gesetzten Link: Die Diskretisierung sampleführt zu einem Mangel an Gleichmäßigkeit, der ein Verhältnis von maximaler zu minimaler Wahrscheinlichkeit von 1,03 ergibt ... Schockierend, nicht wahr ?!
Xi'an
samplem231
9

Perl 6 , 26 Bytes

{sum {roll 1..$_:}...*-$_}

Probieren Sie es online!

Erläuterung

{                        } # Anonymous block
                  ...      # Sequence constructor
     {roll 1..$_:}         #   Next elem is random int between 1 and n
                           #   (Called as 0-ary function with the original
                           #   $_ for the 1st elem, then as 1-ary function
                           #   with $_ set to the previous elem which
                           #   equals n.)
                     *-$_  #   Until elem not equal to n (non-zero difference)
 sum                       # Sum all elements
nwellnhof
quelle
2
Nett, meine eigene Lösung war{sum roll(*,1..$_)...$_>*}
Jo King
9

J , 16 11 Bytes

(+$:)^:=1+?

Probieren 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:

             ┌─ + 
         ┌───┴─ $:
  ┌─ ^: ─┴─ =     
  │               
──┤      ┌─ 1     
  └──────┼─ +     
         └─ ?     

Ein Zug ist, wenn 2 oder mehr Verben verkettet sind. Hier ist die Antwort von der Form f g h j:

(+$:)^:=  1  +  ?
    f     g  h  j

Ein sogenannter "4-Zug" wird wie ein Haken und eine Gabel analysiert:

f g h j   ⇔   f (g h j)

Die Antwort ist also äquivalent zu:

(+$:)^:= (1 + ?)

Haken: (f g) xundx (f g) y

Ein monadischer (Einargument-) Haken aus zwei Verben mit einem gegebenen Argument xhat die folgende Entsprechung:

(f g) x   ⇔   x f (g x)

Zum Beispiel wird (* -) 5ausgewertet bis 5 * (- 5), was ausgewertet bis _25.

Dies bedeutet, dass unser 4-Zug, ein Haken von fund (g h j), äquivalent ist zu:

(f (g h j)) x   ⇔   x f ((g h j) x)

Aber was macht fman hier? (+$:)^:=ist eine Konjunktion von zwei Verben mit der Potenz- Konjunktion ^:: ein weiterer Haken ( (+$:)) und ein Verb ( =). Hinweis hier , das fist dyadic -e hat zwei Argumente ( xund (g h j) x). Wir müssen uns also ansehen, wie sich das ^:verhält. Die Potenzkonjunktion f^:onimmt ein Verb fund entweder ein Verb oder ein Substantiv o(ein Substantiv ist nur ein Datenelement) und wendet f oZeiten an. Nehmen wir zum Beispiel o = 3. Folgende Äquivalenzen gelten:

(f^:3) x     ⇔   f (f (f x))
x (f^:3) y   ⇔   x f (x f (x f y))

Wenn oes sich um ein Verb handelt, wird die Potenzkonjunktion einfach oüber die Argumente ausgewertet und das Nomenergebnis als Wiederholungszahl verwendet.

Für unser Verb oist =das Gleichheitsverb. Es wird 0für unterschiedliche Argumente und 1fü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 sei y ⇔ ((g h j) x). Denken Sie daran, dass unser erster Hook dem folgenden entspricht:

x   (+$:)^:=   ((g h j) x)
x   (+$:)^:=   y

Wenn Sie die Konjunktion erweitern, wird dies zu:

x ((+$:)^:(x = y)) y

Wenn xund gleich ysind, wird dies:

x (+$:)^:1 y   ⇔   x (+$:) y

Andernfalls wird dies:

x (+$:)^:0 y   ⇔   y

Jetzt haben wir monadische Gabeln gesehen. Hier haben wir eine dyadische Gabel:

x (f g) y   ⇔   x f (g y)

Also, wenn xund ysind die gleichen, bekommen wir:

x (+$:) y   ⇔   x + ($: y)

Was ist $:? Es bezieht sich auf das gesamte Verb selbst und ermöglicht eine Rekursion. Das heißt, wann xund y are the same, we apply the verb toy and addx` dazu.

Gabeln: (g h j) x

Was macht nun die innere Gabel? Dies war yin unserem letzten Beispiel. Für eine monadische Abzweigung von drei Verben gilt bei gegebenem Argument xdie folgende Äquivalenz:

(g h j) x   ⇔   (g x) h (j x)

Aus diesem nächsten Beispiel : Angenommen , wir Verben genannt haben SUM, DIVIDEund LENGTH, was tun , was Sie annehmen , sie könnten. Wenn wir die drei zu einer Gabel verketten, erhalten wir:

(SUM DIVIDE LENGTH) x   ⇔   (SUM x) DIVIDE (LENGTH x)

Diese Gabel ergibt den Durchschnitt von x(vorausgesetzt, es xhandelt 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:

(1 + ?) x   ⇔   (1 x) + (? x)
            ⇔   1 + (? x)

?[0,x)[1,x]

Alles zusammen

Angesichts all dieser Dinge ist unser Verb gleichbedeutend mit:

((+$:)^:=1+?) x   ⇔   ((+$:)^:= 1 + ?) x
                  ⇔   ((+$:)^:= (1 + ?)) x
                  ⇔   x ((+$:)^:=) (1 + ?) x
                  ⇔   x ((+$:)^:=) (1 + (? x))
                  ⇔   x (+$:)^:(x = (1 + (? x))
(let y = 1 + (? x))
if x = y          ⇒   x + $: y
otherwise         ⇒   y

Dies drückt die gewünschte Funktionalität aus.

Conor O'Brien
quelle
1
(+$:)^:=1+?­­
13.
@ngn Danke! Eingebaut.
Conor O'Brien
7

Gelee , 7 Bytes

X+ß}¥=¡

Probieren Sie es online!

Verwendet die Rekursion. Führt das Programm erneut aus ( ß) und fügt ( +) hinzu, wenn ( ¡) die Zufallszahl X( =) 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. Histogramm

Hier sind 5000 Datenpunkte von n = 3 auf einem Semilog-Plot, der die (ungefähr?) Exponentialverteilung zeigt. Bildbeschreibung hier eingeben

dylnan
quelle
Schöne Grundstücke! Die Verteilung, die Sie erhalten, ist eine geometrische Verteilung (siehe meine Antwort R ), die eng mit der Exponentialverteilung verwandt ist .
Robin Ryder
6

Pyth - 12 11 Bytes

Verwendet funktionale während. Ich denke, es sollte eine intelligentere Antwort geben, die nur die Verteilung simuliert.

-.W!%HQ+hOQ

-         (Q)         Subtract Q. This is because we start Z at Q to save a char
 .W                   While, functionally
  !                   Logical not. In this case, it checks for 0
   %HQ                Current val mod input
  +     (Z)           Add to current val
   h                  Plus 1
    OQ                Random val in [0, input)

Probieren Sie es online aus .

Maltysen
quelle
4

Python 3 , 80 Bytes

import random as r,math
lambda n:int(-math.log(r.random(),n))*n+r.randint(1,n-1)

Probieren Sie es online!

Lynn
quelle
1
Es besteht jedoch eine geringe Wahrscheinlichkeit, dass ein Fehler r.random()auftritt 1-r.random(), wenn 0 zurückgegeben wird. Sollte funktionieren.
Nwellnhof
Technisch gesehen ist diese Chance 0
Quintec
1
Ein seltener Fall, in dem der import ... as _kürzeste ist!
13.
@xnor in der Tat! Das einzige andere Mal , wenn ich daran erinnern , dass in einer Antwort von mir aus zu gewinnen ist hier
Lynn
4

05AB1E , 10 Bytes

[ILΩDIÊ#}O

Probieren Sie es online aus oder überprüfen Sie die Listen .

10-Byte-Alternative:

[LΩDˆÊ#}¯O

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:

[         # Start an infinite loop:
 IL       #  Create a list in the range [1, input]
   Ω      #  Pop and push a random value from this list
    D     #  Duplicate it
     IÊ   #  If it's NOT equal to the input:
       #  #   Stop the infinite loop
}O        # After the loop: sum all values on the stack
          # (which is output implicitly as result)

[         # Start an infinite loop
 L        #  Create a list in the range [1, (implicit) input]
  Ω       #  Pop and push a random value from this list
   Dˆ     #  Add a copy to the global_array
     Ê    #  If it's NOT equal to the (implicit) input:
      #   #   Stop the infinite loop
        # After the loop: push the global_array
  O       # Pop and push its sum
          # (which is output implicitly as result)  
Kevin Cruijssen
quelle
Ich habe versucht, mir eine Möglichkeit zu überlegen, etwas zu benutzen oder so.
Magic Octopus Urn
3

R , 47 42 Bytes

function(n){while(!F%%n)F=F+sample(n,1)
F}

Probieren Sie es online!

Verdienst des Ansatzes von ArBo .

Noch ein Byte länger als Robin Ryders , gehen upvote sein!

Giuseppe
quelle
Interessanterweise überarbeitete ich dies zu einem rekursiven Wert iffü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!
CriminallyVulgar
Ich habe es mit einer rekursiven Methode versucht und eine 54-Byte-Lösung erhalten. Dann probieren Sie etwas Ähnliches für 44 aus. Probieren Sie es online aus!
Aaron Hayman
3

Ruby , 35 Bytes

->n,s=0{s+=x=1+rand(n);x<n||redo;s}

Probieren Sie es online!

Setzen Sie Monica iamnotmaynard wieder ein
quelle
Speichern Sie ein Byte, indem Sie die xVariable löschen
benj2240
3

Haskell , 77 76 Bytes

import System.Random
f x=randomRIO(1,x)>>=(x!)
x!y|y<x=pure y|0<1=(y+)<$>f x

Probieren Sie es online!

Danke an killmous für ein Byte.

Wenn <|>wir im Vorspiel wären, könnten wir es besser machen mit MonadComprehensions:

Haskell , nicht konkurrierend, 66 Bytes

import System.Random
f x=do y<-randomRIO(1,x);[y|y<x]<|>(y+)<$>f x

Probieren Sie es online!

dfeuer
quelle
1
Sie können ein Byte speichern, wenn Sie g als Infixfunktion definieren.
Killmous
1
@killmous, danke. Auf den ersten Blick dachte ich, dass das genauso oder schlechter sein würde, aber es ist besser.
12.
3

Python 2 , 53 Bytes

f=lambda n:random()*n//1or n+f(n)
from random import*

Probieren Sie es online!

Verwendet die orKurzschlussidee aus der Antwort von ArBo . Der Ausdruck random()*n//1erzeugt eine Zahl von 0bis n-1, 0wobei eine Rolle von ersetzt wird n. Das ornimmt die Zahl, außer wenn es Null ist (Falsey), geht es weiter n+f(n).

xnor
quelle
Offenbar war Ihre Antwort bereits offen, als ich sie in meiner kürzeren bearbeitet habe ... Ich habe sie nicht gesehen, aber wenn Sie möchten, dass ich sie lösche, weil sie ziemlich ähnlich ist, werde ich es tun.
ArBo
3

Japt , 13 Bytes

ö)g@¶°X?X+ß:X

Versuch es

Antwort von Port of Arnauld . Herausgefunden, wie man einen rekursiven Aufruf macht;)

Transpiled JS:

// U: Implicit input
// ö: generate a random number [0,U)
(U.ö())
  // g: run the result through a function
  .g(function(X, Y, Z) {
    // increment the result and compare to input
    return U === (++X)
      // if they are the same, roll again and add to current roll
      ? (X + rp())
      // if they are different, use current roll
      : X
   })
Dana
quelle
1
Sehr nette Verwendung von N.g(f):)
Shaggy
Ich habe es selbst probiert und bin zu 12 Bytes gekommen, aber ich möchte es nicht posten, weil mir deine Lösung zu gut gefällt!
Shaggy
Posten Sie es als eine andere Antwort :)
Dana
Es mag kürzer sein, aber es ist um einiges hässlicher als deins: petershaggynoble.github.io/Japt-Interpreter/…
Shaggy
Ich verstehe - ja, ich habe versucht, einen Weg zu finden, um nicht zu verschmutzen U. Das Überspringen einer Zeile scheint ebenfalls zu funktionieren. Das ist ein guter Trick :)
Dana
3

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.


ö
>°V©VªV+ß

Versuch es

Zottelig
quelle
2

PowerShell , 49 Byte

for($a=$l="$args";$a-eq$l){$o+=$l=1..$a|Random}$o

Probieren Sie es online!

Iterative Methode. Setzt die Eingabe $argsauf $aund den $lAst-Roll (damit wir die Schleife mindestens einmal betreten). Solange der letzte Wurf -eqdem Eingang entspricht, rollen wir weiter. Innerhalb der Schleife akkumulieren wir $odie letzte Rolle, die aktualisiert wird, indem ein Bereich von 1bis zur Eingabe erstellt $aund ein RandomElement davon ausgewählt wird. (Ehrlich gesagt, ich bin ein wenig überrascht, dass das $o+=$l=funktioniert.) Sobald wir die Schleife verlassen haben, bleiben wir $oin der Pipeline und die Ausgabe ist implizit.

AdmBorkBork
quelle
2

Viertens (gviertens) , 72 Bytes

include random.fs
: f >r 0 begin i random 1+ >r i + r> i < until rdrop ;

Probieren Sie es online!

Code Erklärung

include random.fs      \ include library file for random
: f                    \ start a new word definition
  >r                   \ stick the input on the return stack (for easy access)
  0                    \ add a counter to hold the sum
  begin                \ start an indefinite loop
    i random 1+        \ generate a random number from 1 to n
    >r i + r>          \ add the result to the counter, use the return stack to save a few bytes
    i <                \ check if result was less than n
  until                \ end the loop if it was, otherwise go back to begin
  rdrop                \ remove n from the return stack
;                      \ end the word definition
reffu
quelle
2

Batch, 70 Bytes

@set t=0
:g
@set/at+=d=%random%%%%1+1
@if %d%==%1 goto g
@echo %t%

Übernimmt die Eingabe nals Befehlszeilenparameter %1. dist die aktuelle Rolle, tdie kumulative Summe. Einfach weiter rollen bis dungleich ist n.

Neil
quelle
2

Python 3 , 81 72 Bytes

from random import*
def f(x,a=0):
 while a%x<1:a+=randint(1,x)
 return a

Probieren Sie es online!

-9 Bytes dank ArBo

Erläuterung

import random             #load the random module              
def explodeDice(num):     #main function
    ans = 0                     #set answer to 0
    while a % num != 0:         #while a isn't a multiple of the input
        ans += random.randint(1, num) #add the next dice roll to answer
    return ans                  #return the answer
Artemis unterstützt Monica
quelle
Sie können 1 Byte speichern, indem Sie from random import*stattdessen verwenden.
Orthoplex
1
Mit dieser rekursiven Lösung können Sie das auf 74 Byte
reduzieren
1
@squid Sie können 1 Byte wie speichern diese .
orthoplex
1
@orthoplex und dann kannst du das if / else kürzen und es zu einem Einzeiler machen .
Fängt
1
@ArBo Ja, deshalb habe ich nicht zu rekursiv gewechselt, ich wollte dich nicht einfach kopieren.
Artemis unterstützt Monica
2

TI-BASIC, 28 23 Bytes

-5 Bytes dank diesem Meta-Post!

Ans→N:0:Repeat fPart(Ans/N:Ans+randInt(1,N:End:Ans

Eingang ist in Ans.
Die Ausgabe erfolgt in Ansund wird implizit gedruckt.

Beispiele:

4
              4
prgmCDGF11
              5
6
              6
prgmCDGF11
              3

Erläuterung:

Ans→N:0:Repeat fPart(Ans/N:Ans+randInt(1,N:End:Ans   ;full logic

Ans→N                                                ;store the input in "N"
      0                                              ;leave 0 in "Ans"
        Repeat fPart(Ans/N                 End       ;loop until the sum
                                                     ; is not a multiple of
                                                     ; the input
                               randInt(1,N           ;generate a random
                                                     ; integer in [1,N]
                           Ans+                      ;then add it to "Ans"
                                               Ans   ;leave the sum in "Ans"
                                                     ;implicitly print "Ans"

Anmerkungen:

  • TI-BASIC ist eine Token-Sprache. Die Anzahl der Zeichen entspricht nicht der Anzahl der Bytes.
Tau
quelle
Da dies startTmrnicht mehr erforderlich ist, funktioniert diese Übermittlung jetzt für Versionen von TI-BASIC, die vor dem TI-84 +
Tau
2

SmileBASIC 3, 49 Bytes

Die Funktion D N OUT Rimplementiert das rekursive Zerlegen von Würfeln.

DEF D N OUT R
R=RND(N)+1IF R==N THEN R=R+D(N)
END

Ungolfed

DEF D N OUT R  'N is sides and R is output param (shorter than using RETURN in this case)
 R=RND(N)+1  'random number in [1, N]
 IF R==N THEN R=R+D(N)  'if roll is same as N then roll again and add
END

Beachten Sie, dass Funktionen in SmileBASIC mehrere Rückgabewerte haben können. Wenn eine Funktion einen Rückgabewert hat fun in OUT varund var = fun(in)genau derselbe ist, können wir die Funktion in der OUTForm definieren und sie auch in einem Ausdruck im Funktionskörper selbst aufrufen. Wenn ich die Funktion so definiert DEF D(N)hätte, wie ich sie im Funktionskörper explizit angeben müsste RETURN R; Das Mischen beider Syntaxen hat mir Bytes erspart.

Schnecke_
quelle
2

Gelee , 7 Bytes

X=п⁸S_

Ein monadischer Link, der eine Ganzzahl akzeptiert n, die eine Ganzzahl ergibt.

105

Wie?

X=п⁸S_ - Link: integer, n
  п    - Collect up while...
 =  ⁸   - ...condition: equal to chain's left argument, n
X       - ...next value: random number in [1..n]
     S  - sum
      _ - subtract n (since the collection starts with [n])
Jonathan Allan
quelle
2

SmileBASIC, 41 Bytes

INPUT N@L
S=S+RND(N)+1ON S MOD N GOTO@L?S

Nach dem Lesen:

Beachten Sie, dass Sie niemals Vielfache von n ausgeben sollten, da diese immer explodieren.

Mir wurde klar, dass es kein Würfelwurf war n , einfach wiederholen kann, während die Summe ein Vielfaches von ist n.

12Me21
quelle
2

AnyDice , 36 Bytes

Fast ein eingebautes in der Sprache:

function:f I:n{result: [explode dI]}

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.

set "explode depth" to 99

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.

Taemyr
quelle
1
Ich denke, ich bin damit einverstanden, dass nicht viel explodiert. Die 36-Byte-Version ist in Ordnung für mich. Ich habe keine Builtins gesagt und ich bin damit einverstanden, dass sie hier sind, da es nicht so ist, als würde Ihre 1 oder 0 Byte Antwort gewinnen. Aber herzlich willkommen auf der Seite!
15.
2

CJam , 19 Bytes

qi{__mr)_T+:T;=}g;T

Erläuterung:

T is pre-set to 0

qi{__mr)_T+:T;=}g;T - whole code
qi                  - read input as integer (n) | Stack: n
  {            }    - block
   __               - Duplicate twice | Stack: n n n
     mr)            - Choose a random number from 1 to n (r). Since 'mr' picks a
                      number from 0 to n-1, the number has to be incremented with ')' 
                      Stack: n n r
        _           - Duplicate |  Stack: n n r r
         T          - push T | Stack: n n r r T
          +         - add the random number to T (t) | Stack: n n r t
           :T;      - pop the value and store in T | Stack: n n r
              =     - are the top two stack values the same (c) | Stack: n c
               }
                g   - do while loop that pops the condition from the stack after each
                      iteration | Stack: n
                 ;  - pop the top stack element and discard | Stack: T
                  T - push T | Stack: T
                    - implicit output

Oder im Pseudocode:

input n
var sum = 0
do {
    var random_number = pick random number from 1 to n
    sum = sum + random_number
} while (random_number == n)
output n

Als Flussdiagramm:

Flussdiagramm des Codes

Probieren Sie es online!

lolad
quelle
2

Excel VBA, 46 Bytes

Vielen Dank an @TaylorScott

Do:v=-Int(-[A1]*Rnd):t=t+v:Loop While[A1]=v:?t

Wird im Befehlsfenster ausgeführt.

Als benutzerdefinierte Funktion.

Excel VBA, 108 67 Bytes

Function z(i)
Do
v=Int((i*Rnd)+1)
z=z+v
Loop While v=i
End Function
William Porter
quelle
Sie können dies doerheblich loop whilereduzieren, 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
Taylor Scott
1
@TaylorScott Danke, ich habe vergessen, dass Do x While y in Excel VBA existiert.
William Porter