Simulating Exploding Dice
$begingroup$
Your task is to make a program that takes in an integer n > 1
, and outputs the roll of a single n
-sided die. However, this dice follows the rules for exploding dice.
When you roll the die, check what value you rolled. If you got the maximum for that kind of die (on a standard d4 that would be 4, or 6 on a d6, etc.), roll again and add the new roll to that total. Each roll continues adding to the total, until you don't roll the max number anymore. That final number is still added though.
Your program should take in a single integer n
, and roll the exploding n
-sided die. Here's an example distribution to show what it should look like for n=4
. Note that you should never output any multiples of n
, since they will always explode.
You can assume the stack size for any recursion you do is infinite, and your random function must meet our standards for randomness (built-in random generator or time/date). Your random function should also be as uniform as possible, vs. something like a geometric distribution, since these are dice we're talking about.
code-golf random
$endgroup$
add a comment |
$begingroup$
Your task is to make a program that takes in an integer n > 1
, and outputs the roll of a single n
-sided die. However, this dice follows the rules for exploding dice.
When you roll the die, check what value you rolled. If you got the maximum for that kind of die (on a standard d4 that would be 4, or 6 on a d6, etc.), roll again and add the new roll to that total. Each roll continues adding to the total, until you don't roll the max number anymore. That final number is still added though.
Your program should take in a single integer n
, and roll the exploding n
-sided die. Here's an example distribution to show what it should look like for n=4
. Note that you should never output any multiples of n
, since they will always explode.
You can assume the stack size for any recursion you do is infinite, and your random function must meet our standards for randomness (built-in random generator or time/date). Your random function should also be as uniform as possible, vs. something like a geometric distribution, since these are dice we're talking about.
code-golf random
$endgroup$
1
$begingroup$
does the program have to be perfect? Like can its distribution be off by some extremely low amount?
$endgroup$
– Maltysen
11 hours ago
$begingroup$
To: Riker; RE: @Maltysen's comment above; or extremely high amount?
$endgroup$
– Artemis Fowl
10 hours ago
2
$begingroup$
@ArtemisFowl See our standards for randomness. Also, here.
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
add a comment |
$begingroup$
Your task is to make a program that takes in an integer n > 1
, and outputs the roll of a single n
-sided die. However, this dice follows the rules for exploding dice.
When you roll the die, check what value you rolled. If you got the maximum for that kind of die (on a standard d4 that would be 4, or 6 on a d6, etc.), roll again and add the new roll to that total. Each roll continues adding to the total, until you don't roll the max number anymore. That final number is still added though.
Your program should take in a single integer n
, and roll the exploding n
-sided die. Here's an example distribution to show what it should look like for n=4
. Note that you should never output any multiples of n
, since they will always explode.
You can assume the stack size for any recursion you do is infinite, and your random function must meet our standards for randomness (built-in random generator or time/date). Your random function should also be as uniform as possible, vs. something like a geometric distribution, since these are dice we're talking about.
code-golf random
$endgroup$
Your task is to make a program that takes in an integer n > 1
, and outputs the roll of a single n
-sided die. However, this dice follows the rules for exploding dice.
When you roll the die, check what value you rolled. If you got the maximum for that kind of die (on a standard d4 that would be 4, or 6 on a d6, etc.), roll again and add the new roll to that total. Each roll continues adding to the total, until you don't roll the max number anymore. That final number is still added though.
Your program should take in a single integer n
, and roll the exploding n
-sided die. Here's an example distribution to show what it should look like for n=4
. Note that you should never output any multiples of n
, since they will always explode.
You can assume the stack size for any recursion you do is infinite, and your random function must meet our standards for randomness (built-in random generator or time/date). Your random function should also be as uniform as possible, vs. something like a geometric distribution, since these are dice we're talking about.
code-golf random
code-golf random
edited 2 hours ago
Rɪᴋᴇʀ
asked 11 hours ago
RɪᴋᴇʀRɪᴋᴇʀ
6,06042869
6,06042869
1
$begingroup$
does the program have to be perfect? Like can its distribution be off by some extremely low amount?
$endgroup$
– Maltysen
11 hours ago
$begingroup$
To: Riker; RE: @Maltysen's comment above; or extremely high amount?
$endgroup$
– Artemis Fowl
10 hours ago
2
$begingroup$
@ArtemisFowl See our standards for randomness. Also, here.
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
add a comment |
1
$begingroup$
does the program have to be perfect? Like can its distribution be off by some extremely low amount?
$endgroup$
– Maltysen
11 hours ago
$begingroup$
To: Riker; RE: @Maltysen's comment above; or extremely high amount?
$endgroup$
– Artemis Fowl
10 hours ago
2
$begingroup$
@ArtemisFowl See our standards for randomness. Also, here.
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
1
1
$begingroup$
does the program have to be perfect? Like can its distribution be off by some extremely low amount?
$endgroup$
– Maltysen
11 hours ago
$begingroup$
does the program have to be perfect? Like can its distribution be off by some extremely low amount?
$endgroup$
– Maltysen
11 hours ago
$begingroup$
To: Riker; RE: @Maltysen's comment above; or extremely high amount?
$endgroup$
– Artemis Fowl
10 hours ago
$begingroup$
To: Riker; RE: @Maltysen's comment above; or extremely high amount?
$endgroup$
– Artemis Fowl
10 hours ago
2
2
$begingroup$
@ArtemisFowl See our standards for randomness. Also, here.
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
$begingroup$
@ArtemisFowl See our standards for randomness. Also, here.
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
add a comment |
30 Answers
30
active
oldest
votes
$begingroup$
Perl 6, 26 bytes
{sum {roll 1..$_:}...*-$_}
Try it online!
Explanation
{ } # 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
$endgroup$
1
$begingroup$
Nice, my own solution was{sum roll(*,1..$_)...$_>*}
$endgroup$
– Jo King
10 hours ago
add a comment |
$begingroup$
Python 2, 66 64 bytes
f=lambda n,c=0:c*(c<n)or c+f(n,randint(1,n))
from random import*
Try it online!
The previous roll is stored in c
, allowing us to access it multiple times without having to store it to a variable, which can't be done in a Python lambda. Each recursion, we check if we rolled exploding dice.
c
is initialised to zero. While c<n
does evaluate to True
in the first iteration, luckily the multiplication by c
makes it falsey again, allowing the lambda to recurse for the first time.
$endgroup$
1
$begingroup$
Recursive functions where the breaking condition is based on randomness will always have a non-zero chance of stack overflow. Statistically insignificant chance, but still...
$endgroup$
– mypetlion
6 hours ago
1
$begingroup$
Typically, stack size is assumed to be infinite in code golfing challenges in my experience. As the stack size increases to infinity, the likelihood of stack overflow quickly converges to zero.
$endgroup$
– ArBo
5 hours ago
add a comment |
$begingroup$
J, 16 bytes
[(]+$:@[)^:=>:@?
Try it online!
Explanation
The function is a fork of three verbs:
┌─ [
│ ┌─ ]
│ ├─ +
│ ┌────┤ ┌─ $:
──┼─ ^: ─┤ └─ @ ─┴─ [
│ └─ =
│
│ ┌─ >:
└─ @ ──┴─ ?
The rightmost verb:>@?
performs the dice roll: 1 + a random number in the range $[0,n)$.
The central verb performs the loop check: (]+$:@[)^:=
. ^:
is the Power conjunction; in this case, because of [
, this gets called dyadically, as n (f^:g) roll
. When used dyadically, f^:g
calls f
on both arguments n g roll
times. =
will yield 1
when roll
is n
. f
(another fork in this case, ] + $:@[
) performs the check to reiterate. It adds the roll (] +
) to the function called again ($:
) with the same input (@[
).
$endgroup$
$begingroup$
(+$:)^:=1+?
$endgroup$
– ngn
29 mins ago
add a comment |
$begingroup$
Pyth - 12 11 bytes
Uses functional while. I feel like there should be a smarter answer that just simulates the distribution.
-.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)
Try it online.
$endgroup$
add a comment |
$begingroup$
R, 41 bytes
function(n)n*rgeom(1,1-1/n)+sample(n-1,1)
Try it online!
Explanation: for a die with $n$ sides, the number of explosions follows a $mathrm{Geometric}left(1-frac{1}{n}right)$ distribution (number of successes before the first failure, where probability of success is $1-frac1n$), which each bring $n$ to the total. The final roll follows a $mathrm{Uniform}(1,2,ldots,n-1)$ distribution which we add to the total.
$endgroup$
$begingroup$
very nice! Gotta love the builtin distributions for random challenges!
$endgroup$
– Giuseppe
10 hours ago
$begingroup$
I'm not sure whether a non-uniform random distribution qualifies as random, but I'm inclined to say no...
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
$begingroup$
I've posted a meta question re: the above comment, so this answer is in limbo for now, but I'm not going to allow any answers using that in the interim. I've also clarified the body of the question.
$endgroup$
– Rɪᴋᴇʀ
2 hours ago
add a comment |
$begingroup$
x86 Machine Code (for Intel Ivy Bridge and later), 17 bytes
31 C9 0F C7 F0 31 D2 F7 F6 42 01 D1 39 F2 74 F2 C3
The above bytes of code define a function that simulates an exploding die. It takes a single input, passed in the ESI
register, indicating the maximum number of the die. It returns a single value in the ECX
register, which is the result of the rolls.
Internally, it uses the RDRAND
instruction to generate a random number. This uses a random number generator (RNG) that is built into the hardware on Intel Ivy Bridge processors and later (some AMD CPUs also support this instruction).
The logic of the function is otherwise quite straightforward. The generated random number is scaled to lie within the desired range using the standard technique ((rand % dieSize) + 1
), and then it is checked to see if it should cause an explosion. The final result is kept in an accumulator register.
Here is an annotated version showing the assembly language mnemonics:
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
I am cheating a bit. All standard x86 calling conventions return a function's result in the EAX
register. But, in true machine code, there are no calling conventions. You can use any registers you want for input/output. Using ECX
for the output register saved me 1 byte. If you want to use EAX
, insert a 1-byte XCHG eax, ecx
instruction immediately before the ret
instruction. This swaps the values of the EAX
and ECX
registers, effectively copying the result from ECX
into EAX
, and trashing ECX
with the old value of EAX
.
Try it online!
Here's the equivalent function transcribed in C, using the __builtin_ia32_rdrand32_step
intrinsic supported by GCC, Clang, and ICC to generate the RDRAND
instruction:
#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;
}
Interestingly, GCC with the -Os
flag transforms this into almost exactly the same machine code. It takes the input in EDI
instead of ESI
, which is completely arbitrary and changes nothing of substance about the code. It must return the result in EAX
, as I mentioned earlier, and it uses the more efficient (but larger) MOV
instruction to do this immediately before the RET
. Otherwise, samezies. It's always fun when the process is fully reversible: write the code in assembly, transcribe it into C, run it through a C compiler, and get your original assembly back out!
$endgroup$
add a comment |
$begingroup$
R, 47 42 bytes
function(n){while(!F%%n)F=F+sample(n,1)
F}
Try it online!
Credit to ArBo's approach.
Still a byte longer than Robin Ryder's, go upvote his!
$endgroup$
$begingroup$
Interesting, I reworked this to a recursiveif
for 46 bytes, but ended up getting a 52 on one roll which shouldn't be possible with n=4, so I don't know if there's a weird low recursion limit thing happening, but I think it may be buggy. Try it online!
$endgroup$
– CriminallyVulgar
11 hours ago
$begingroup$
I tried a recursive and got a 54 byte solution. Then tried something similar to yours for 44 Try it online!
$endgroup$
– Aaron Hayman
9 hours ago
add a comment |
$begingroup$
Wolfram Language (Mathematica), 50 bytes
R@#//.x_/;x~Mod~#==0:>x+R@#&
R=RandomChoice@*Range
Try it online!
$endgroup$
add a comment |
$begingroup$
Python 3, 80 bytes
import random as r,math
lambda n:int(-math.log(r.random(),n))*n+r.randint(1,n-1)
Try it online!
$endgroup$
1
$begingroup$
There's a slight chance for failure ifr.random()
happens to return 0.1-r.random()
should work, though.
$endgroup$
– nwellnhof
9 hours ago
$begingroup$
Though technically that chance is 0
$endgroup$
– Quintec
5 hours ago
add a comment |
$begingroup$
Ruby, 35 bytes
->n,s=0{s+=x=1+rand(n);x<n||redo;s}
Try it online!
$endgroup$
$begingroup$
Save a byte by dropping thex
variable: Try it online!
$endgroup$
– benj2240
3 hours ago
add a comment |
$begingroup$
Python 3, 81 72 bytes
from random import*
def f(x,a=0):
while a%x<1:a+=randint(1,x)
return a
Try it online!
-9 bytes thanks to ArBo
Explanation
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
$endgroup$
$begingroup$
You can save 1 byte by usingfrom random import*
instead.
$endgroup$
– orthoplex
10 hours ago
1
$begingroup$
You can get this down to 74 bytes using this recursive solution
$endgroup$
– squid
10 hours ago
1
$begingroup$
@squid You can save 1 byte like this.
$endgroup$
– orthoplex
9 hours ago
1
$begingroup$
@orthoplex and then you can shorten the if/else, and make it a one-liner. Starts to look like my solution then ;)
$endgroup$
– ArBo
9 hours ago
1
$begingroup$
@ArBo Yea that's why I didn't change to recursive, didn't want to just copy you.
$endgroup$
– Artemis Fowl
8 hours ago
|
show 3 more comments
$begingroup$
JavaScript (ES6), 39 bytes
f=n=>(x=Math.random()*n+1|0)<n?x:x+f(n)
Try it online! or See the distribution for n=4
$endgroup$
add a comment |
$begingroup$
><>, 90 bytes
0& v
v:::< <
v/1>{1-:?!v}
>x0^v10~ <
^
5=?v>:@}}*{+{2*l
&n;>,*:1%-1+:&+&=?^
Try it online!
The whitespace on the second line is bugging me. I'll work on golfing that out.
><>
doesn't have a nice method for producing uniform random integers. This approach generates, for input $N$, a random number produced by generating $N$ random bits, then taking the resulting binary integer and dividing it by $2^N$. This process is repeated until $N$ is not generated by this process.
$endgroup$
$begingroup$
Compression to 72 bytes.
$endgroup$
– Jo King
1 hour ago
add a comment |
$begingroup$
Attache, 30 bytes
f:=${If[x=y,f@x+y,y]}#1&Random
Try it online!
Direct implementation of the process.
Alternatives
36 bytes: ${NestWhile[{_+Random[1,x]},x&`|,0]}
37 bytes: ${NestWhile[{_+Random[1,x]},{x|_},0]}
$endgroup$
add a comment |
$begingroup$
C (gcc), 36 bytes
f(n,x){x=rand()%n+1;x=x-n?x:x+f(n);}
Try it online!
Here a Test with 100k d4
$endgroup$
1
$begingroup$
Shouldn'tsrand(time(0))
be included in the byte count? AFAIKrand()
will always return the same value if it was never seeded
$endgroup$
– Tau
9 hours ago
1
$begingroup$
I'm not entirely sure, but I remember the meta consensus being that using an unseed PRNG is acceptable @Tau
$endgroup$
– Conor O'Brien
9 hours ago
$begingroup$
@ConorO'Brien i was looking on the meta and i found this: codegolf.meta.stackexchange.com/questions/15025/…
$endgroup$
– Giacomo Garabello
9 hours ago
$begingroup$
@GiacomoGarabello I'm 100% ok with a non-seeded PRNG, and it's allowed by our rules on randomness I believe.
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
add a comment |
$begingroup$
Excel VBA, 108 bytes
Function z(i)
v = Int((i * Rnd) + 1)
z = v
Do While v = i
v = Int((i * Rnd) + 1)
z = z + v
Loop
End Function
$endgroup$
add a comment |
$begingroup$
Perl 6, 26 bytes
{[+] {^$_ .roll+1}...$_>*}
Try it online!
$endgroup$
add a comment |
$begingroup$
Python 3, 80 bytes
This is pretty much just a tail-call recursive version of @Artemis Fowl's answer, but I liked doing it without unrolling into a while loop.
Uses an accumulator parameter to return the total rolled value once the exploding stops.
from random import*
def r(n,a=0):v=randint(1,n);a+=v;return r(n,a)if v==n else a
$endgroup$
add a comment |
$begingroup$
PowerShell, 49 bytes
for($a=$l="$args";$a-eq$l){$o+=$l=1..$a|Random}$o
Try it online!
Iterative method. Sets the input $args
to $a
and the $l
ast roll (done so we enter the loop at least once). Then, so long as the last roll is -eq
ual to the input, we keep rolling. Inside the loop we accumulate into $o
the last roll, which is updated by creating a range from 1
to input $a
and picking a Random
element thereof. (Honestly, I'm a little surprised that $o+=$l=
works.) Once we're out of the loop, we leave $o
on the pipeline and output is implicit.
$endgroup$
add a comment |
$begingroup$
Forth (gforth), 72 bytes
include random.fs
: f >r 0 begin i random 1+ >r i + r> i < until rdrop ;
Try it online!
Code Explanation
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
$endgroup$
add a comment |
$begingroup$
Charcoal, 17 bytes
NθW⁼Lυ№υθ⊞υ⊕‽θIΣυ
Try it online! Link is to verbose version of code. Explanation:
Nθ
Input n
.
W⁼Lυ№υθ
Repeat while the predefined empty list only contains n
s (i.e. its length equals its count of n
s)...
⊞υ⊕‽θ
... push a random integer from 1
to n
to the list.
IΣυ
Print the total.
$endgroup$
add a comment |
$begingroup$
Batch, 70 bytes
@set t=0
:g
@set/at+=d=%random%%%%1+1
@if %d%==%1 goto g
@echo %t%
Takes input n
as a command-line parameter %1
. d
is the current roll, t
the cumulative total. Simply keeps rolling until d
is not equal to n
.
$endgroup$
add a comment |
$begingroup$
Jelly, 9 bytes
x⁹X€Ä%ƇµḢ
Try it online!
A monadic link that takes n as its argument and returns a number generated by an exploding n-sided die. This generates 256 numbers from 1 to n and returns the first cumulative sum that is not a multiple of n. In theory this could return 256n, but even for a 2-sided die this would happen only one every $2^{256}$ times.
An alternative that doesn’t have this limitation is:
Jelly, 10 bytes
X³X¤+¥³ḍ¥¿
Try it online!
Note both TIO links generate 400 numbers to show the distribution.
$endgroup$
add a comment |
$begingroup$
C# (Visual C# Interactive Compiler), 60 bytes
int f(int n,int k=1)=>(k=new Random().Next(n)+1)<n?k:k+f(n);
Saved 4 bytes thanks to @ExpiredData!
Try it online!
$endgroup$
$begingroup$
60 bytes
$endgroup$
– Expired Data
6 hours ago
$begingroup$
@ExpiredData Using new Random() gives it the same seed if you call it again, which doesn't make it truly random
$endgroup$
– Embodiment of Ignorance
5 hours ago
$begingroup$
Nah it's a new seed, run my tio a few times. But even if it was same seed random() isn't true random anyway it's a prng....
$endgroup$
– Expired Data
5 hours ago
add a comment |
$begingroup$
Haskell, 77 76 bytes
import System.Random
f x=randomRIO(1,x)>>=(x!)
x!y|y<x=pure y|0<1=(y+)<$>f x
Try it online!
Thanks to killmous for one byte.
$endgroup$
$begingroup$
You can save a byte if you define g as an infix function.
$endgroup$
– killmous
6 hours ago
$begingroup$
@killmous, thanks. At first glance I figured that would be the same or worse, but it's better.
$endgroup$
– dfeuer
4 hours ago
add a comment |
$begingroup$
Haskell, 94 bytes
import System.Random
f n=do
i<-randomRIO(1,n)
if i<n
then return i
else (i+)<$>f n
Try it online!
Quite similar to @dfeur's, but using do
notation.
New contributor
$endgroup$
add a comment |
$begingroup$
perl -Minteger -pe, 34 bytes
$s+=1+rand$_;$s%$_||redo;$_=$s
$endgroup$
add a comment |
$begingroup$
TI-BASIC, 28 23 bytes
-5 bytes thanks to this meta post!
Ans→N:0:Repeat fPart(Ans/N:Ans+randInt(1,N:End:Ans
Input is in Ans
.
Output is in Ans
and is implicitly printed.
Examples:
4
4
prgmCDGF11
5
6
6
prgmCDGF11
3
Explanation:
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"
Notes:
- TI-BASIC is a tokenized language. Character count does not equal byte count.
$endgroup$
$begingroup$
SincestartTmr
is no longer necessary, this submission will now work for versions of TI-BASIC earlier than the TI-84+
$endgroup$
– Tau
1 hour ago
add a comment |
$begingroup$
Jelly, 7 bytes
X+ß}¥=¡
Try it online!
Uses recursion. Runs the program again (ß
) and adds (+
) if (¡
) the random number (X
) is equal (=
) to the program input. }
makes ß
act on the program input and ¥
combines +ß}
into a single link for ¡
to consume.
Here a distribution of 1000 outputs for n=6 which I collected using this program. Plotted with python/matplotlib.
Here is a 5000 data points from n=3 on a semilog plot which shows the (approximately?) exponential distribution.
$endgroup$
add a comment |
$begingroup$
APL (Dyalog Unicode), 15 14 bytes
{×r←?⍵:r⋄⍵+∇⍵}
Try it online!
$endgroup$
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "200"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f183073%2fsimulating-exploding-dice%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
30 Answers
30
active
oldest
votes
30 Answers
30
active
oldest
votes
active
oldest
votes
active
oldest
votes
$begingroup$
Perl 6, 26 bytes
{sum {roll 1..$_:}...*-$_}
Try it online!
Explanation
{ } # 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
$endgroup$
1
$begingroup$
Nice, my own solution was{sum roll(*,1..$_)...$_>*}
$endgroup$
– Jo King
10 hours ago
add a comment |
$begingroup$
Perl 6, 26 bytes
{sum {roll 1..$_:}...*-$_}
Try it online!
Explanation
{ } # 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
$endgroup$
1
$begingroup$
Nice, my own solution was{sum roll(*,1..$_)...$_>*}
$endgroup$
– Jo King
10 hours ago
add a comment |
$begingroup$
Perl 6, 26 bytes
{sum {roll 1..$_:}...*-$_}
Try it online!
Explanation
{ } # 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
$endgroup$
Perl 6, 26 bytes
{sum {roll 1..$_:}...*-$_}
Try it online!
Explanation
{ } # 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
edited 10 hours ago
answered 11 hours ago
nwellnhofnwellnhof
7,52011128
7,52011128
1
$begingroup$
Nice, my own solution was{sum roll(*,1..$_)...$_>*}
$endgroup$
– Jo King
10 hours ago
add a comment |
1
$begingroup$
Nice, my own solution was{sum roll(*,1..$_)...$_>*}
$endgroup$
– Jo King
10 hours ago
1
1
$begingroup$
Nice, my own solution was
{sum roll(*,1..$_)...$_>*}
$endgroup$
– Jo King
10 hours ago
$begingroup$
Nice, my own solution was
{sum roll(*,1..$_)...$_>*}
$endgroup$
– Jo King
10 hours ago
add a comment |
$begingroup$
Python 2, 66 64 bytes
f=lambda n,c=0:c*(c<n)or c+f(n,randint(1,n))
from random import*
Try it online!
The previous roll is stored in c
, allowing us to access it multiple times without having to store it to a variable, which can't be done in a Python lambda. Each recursion, we check if we rolled exploding dice.
c
is initialised to zero. While c<n
does evaluate to True
in the first iteration, luckily the multiplication by c
makes it falsey again, allowing the lambda to recurse for the first time.
$endgroup$
1
$begingroup$
Recursive functions where the breaking condition is based on randomness will always have a non-zero chance of stack overflow. Statistically insignificant chance, but still...
$endgroup$
– mypetlion
6 hours ago
1
$begingroup$
Typically, stack size is assumed to be infinite in code golfing challenges in my experience. As the stack size increases to infinity, the likelihood of stack overflow quickly converges to zero.
$endgroup$
– ArBo
5 hours ago
add a comment |
$begingroup$
Python 2, 66 64 bytes
f=lambda n,c=0:c*(c<n)or c+f(n,randint(1,n))
from random import*
Try it online!
The previous roll is stored in c
, allowing us to access it multiple times without having to store it to a variable, which can't be done in a Python lambda. Each recursion, we check if we rolled exploding dice.
c
is initialised to zero. While c<n
does evaluate to True
in the first iteration, luckily the multiplication by c
makes it falsey again, allowing the lambda to recurse for the first time.
$endgroup$
1
$begingroup$
Recursive functions where the breaking condition is based on randomness will always have a non-zero chance of stack overflow. Statistically insignificant chance, but still...
$endgroup$
– mypetlion
6 hours ago
1
$begingroup$
Typically, stack size is assumed to be infinite in code golfing challenges in my experience. As the stack size increases to infinity, the likelihood of stack overflow quickly converges to zero.
$endgroup$
– ArBo
5 hours ago
add a comment |
$begingroup$
Python 2, 66 64 bytes
f=lambda n,c=0:c*(c<n)or c+f(n,randint(1,n))
from random import*
Try it online!
The previous roll is stored in c
, allowing us to access it multiple times without having to store it to a variable, which can't be done in a Python lambda. Each recursion, we check if we rolled exploding dice.
c
is initialised to zero. While c<n
does evaluate to True
in the first iteration, luckily the multiplication by c
makes it falsey again, allowing the lambda to recurse for the first time.
$endgroup$
Python 2, 66 64 bytes
f=lambda n,c=0:c*(c<n)or c+f(n,randint(1,n))
from random import*
Try it online!
The previous roll is stored in c
, allowing us to access it multiple times without having to store it to a variable, which can't be done in a Python lambda. Each recursion, we check if we rolled exploding dice.
c
is initialised to zero. While c<n
does evaluate to True
in the first iteration, luckily the multiplication by c
makes it falsey again, allowing the lambda to recurse for the first time.
edited 5 hours ago
answered 10 hours ago
ArBoArBo
43115
43115
1
$begingroup$
Recursive functions where the breaking condition is based on randomness will always have a non-zero chance of stack overflow. Statistically insignificant chance, but still...
$endgroup$
– mypetlion
6 hours ago
1
$begingroup$
Typically, stack size is assumed to be infinite in code golfing challenges in my experience. As the stack size increases to infinity, the likelihood of stack overflow quickly converges to zero.
$endgroup$
– ArBo
5 hours ago
add a comment |
1
$begingroup$
Recursive functions where the breaking condition is based on randomness will always have a non-zero chance of stack overflow. Statistically insignificant chance, but still...
$endgroup$
– mypetlion
6 hours ago
1
$begingroup$
Typically, stack size is assumed to be infinite in code golfing challenges in my experience. As the stack size increases to infinity, the likelihood of stack overflow quickly converges to zero.
$endgroup$
– ArBo
5 hours ago
1
1
$begingroup$
Recursive functions where the breaking condition is based on randomness will always have a non-zero chance of stack overflow. Statistically insignificant chance, but still...
$endgroup$
– mypetlion
6 hours ago
$begingroup$
Recursive functions where the breaking condition is based on randomness will always have a non-zero chance of stack overflow. Statistically insignificant chance, but still...
$endgroup$
– mypetlion
6 hours ago
1
1
$begingroup$
Typically, stack size is assumed to be infinite in code golfing challenges in my experience. As the stack size increases to infinity, the likelihood of stack overflow quickly converges to zero.
$endgroup$
– ArBo
5 hours ago
$begingroup$
Typically, stack size is assumed to be infinite in code golfing challenges in my experience. As the stack size increases to infinity, the likelihood of stack overflow quickly converges to zero.
$endgroup$
– ArBo
5 hours ago
add a comment |
$begingroup$
J, 16 bytes
[(]+$:@[)^:=>:@?
Try it online!
Explanation
The function is a fork of three verbs:
┌─ [
│ ┌─ ]
│ ├─ +
│ ┌────┤ ┌─ $:
──┼─ ^: ─┤ └─ @ ─┴─ [
│ └─ =
│
│ ┌─ >:
└─ @ ──┴─ ?
The rightmost verb:>@?
performs the dice roll: 1 + a random number in the range $[0,n)$.
The central verb performs the loop check: (]+$:@[)^:=
. ^:
is the Power conjunction; in this case, because of [
, this gets called dyadically, as n (f^:g) roll
. When used dyadically, f^:g
calls f
on both arguments n g roll
times. =
will yield 1
when roll
is n
. f
(another fork in this case, ] + $:@[
) performs the check to reiterate. It adds the roll (] +
) to the function called again ($:
) with the same input (@[
).
$endgroup$
$begingroup$
(+$:)^:=1+?
$endgroup$
– ngn
29 mins ago
add a comment |
$begingroup$
J, 16 bytes
[(]+$:@[)^:=>:@?
Try it online!
Explanation
The function is a fork of three verbs:
┌─ [
│ ┌─ ]
│ ├─ +
│ ┌────┤ ┌─ $:
──┼─ ^: ─┤ └─ @ ─┴─ [
│ └─ =
│
│ ┌─ >:
└─ @ ──┴─ ?
The rightmost verb:>@?
performs the dice roll: 1 + a random number in the range $[0,n)$.
The central verb performs the loop check: (]+$:@[)^:=
. ^:
is the Power conjunction; in this case, because of [
, this gets called dyadically, as n (f^:g) roll
. When used dyadically, f^:g
calls f
on both arguments n g roll
times. =
will yield 1
when roll
is n
. f
(another fork in this case, ] + $:@[
) performs the check to reiterate. It adds the roll (] +
) to the function called again ($:
) with the same input (@[
).
$endgroup$
$begingroup$
(+$:)^:=1+?
$endgroup$
– ngn
29 mins ago
add a comment |
$begingroup$
J, 16 bytes
[(]+$:@[)^:=>:@?
Try it online!
Explanation
The function is a fork of three verbs:
┌─ [
│ ┌─ ]
│ ├─ +
│ ┌────┤ ┌─ $:
──┼─ ^: ─┤ └─ @ ─┴─ [
│ └─ =
│
│ ┌─ >:
└─ @ ──┴─ ?
The rightmost verb:>@?
performs the dice roll: 1 + a random number in the range $[0,n)$.
The central verb performs the loop check: (]+$:@[)^:=
. ^:
is the Power conjunction; in this case, because of [
, this gets called dyadically, as n (f^:g) roll
. When used dyadically, f^:g
calls f
on both arguments n g roll
times. =
will yield 1
when roll
is n
. f
(another fork in this case, ] + $:@[
) performs the check to reiterate. It adds the roll (] +
) to the function called again ($:
) with the same input (@[
).
$endgroup$
J, 16 bytes
[(]+$:@[)^:=>:@?
Try it online!
Explanation
The function is a fork of three verbs:
┌─ [
│ ┌─ ]
│ ├─ +
│ ┌────┤ ┌─ $:
──┼─ ^: ─┤ └─ @ ─┴─ [
│ └─ =
│
│ ┌─ >:
└─ @ ──┴─ ?
The rightmost verb:>@?
performs the dice roll: 1 + a random number in the range $[0,n)$.
The central verb performs the loop check: (]+$:@[)^:=
. ^:
is the Power conjunction; in this case, because of [
, this gets called dyadically, as n (f^:g) roll
. When used dyadically, f^:g
calls f
on both arguments n g roll
times. =
will yield 1
when roll
is n
. f
(another fork in this case, ] + $:@[
) performs the check to reiterate. It adds the roll (] +
) to the function called again ($:
) with the same input (@[
).
answered 11 hours ago
Conor O'BrienConor O'Brien
30.7k264162
30.7k264162
$begingroup$
(+$:)^:=1+?
$endgroup$
– ngn
29 mins ago
add a comment |
$begingroup$
(+$:)^:=1+?
$endgroup$
– ngn
29 mins ago
$begingroup$
(+$:)^:=1+?
$endgroup$
– ngn
29 mins ago
$begingroup$
(+$:)^:=1+?
$endgroup$
– ngn
29 mins ago
add a comment |
$begingroup$
Pyth - 12 11 bytes
Uses functional while. I feel like there should be a smarter answer that just simulates the distribution.
-.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)
Try it online.
$endgroup$
add a comment |
$begingroup$
Pyth - 12 11 bytes
Uses functional while. I feel like there should be a smarter answer that just simulates the distribution.
-.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)
Try it online.
$endgroup$
add a comment |
$begingroup$
Pyth - 12 11 bytes
Uses functional while. I feel like there should be a smarter answer that just simulates the distribution.
-.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)
Try it online.
$endgroup$
Pyth - 12 11 bytes
Uses functional while. I feel like there should be a smarter answer that just simulates the distribution.
-.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)
Try it online.
edited 6 hours ago
answered 11 hours ago
MaltysenMaltysen
21.4k445116
21.4k445116
add a comment |
add a comment |
$begingroup$
R, 41 bytes
function(n)n*rgeom(1,1-1/n)+sample(n-1,1)
Try it online!
Explanation: for a die with $n$ sides, the number of explosions follows a $mathrm{Geometric}left(1-frac{1}{n}right)$ distribution (number of successes before the first failure, where probability of success is $1-frac1n$), which each bring $n$ to the total. The final roll follows a $mathrm{Uniform}(1,2,ldots,n-1)$ distribution which we add to the total.
$endgroup$
$begingroup$
very nice! Gotta love the builtin distributions for random challenges!
$endgroup$
– Giuseppe
10 hours ago
$begingroup$
I'm not sure whether a non-uniform random distribution qualifies as random, but I'm inclined to say no...
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
$begingroup$
I've posted a meta question re: the above comment, so this answer is in limbo for now, but I'm not going to allow any answers using that in the interim. I've also clarified the body of the question.
$endgroup$
– Rɪᴋᴇʀ
2 hours ago
add a comment |
$begingroup$
R, 41 bytes
function(n)n*rgeom(1,1-1/n)+sample(n-1,1)
Try it online!
Explanation: for a die with $n$ sides, the number of explosions follows a $mathrm{Geometric}left(1-frac{1}{n}right)$ distribution (number of successes before the first failure, where probability of success is $1-frac1n$), which each bring $n$ to the total. The final roll follows a $mathrm{Uniform}(1,2,ldots,n-1)$ distribution which we add to the total.
$endgroup$
$begingroup$
very nice! Gotta love the builtin distributions for random challenges!
$endgroup$
– Giuseppe
10 hours ago
$begingroup$
I'm not sure whether a non-uniform random distribution qualifies as random, but I'm inclined to say no...
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
$begingroup$
I've posted a meta question re: the above comment, so this answer is in limbo for now, but I'm not going to allow any answers using that in the interim. I've also clarified the body of the question.
$endgroup$
– Rɪᴋᴇʀ
2 hours ago
add a comment |
$begingroup$
R, 41 bytes
function(n)n*rgeom(1,1-1/n)+sample(n-1,1)
Try it online!
Explanation: for a die with $n$ sides, the number of explosions follows a $mathrm{Geometric}left(1-frac{1}{n}right)$ distribution (number of successes before the first failure, where probability of success is $1-frac1n$), which each bring $n$ to the total. The final roll follows a $mathrm{Uniform}(1,2,ldots,n-1)$ distribution which we add to the total.
$endgroup$
R, 41 bytes
function(n)n*rgeom(1,1-1/n)+sample(n-1,1)
Try it online!
Explanation: for a die with $n$ sides, the number of explosions follows a $mathrm{Geometric}left(1-frac{1}{n}right)$ distribution (number of successes before the first failure, where probability of success is $1-frac1n$), which each bring $n$ to the total. The final roll follows a $mathrm{Uniform}(1,2,ldots,n-1)$ distribution which we add to the total.
edited 4 hours ago
Solomon Ucko
374212
374212
answered 10 hours ago
Robin RyderRobin Ryder
6719
6719
$begingroup$
very nice! Gotta love the builtin distributions for random challenges!
$endgroup$
– Giuseppe
10 hours ago
$begingroup$
I'm not sure whether a non-uniform random distribution qualifies as random, but I'm inclined to say no...
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
$begingroup$
I've posted a meta question re: the above comment, so this answer is in limbo for now, but I'm not going to allow any answers using that in the interim. I've also clarified the body of the question.
$endgroup$
– Rɪᴋᴇʀ
2 hours ago
add a comment |
$begingroup$
very nice! Gotta love the builtin distributions for random challenges!
$endgroup$
– Giuseppe
10 hours ago
$begingroup$
I'm not sure whether a non-uniform random distribution qualifies as random, but I'm inclined to say no...
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
$begingroup$
I've posted a meta question re: the above comment, so this answer is in limbo for now, but I'm not going to allow any answers using that in the interim. I've also clarified the body of the question.
$endgroup$
– Rɪᴋᴇʀ
2 hours ago
$begingroup$
very nice! Gotta love the builtin distributions for random challenges!
$endgroup$
– Giuseppe
10 hours ago
$begingroup$
very nice! Gotta love the builtin distributions for random challenges!
$endgroup$
– Giuseppe
10 hours ago
$begingroup$
I'm not sure whether a non-uniform random distribution qualifies as random, but I'm inclined to say no...
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
$begingroup$
I'm not sure whether a non-uniform random distribution qualifies as random, but I'm inclined to say no...
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
$begingroup$
I've posted a meta question re: the above comment, so this answer is in limbo for now, but I'm not going to allow any answers using that in the interim. I've also clarified the body of the question.
$endgroup$
– Rɪᴋᴇʀ
2 hours ago
$begingroup$
I've posted a meta question re: the above comment, so this answer is in limbo for now, but I'm not going to allow any answers using that in the interim. I've also clarified the body of the question.
$endgroup$
– Rɪᴋᴇʀ
2 hours ago
add a comment |
$begingroup$
x86 Machine Code (for Intel Ivy Bridge and later), 17 bytes
31 C9 0F C7 F0 31 D2 F7 F6 42 01 D1 39 F2 74 F2 C3
The above bytes of code define a function that simulates an exploding die. It takes a single input, passed in the ESI
register, indicating the maximum number of the die. It returns a single value in the ECX
register, which is the result of the rolls.
Internally, it uses the RDRAND
instruction to generate a random number. This uses a random number generator (RNG) that is built into the hardware on Intel Ivy Bridge processors and later (some AMD CPUs also support this instruction).
The logic of the function is otherwise quite straightforward. The generated random number is scaled to lie within the desired range using the standard technique ((rand % dieSize) + 1
), and then it is checked to see if it should cause an explosion. The final result is kept in an accumulator register.
Here is an annotated version showing the assembly language mnemonics:
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
I am cheating a bit. All standard x86 calling conventions return a function's result in the EAX
register. But, in true machine code, there are no calling conventions. You can use any registers you want for input/output. Using ECX
for the output register saved me 1 byte. If you want to use EAX
, insert a 1-byte XCHG eax, ecx
instruction immediately before the ret
instruction. This swaps the values of the EAX
and ECX
registers, effectively copying the result from ECX
into EAX
, and trashing ECX
with the old value of EAX
.
Try it online!
Here's the equivalent function transcribed in C, using the __builtin_ia32_rdrand32_step
intrinsic supported by GCC, Clang, and ICC to generate the RDRAND
instruction:
#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;
}
Interestingly, GCC with the -Os
flag transforms this into almost exactly the same machine code. It takes the input in EDI
instead of ESI
, which is completely arbitrary and changes nothing of substance about the code. It must return the result in EAX
, as I mentioned earlier, and it uses the more efficient (but larger) MOV
instruction to do this immediately before the RET
. Otherwise, samezies. It's always fun when the process is fully reversible: write the code in assembly, transcribe it into C, run it through a C compiler, and get your original assembly back out!
$endgroup$
add a comment |
$begingroup$
x86 Machine Code (for Intel Ivy Bridge and later), 17 bytes
31 C9 0F C7 F0 31 D2 F7 F6 42 01 D1 39 F2 74 F2 C3
The above bytes of code define a function that simulates an exploding die. It takes a single input, passed in the ESI
register, indicating the maximum number of the die. It returns a single value in the ECX
register, which is the result of the rolls.
Internally, it uses the RDRAND
instruction to generate a random number. This uses a random number generator (RNG) that is built into the hardware on Intel Ivy Bridge processors and later (some AMD CPUs also support this instruction).
The logic of the function is otherwise quite straightforward. The generated random number is scaled to lie within the desired range using the standard technique ((rand % dieSize) + 1
), and then it is checked to see if it should cause an explosion. The final result is kept in an accumulator register.
Here is an annotated version showing the assembly language mnemonics:
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
I am cheating a bit. All standard x86 calling conventions return a function's result in the EAX
register. But, in true machine code, there are no calling conventions. You can use any registers you want for input/output. Using ECX
for the output register saved me 1 byte. If you want to use EAX
, insert a 1-byte XCHG eax, ecx
instruction immediately before the ret
instruction. This swaps the values of the EAX
and ECX
registers, effectively copying the result from ECX
into EAX
, and trashing ECX
with the old value of EAX
.
Try it online!
Here's the equivalent function transcribed in C, using the __builtin_ia32_rdrand32_step
intrinsic supported by GCC, Clang, and ICC to generate the RDRAND
instruction:
#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;
}
Interestingly, GCC with the -Os
flag transforms this into almost exactly the same machine code. It takes the input in EDI
instead of ESI
, which is completely arbitrary and changes nothing of substance about the code. It must return the result in EAX
, as I mentioned earlier, and it uses the more efficient (but larger) MOV
instruction to do this immediately before the RET
. Otherwise, samezies. It's always fun when the process is fully reversible: write the code in assembly, transcribe it into C, run it through a C compiler, and get your original assembly back out!
$endgroup$
add a comment |
$begingroup$
x86 Machine Code (for Intel Ivy Bridge and later), 17 bytes
31 C9 0F C7 F0 31 D2 F7 F6 42 01 D1 39 F2 74 F2 C3
The above bytes of code define a function that simulates an exploding die. It takes a single input, passed in the ESI
register, indicating the maximum number of the die. It returns a single value in the ECX
register, which is the result of the rolls.
Internally, it uses the RDRAND
instruction to generate a random number. This uses a random number generator (RNG) that is built into the hardware on Intel Ivy Bridge processors and later (some AMD CPUs also support this instruction).
The logic of the function is otherwise quite straightforward. The generated random number is scaled to lie within the desired range using the standard technique ((rand % dieSize) + 1
), and then it is checked to see if it should cause an explosion. The final result is kept in an accumulator register.
Here is an annotated version showing the assembly language mnemonics:
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
I am cheating a bit. All standard x86 calling conventions return a function's result in the EAX
register. But, in true machine code, there are no calling conventions. You can use any registers you want for input/output. Using ECX
for the output register saved me 1 byte. If you want to use EAX
, insert a 1-byte XCHG eax, ecx
instruction immediately before the ret
instruction. This swaps the values of the EAX
and ECX
registers, effectively copying the result from ECX
into EAX
, and trashing ECX
with the old value of EAX
.
Try it online!
Here's the equivalent function transcribed in C, using the __builtin_ia32_rdrand32_step
intrinsic supported by GCC, Clang, and ICC to generate the RDRAND
instruction:
#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;
}
Interestingly, GCC with the -Os
flag transforms this into almost exactly the same machine code. It takes the input in EDI
instead of ESI
, which is completely arbitrary and changes nothing of substance about the code. It must return the result in EAX
, as I mentioned earlier, and it uses the more efficient (but larger) MOV
instruction to do this immediately before the RET
. Otherwise, samezies. It's always fun when the process is fully reversible: write the code in assembly, transcribe it into C, run it through a C compiler, and get your original assembly back out!
$endgroup$
x86 Machine Code (for Intel Ivy Bridge and later), 17 bytes
31 C9 0F C7 F0 31 D2 F7 F6 42 01 D1 39 F2 74 F2 C3
The above bytes of code define a function that simulates an exploding die. It takes a single input, passed in the ESI
register, indicating the maximum number of the die. It returns a single value in the ECX
register, which is the result of the rolls.
Internally, it uses the RDRAND
instruction to generate a random number. This uses a random number generator (RNG) that is built into the hardware on Intel Ivy Bridge processors and later (some AMD CPUs also support this instruction).
The logic of the function is otherwise quite straightforward. The generated random number is scaled to lie within the desired range using the standard technique ((rand % dieSize) + 1
), and then it is checked to see if it should cause an explosion. The final result is kept in an accumulator register.
Here is an annotated version showing the assembly language mnemonics:
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
I am cheating a bit. All standard x86 calling conventions return a function's result in the EAX
register. But, in true machine code, there are no calling conventions. You can use any registers you want for input/output. Using ECX
for the output register saved me 1 byte. If you want to use EAX
, insert a 1-byte XCHG eax, ecx
instruction immediately before the ret
instruction. This swaps the values of the EAX
and ECX
registers, effectively copying the result from ECX
into EAX
, and trashing ECX
with the old value of EAX
.
Try it online!
Here's the equivalent function transcribed in C, using the __builtin_ia32_rdrand32_step
intrinsic supported by GCC, Clang, and ICC to generate the RDRAND
instruction:
#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;
}
Interestingly, GCC with the -Os
flag transforms this into almost exactly the same machine code. It takes the input in EDI
instead of ESI
, which is completely arbitrary and changes nothing of substance about the code. It must return the result in EAX
, as I mentioned earlier, and it uses the more efficient (but larger) MOV
instruction to do this immediately before the RET
. Otherwise, samezies. It's always fun when the process is fully reversible: write the code in assembly, transcribe it into C, run it through a C compiler, and get your original assembly back out!
edited 3 hours ago
answered 6 hours ago
Cody GrayCody Gray
2,069416
2,069416
add a comment |
add a comment |
$begingroup$
R, 47 42 bytes
function(n){while(!F%%n)F=F+sample(n,1)
F}
Try it online!
Credit to ArBo's approach.
Still a byte longer than Robin Ryder's, go upvote his!
$endgroup$
$begingroup$
Interesting, I reworked this to a recursiveif
for 46 bytes, but ended up getting a 52 on one roll which shouldn't be possible with n=4, so I don't know if there's a weird low recursion limit thing happening, but I think it may be buggy. Try it online!
$endgroup$
– CriminallyVulgar
11 hours ago
$begingroup$
I tried a recursive and got a 54 byte solution. Then tried something similar to yours for 44 Try it online!
$endgroup$
– Aaron Hayman
9 hours ago
add a comment |
$begingroup$
R, 47 42 bytes
function(n){while(!F%%n)F=F+sample(n,1)
F}
Try it online!
Credit to ArBo's approach.
Still a byte longer than Robin Ryder's, go upvote his!
$endgroup$
$begingroup$
Interesting, I reworked this to a recursiveif
for 46 bytes, but ended up getting a 52 on one roll which shouldn't be possible with n=4, so I don't know if there's a weird low recursion limit thing happening, but I think it may be buggy. Try it online!
$endgroup$
– CriminallyVulgar
11 hours ago
$begingroup$
I tried a recursive and got a 54 byte solution. Then tried something similar to yours for 44 Try it online!
$endgroup$
– Aaron Hayman
9 hours ago
add a comment |
$begingroup$
R, 47 42 bytes
function(n){while(!F%%n)F=F+sample(n,1)
F}
Try it online!
Credit to ArBo's approach.
Still a byte longer than Robin Ryder's, go upvote his!
$endgroup$
R, 47 42 bytes
function(n){while(!F%%n)F=F+sample(n,1)
F}
Try it online!
Credit to ArBo's approach.
Still a byte longer than Robin Ryder's, go upvote his!
edited 9 hours ago
answered 11 hours ago
GiuseppeGiuseppe
17.8k31153
17.8k31153
$begingroup$
Interesting, I reworked this to a recursiveif
for 46 bytes, but ended up getting a 52 on one roll which shouldn't be possible with n=4, so I don't know if there's a weird low recursion limit thing happening, but I think it may be buggy. Try it online!
$endgroup$
– CriminallyVulgar
11 hours ago
$begingroup$
I tried a recursive and got a 54 byte solution. Then tried something similar to yours for 44 Try it online!
$endgroup$
– Aaron Hayman
9 hours ago
add a comment |
$begingroup$
Interesting, I reworked this to a recursiveif
for 46 bytes, but ended up getting a 52 on one roll which shouldn't be possible with n=4, so I don't know if there's a weird low recursion limit thing happening, but I think it may be buggy. Try it online!
$endgroup$
– CriminallyVulgar
11 hours ago
$begingroup$
I tried a recursive and got a 54 byte solution. Then tried something similar to yours for 44 Try it online!
$endgroup$
– Aaron Hayman
9 hours ago
$begingroup$
Interesting, I reworked this to a recursive
if
for 46 bytes, but ended up getting a 52 on one roll which shouldn't be possible with n=4, so I don't know if there's a weird low recursion limit thing happening, but I think it may be buggy. Try it online!$endgroup$
– CriminallyVulgar
11 hours ago
$begingroup$
Interesting, I reworked this to a recursive
if
for 46 bytes, but ended up getting a 52 on one roll which shouldn't be possible with n=4, so I don't know if there's a weird low recursion limit thing happening, but I think it may be buggy. Try it online!$endgroup$
– CriminallyVulgar
11 hours ago
$begingroup$
I tried a recursive and got a 54 byte solution. Then tried something similar to yours for 44 Try it online!
$endgroup$
– Aaron Hayman
9 hours ago
$begingroup$
I tried a recursive and got a 54 byte solution. Then tried something similar to yours for 44 Try it online!
$endgroup$
– Aaron Hayman
9 hours ago
add a comment |
$begingroup$
Wolfram Language (Mathematica), 50 bytes
R@#//.x_/;x~Mod~#==0:>x+R@#&
R=RandomChoice@*Range
Try it online!
$endgroup$
add a comment |
$begingroup$
Wolfram Language (Mathematica), 50 bytes
R@#//.x_/;x~Mod~#==0:>x+R@#&
R=RandomChoice@*Range
Try it online!
$endgroup$
add a comment |
$begingroup$
Wolfram Language (Mathematica), 50 bytes
R@#//.x_/;x~Mod~#==0:>x+R@#&
R=RandomChoice@*Range
Try it online!
$endgroup$
Wolfram Language (Mathematica), 50 bytes
R@#//.x_/;x~Mod~#==0:>x+R@#&
R=RandomChoice@*Range
Try it online!
edited 10 hours ago
answered 11 hours ago
J42161217J42161217
14k21353
14k21353
add a comment |
add a comment |
$begingroup$
Python 3, 80 bytes
import random as r,math
lambda n:int(-math.log(r.random(),n))*n+r.randint(1,n-1)
Try it online!
$endgroup$
1
$begingroup$
There's a slight chance for failure ifr.random()
happens to return 0.1-r.random()
should work, though.
$endgroup$
– nwellnhof
9 hours ago
$begingroup$
Though technically that chance is 0
$endgroup$
– Quintec
5 hours ago
add a comment |
$begingroup$
Python 3, 80 bytes
import random as r,math
lambda n:int(-math.log(r.random(),n))*n+r.randint(1,n-1)
Try it online!
$endgroup$
1
$begingroup$
There's a slight chance for failure ifr.random()
happens to return 0.1-r.random()
should work, though.
$endgroup$
– nwellnhof
9 hours ago
$begingroup$
Though technically that chance is 0
$endgroup$
– Quintec
5 hours ago
add a comment |
$begingroup$
Python 3, 80 bytes
import random as r,math
lambda n:int(-math.log(r.random(),n))*n+r.randint(1,n-1)
Try it online!
$endgroup$
Python 3, 80 bytes
import random as r,math
lambda n:int(-math.log(r.random(),n))*n+r.randint(1,n-1)
Try it online!
answered 9 hours ago
LynnLynn
50.8k899233
50.8k899233
1
$begingroup$
There's a slight chance for failure ifr.random()
happens to return 0.1-r.random()
should work, though.
$endgroup$
– nwellnhof
9 hours ago
$begingroup$
Though technically that chance is 0
$endgroup$
– Quintec
5 hours ago
add a comment |
1
$begingroup$
There's a slight chance for failure ifr.random()
happens to return 0.1-r.random()
should work, though.
$endgroup$
– nwellnhof
9 hours ago
$begingroup$
Though technically that chance is 0
$endgroup$
– Quintec
5 hours ago
1
1
$begingroup$
There's a slight chance for failure if
r.random()
happens to return 0. 1-r.random()
should work, though.$endgroup$
– nwellnhof
9 hours ago
$begingroup$
There's a slight chance for failure if
r.random()
happens to return 0. 1-r.random()
should work, though.$endgroup$
– nwellnhof
9 hours ago
$begingroup$
Though technically that chance is 0
$endgroup$
– Quintec
5 hours ago
$begingroup$
Though technically that chance is 0
$endgroup$
– Quintec
5 hours ago
add a comment |
$begingroup$
Ruby, 35 bytes
->n,s=0{s+=x=1+rand(n);x<n||redo;s}
Try it online!
$endgroup$
$begingroup$
Save a byte by dropping thex
variable: Try it online!
$endgroup$
– benj2240
3 hours ago
add a comment |
$begingroup$
Ruby, 35 bytes
->n,s=0{s+=x=1+rand(n);x<n||redo;s}
Try it online!
$endgroup$
$begingroup$
Save a byte by dropping thex
variable: Try it online!
$endgroup$
– benj2240
3 hours ago
add a comment |
$begingroup$
Ruby, 35 bytes
->n,s=0{s+=x=1+rand(n);x<n||redo;s}
Try it online!
$endgroup$
Ruby, 35 bytes
->n,s=0{s+=x=1+rand(n);x<n||redo;s}
Try it online!
answered 8 hours ago
iamnotmaynardiamnotmaynard
95349
95349
$begingroup$
Save a byte by dropping thex
variable: Try it online!
$endgroup$
– benj2240
3 hours ago
add a comment |
$begingroup$
Save a byte by dropping thex
variable: Try it online!
$endgroup$
– benj2240
3 hours ago
$begingroup$
Save a byte by dropping the
x
variable: Try it online!$endgroup$
– benj2240
3 hours ago
$begingroup$
Save a byte by dropping the
x
variable: Try it online!$endgroup$
– benj2240
3 hours ago
add a comment |
$begingroup$
Python 3, 81 72 bytes
from random import*
def f(x,a=0):
while a%x<1:a+=randint(1,x)
return a
Try it online!
-9 bytes thanks to ArBo
Explanation
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
$endgroup$
$begingroup$
You can save 1 byte by usingfrom random import*
instead.
$endgroup$
– orthoplex
10 hours ago
1
$begingroup$
You can get this down to 74 bytes using this recursive solution
$endgroup$
– squid
10 hours ago
1
$begingroup$
@squid You can save 1 byte like this.
$endgroup$
– orthoplex
9 hours ago
1
$begingroup$
@orthoplex and then you can shorten the if/else, and make it a one-liner. Starts to look like my solution then ;)
$endgroup$
– ArBo
9 hours ago
1
$begingroup$
@ArBo Yea that's why I didn't change to recursive, didn't want to just copy you.
$endgroup$
– Artemis Fowl
8 hours ago
|
show 3 more comments
$begingroup$
Python 3, 81 72 bytes
from random import*
def f(x,a=0):
while a%x<1:a+=randint(1,x)
return a
Try it online!
-9 bytes thanks to ArBo
Explanation
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
$endgroup$
$begingroup$
You can save 1 byte by usingfrom random import*
instead.
$endgroup$
– orthoplex
10 hours ago
1
$begingroup$
You can get this down to 74 bytes using this recursive solution
$endgroup$
– squid
10 hours ago
1
$begingroup$
@squid You can save 1 byte like this.
$endgroup$
– orthoplex
9 hours ago
1
$begingroup$
@orthoplex and then you can shorten the if/else, and make it a one-liner. Starts to look like my solution then ;)
$endgroup$
– ArBo
9 hours ago
1
$begingroup$
@ArBo Yea that's why I didn't change to recursive, didn't want to just copy you.
$endgroup$
– Artemis Fowl
8 hours ago
|
show 3 more comments
$begingroup$
Python 3, 81 72 bytes
from random import*
def f(x,a=0):
while a%x<1:a+=randint(1,x)
return a
Try it online!
-9 bytes thanks to ArBo
Explanation
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
$endgroup$
Python 3, 81 72 bytes
from random import*
def f(x,a=0):
while a%x<1:a+=randint(1,x)
return a
Try it online!
-9 bytes thanks to ArBo
Explanation
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
edited 2 hours ago
answered 11 hours ago
Artemis FowlArtemis Fowl
26111
26111
$begingroup$
You can save 1 byte by usingfrom random import*
instead.
$endgroup$
– orthoplex
10 hours ago
1
$begingroup$
You can get this down to 74 bytes using this recursive solution
$endgroup$
– squid
10 hours ago
1
$begingroup$
@squid You can save 1 byte like this.
$endgroup$
– orthoplex
9 hours ago
1
$begingroup$
@orthoplex and then you can shorten the if/else, and make it a one-liner. Starts to look like my solution then ;)
$endgroup$
– ArBo
9 hours ago
1
$begingroup$
@ArBo Yea that's why I didn't change to recursive, didn't want to just copy you.
$endgroup$
– Artemis Fowl
8 hours ago
|
show 3 more comments
$begingroup$
You can save 1 byte by usingfrom random import*
instead.
$endgroup$
– orthoplex
10 hours ago
1
$begingroup$
You can get this down to 74 bytes using this recursive solution
$endgroup$
– squid
10 hours ago
1
$begingroup$
@squid You can save 1 byte like this.
$endgroup$
– orthoplex
9 hours ago
1
$begingroup$
@orthoplex and then you can shorten the if/else, and make it a one-liner. Starts to look like my solution then ;)
$endgroup$
– ArBo
9 hours ago
1
$begingroup$
@ArBo Yea that's why I didn't change to recursive, didn't want to just copy you.
$endgroup$
– Artemis Fowl
8 hours ago
$begingroup$
You can save 1 byte by using
from random import*
instead.$endgroup$
– orthoplex
10 hours ago
$begingroup$
You can save 1 byte by using
from random import*
instead.$endgroup$
– orthoplex
10 hours ago
1
1
$begingroup$
You can get this down to 74 bytes using this recursive solution
$endgroup$
– squid
10 hours ago
$begingroup$
You can get this down to 74 bytes using this recursive solution
$endgroup$
– squid
10 hours ago
1
1
$begingroup$
@squid You can save 1 byte like this.
$endgroup$
– orthoplex
9 hours ago
$begingroup$
@squid You can save 1 byte like this.
$endgroup$
– orthoplex
9 hours ago
1
1
$begingroup$
@orthoplex and then you can shorten the if/else, and make it a one-liner. Starts to look like my solution then ;)
$endgroup$
– ArBo
9 hours ago
$begingroup$
@orthoplex and then you can shorten the if/else, and make it a one-liner. Starts to look like my solution then ;)
$endgroup$
– ArBo
9 hours ago
1
1
$begingroup$
@ArBo Yea that's why I didn't change to recursive, didn't want to just copy you.
$endgroup$
– Artemis Fowl
8 hours ago
$begingroup$
@ArBo Yea that's why I didn't change to recursive, didn't want to just copy you.
$endgroup$
– Artemis Fowl
8 hours ago
|
show 3 more comments
$begingroup$
JavaScript (ES6), 39 bytes
f=n=>(x=Math.random()*n+1|0)<n?x:x+f(n)
Try it online! or See the distribution for n=4
$endgroup$
add a comment |
$begingroup$
JavaScript (ES6), 39 bytes
f=n=>(x=Math.random()*n+1|0)<n?x:x+f(n)
Try it online! or See the distribution for n=4
$endgroup$
add a comment |
$begingroup$
JavaScript (ES6), 39 bytes
f=n=>(x=Math.random()*n+1|0)<n?x:x+f(n)
Try it online! or See the distribution for n=4
$endgroup$
JavaScript (ES6), 39 bytes
f=n=>(x=Math.random()*n+1|0)<n?x:x+f(n)
Try it online! or See the distribution for n=4
answered 11 hours ago
ArnauldArnauld
80.9k797334
80.9k797334
add a comment |
add a comment |
$begingroup$
><>, 90 bytes
0& v
v:::< <
v/1>{1-:?!v}
>x0^v10~ <
^
5=?v>:@}}*{+{2*l
&n;>,*:1%-1+:&+&=?^
Try it online!
The whitespace on the second line is bugging me. I'll work on golfing that out.
><>
doesn't have a nice method for producing uniform random integers. This approach generates, for input $N$, a random number produced by generating $N$ random bits, then taking the resulting binary integer and dividing it by $2^N$. This process is repeated until $N$ is not generated by this process.
$endgroup$
$begingroup$
Compression to 72 bytes.
$endgroup$
– Jo King
1 hour ago
add a comment |
$begingroup$
><>, 90 bytes
0& v
v:::< <
v/1>{1-:?!v}
>x0^v10~ <
^
5=?v>:@}}*{+{2*l
&n;>,*:1%-1+:&+&=?^
Try it online!
The whitespace on the second line is bugging me. I'll work on golfing that out.
><>
doesn't have a nice method for producing uniform random integers. This approach generates, for input $N$, a random number produced by generating $N$ random bits, then taking the resulting binary integer and dividing it by $2^N$. This process is repeated until $N$ is not generated by this process.
$endgroup$
$begingroup$
Compression to 72 bytes.
$endgroup$
– Jo King
1 hour ago
add a comment |
$begingroup$
><>, 90 bytes
0& v
v:::< <
v/1>{1-:?!v}
>x0^v10~ <
^
5=?v>:@}}*{+{2*l
&n;>,*:1%-1+:&+&=?^
Try it online!
The whitespace on the second line is bugging me. I'll work on golfing that out.
><>
doesn't have a nice method for producing uniform random integers. This approach generates, for input $N$, a random number produced by generating $N$ random bits, then taking the resulting binary integer and dividing it by $2^N$. This process is repeated until $N$ is not generated by this process.
$endgroup$
><>, 90 bytes
0& v
v:::< <
v/1>{1-:?!v}
>x0^v10~ <
^
5=?v>:@}}*{+{2*l
&n;>,*:1%-1+:&+&=?^
Try it online!
The whitespace on the second line is bugging me. I'll work on golfing that out.
><>
doesn't have a nice method for producing uniform random integers. This approach generates, for input $N$, a random number produced by generating $N$ random bits, then taking the resulting binary integer and dividing it by $2^N$. This process is repeated until $N$ is not generated by this process.
answered 9 hours ago
Conor O'BrienConor O'Brien
30.7k264162
30.7k264162
$begingroup$
Compression to 72 bytes.
$endgroup$
– Jo King
1 hour ago
add a comment |
$begingroup$
Compression to 72 bytes.
$endgroup$
– Jo King
1 hour ago
$begingroup$
Compression to 72 bytes.
$endgroup$
– Jo King
1 hour ago
$begingroup$
Compression to 72 bytes.
$endgroup$
– Jo King
1 hour ago
add a comment |
$begingroup$
Attache, 30 bytes
f:=${If[x=y,f@x+y,y]}#1&Random
Try it online!
Direct implementation of the process.
Alternatives
36 bytes: ${NestWhile[{_+Random[1,x]},x&`|,0]}
37 bytes: ${NestWhile[{_+Random[1,x]},{x|_},0]}
$endgroup$
add a comment |
$begingroup$
Attache, 30 bytes
f:=${If[x=y,f@x+y,y]}#1&Random
Try it online!
Direct implementation of the process.
Alternatives
36 bytes: ${NestWhile[{_+Random[1,x]},x&`|,0]}
37 bytes: ${NestWhile[{_+Random[1,x]},{x|_},0]}
$endgroup$
add a comment |
$begingroup$
Attache, 30 bytes
f:=${If[x=y,f@x+y,y]}#1&Random
Try it online!
Direct implementation of the process.
Alternatives
36 bytes: ${NestWhile[{_+Random[1,x]},x&`|,0]}
37 bytes: ${NestWhile[{_+Random[1,x]},{x|_},0]}
$endgroup$
Attache, 30 bytes
f:=${If[x=y,f@x+y,y]}#1&Random
Try it online!
Direct implementation of the process.
Alternatives
36 bytes: ${NestWhile[{_+Random[1,x]},x&`|,0]}
37 bytes: ${NestWhile[{_+Random[1,x]},{x|_},0]}
answered 9 hours ago
Conor O'BrienConor O'Brien
30.7k264162
30.7k264162
add a comment |
add a comment |
$begingroup$
C (gcc), 36 bytes
f(n,x){x=rand()%n+1;x=x-n?x:x+f(n);}
Try it online!
Here a Test with 100k d4
$endgroup$
1
$begingroup$
Shouldn'tsrand(time(0))
be included in the byte count? AFAIKrand()
will always return the same value if it was never seeded
$endgroup$
– Tau
9 hours ago
1
$begingroup$
I'm not entirely sure, but I remember the meta consensus being that using an unseed PRNG is acceptable @Tau
$endgroup$
– Conor O'Brien
9 hours ago
$begingroup$
@ConorO'Brien i was looking on the meta and i found this: codegolf.meta.stackexchange.com/questions/15025/…
$endgroup$
– Giacomo Garabello
9 hours ago
$begingroup$
@GiacomoGarabello I'm 100% ok with a non-seeded PRNG, and it's allowed by our rules on randomness I believe.
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
add a comment |
$begingroup$
C (gcc), 36 bytes
f(n,x){x=rand()%n+1;x=x-n?x:x+f(n);}
Try it online!
Here a Test with 100k d4
$endgroup$
1
$begingroup$
Shouldn'tsrand(time(0))
be included in the byte count? AFAIKrand()
will always return the same value if it was never seeded
$endgroup$
– Tau
9 hours ago
1
$begingroup$
I'm not entirely sure, but I remember the meta consensus being that using an unseed PRNG is acceptable @Tau
$endgroup$
– Conor O'Brien
9 hours ago
$begingroup$
@ConorO'Brien i was looking on the meta and i found this: codegolf.meta.stackexchange.com/questions/15025/…
$endgroup$
– Giacomo Garabello
9 hours ago
$begingroup$
@GiacomoGarabello I'm 100% ok with a non-seeded PRNG, and it's allowed by our rules on randomness I believe.
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
add a comment |
$begingroup$
C (gcc), 36 bytes
f(n,x){x=rand()%n+1;x=x-n?x:x+f(n);}
Try it online!
Here a Test with 100k d4
$endgroup$
C (gcc), 36 bytes
f(n,x){x=rand()%n+1;x=x-n?x:x+f(n);}
Try it online!
Here a Test with 100k d4
edited 9 hours ago
answered 9 hours ago
Giacomo GarabelloGiacomo Garabello
1,439417
1,439417
1
$begingroup$
Shouldn'tsrand(time(0))
be included in the byte count? AFAIKrand()
will always return the same value if it was never seeded
$endgroup$
– Tau
9 hours ago
1
$begingroup$
I'm not entirely sure, but I remember the meta consensus being that using an unseed PRNG is acceptable @Tau
$endgroup$
– Conor O'Brien
9 hours ago
$begingroup$
@ConorO'Brien i was looking on the meta and i found this: codegolf.meta.stackexchange.com/questions/15025/…
$endgroup$
– Giacomo Garabello
9 hours ago
$begingroup$
@GiacomoGarabello I'm 100% ok with a non-seeded PRNG, and it's allowed by our rules on randomness I believe.
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
add a comment |
1
$begingroup$
Shouldn'tsrand(time(0))
be included in the byte count? AFAIKrand()
will always return the same value if it was never seeded
$endgroup$
– Tau
9 hours ago
1
$begingroup$
I'm not entirely sure, but I remember the meta consensus being that using an unseed PRNG is acceptable @Tau
$endgroup$
– Conor O'Brien
9 hours ago
$begingroup$
@ConorO'Brien i was looking on the meta and i found this: codegolf.meta.stackexchange.com/questions/15025/…
$endgroup$
– Giacomo Garabello
9 hours ago
$begingroup$
@GiacomoGarabello I'm 100% ok with a non-seeded PRNG, and it's allowed by our rules on randomness I believe.
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
1
1
$begingroup$
Shouldn't
srand(time(0))
be included in the byte count? AFAIK rand()
will always return the same value if it was never seeded$endgroup$
– Tau
9 hours ago
$begingroup$
Shouldn't
srand(time(0))
be included in the byte count? AFAIK rand()
will always return the same value if it was never seeded$endgroup$
– Tau
9 hours ago
1
1
$begingroup$
I'm not entirely sure, but I remember the meta consensus being that using an unseed PRNG is acceptable @Tau
$endgroup$
– Conor O'Brien
9 hours ago
$begingroup$
I'm not entirely sure, but I remember the meta consensus being that using an unseed PRNG is acceptable @Tau
$endgroup$
– Conor O'Brien
9 hours ago
$begingroup$
@ConorO'Brien i was looking on the meta and i found this: codegolf.meta.stackexchange.com/questions/15025/…
$endgroup$
– Giacomo Garabello
9 hours ago
$begingroup$
@ConorO'Brien i was looking on the meta and i found this: codegolf.meta.stackexchange.com/questions/15025/…
$endgroup$
– Giacomo Garabello
9 hours ago
$begingroup$
@GiacomoGarabello I'm 100% ok with a non-seeded PRNG, and it's allowed by our rules on randomness I believe.
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
$begingroup$
@GiacomoGarabello I'm 100% ok with a non-seeded PRNG, and it's allowed by our rules on randomness I believe.
$endgroup$
– Rɪᴋᴇʀ
3 hours ago
add a comment |
$begingroup$
Excel VBA, 108 bytes
Function z(i)
v = Int((i * Rnd) + 1)
z = v
Do While v = i
v = Int((i * Rnd) + 1)
z = z + v
Loop
End Function
$endgroup$
add a comment |
$begingroup$
Excel VBA, 108 bytes
Function z(i)
v = Int((i * Rnd) + 1)
z = v
Do While v = i
v = Int((i * Rnd) + 1)
z = z + v
Loop
End Function
$endgroup$
add a comment |
$begingroup$
Excel VBA, 108 bytes
Function z(i)
v = Int((i * Rnd) + 1)
z = v
Do While v = i
v = Int((i * Rnd) + 1)
z = z + v
Loop
End Function
$endgroup$
Excel VBA, 108 bytes
Function z(i)
v = Int((i * Rnd) + 1)
z = v
Do While v = i
v = Int((i * Rnd) + 1)
z = z + v
Loop
End Function
answered 8 hours ago
william porterwilliam porter
1515
1515
add a comment |
add a comment |
$begingroup$
Perl 6, 26 bytes
{[+] {^$_ .roll+1}...$_>*}
Try it online!
$endgroup$
add a comment |
$begingroup$
Perl 6, 26 bytes
{[+] {^$_ .roll+1}...$_>*}
Try it online!
$endgroup$
add a comment |
$begingroup$
Perl 6, 26 bytes
{[+] {^$_ .roll+1}...$_>*}
Try it online!
$endgroup$
Perl 6, 26 bytes
{[+] {^$_ .roll+1}...$_>*}
Try it online!
answered 8 hours ago
bb94bb94
1,065611
1,065611
add a comment |
add a comment |
$begingroup$
Python 3, 80 bytes
This is pretty much just a tail-call recursive version of @Artemis Fowl's answer, but I liked doing it without unrolling into a while loop.
Uses an accumulator parameter to return the total rolled value once the exploding stops.
from random import*
def r(n,a=0):v=randint(1,n);a+=v;return r(n,a)if v==n else a
$endgroup$
add a comment |
$begingroup$
Python 3, 80 bytes
This is pretty much just a tail-call recursive version of @Artemis Fowl's answer, but I liked doing it without unrolling into a while loop.
Uses an accumulator parameter to return the total rolled value once the exploding stops.
from random import*
def r(n,a=0):v=randint(1,n);a+=v;return r(n,a)if v==n else a
$endgroup$
add a comment |
$begingroup$
Python 3, 80 bytes
This is pretty much just a tail-call recursive version of @Artemis Fowl's answer, but I liked doing it without unrolling into a while loop.
Uses an accumulator parameter to return the total rolled value once the exploding stops.
from random import*
def r(n,a=0):v=randint(1,n);a+=v;return r(n,a)if v==n else a
$endgroup$
Python 3, 80 bytes
This is pretty much just a tail-call recursive version of @Artemis Fowl's answer, but I liked doing it without unrolling into a while loop.
Uses an accumulator parameter to return the total rolled value once the exploding stops.
from random import*
def r(n,a=0):v=randint(1,n);a+=v;return r(n,a)if v==n else a
answered 8 hours ago
Delya ErricsonDelya Erricson
6113
6113
add a comment |
add a comment |
$begingroup$
PowerShell, 49 bytes
for($a=$l="$args";$a-eq$l){$o+=$l=1..$a|Random}$o
Try it online!
Iterative method. Sets the input $args
to $a
and the $l
ast roll (done so we enter the loop at least once). Then, so long as the last roll is -eq
ual to the input, we keep rolling. Inside the loop we accumulate into $o
the last roll, which is updated by creating a range from 1
to input $a
and picking a Random
element thereof. (Honestly, I'm a little surprised that $o+=$l=
works.) Once we're out of the loop, we leave $o
on the pipeline and output is implicit.
$endgroup$
add a comment |
$begingroup$
PowerShell, 49 bytes
for($a=$l="$args";$a-eq$l){$o+=$l=1..$a|Random}$o
Try it online!
Iterative method. Sets the input $args
to $a
and the $l
ast roll (done so we enter the loop at least once). Then, so long as the last roll is -eq
ual to the input, we keep rolling. Inside the loop we accumulate into $o
the last roll, which is updated by creating a range from 1
to input $a
and picking a Random
element thereof. (Honestly, I'm a little surprised that $o+=$l=
works.) Once we're out of the loop, we leave $o
on the pipeline and output is implicit.
$endgroup$
add a comment |
$begingroup$
PowerShell, 49 bytes
for($a=$l="$args";$a-eq$l){$o+=$l=1..$a|Random}$o
Try it online!
Iterative method. Sets the input $args
to $a
and the $l
ast roll (done so we enter the loop at least once). Then, so long as the last roll is -eq
ual to the input, we keep rolling. Inside the loop we accumulate into $o
the last roll, which is updated by creating a range from 1
to input $a
and picking a Random
element thereof. (Honestly, I'm a little surprised that $o+=$l=
works.) Once we're out of the loop, we leave $o
on the pipeline and output is implicit.
$endgroup$
PowerShell, 49 bytes
for($a=$l="$args";$a-eq$l){$o+=$l=1..$a|Random}$o
Try it online!
Iterative method. Sets the input $args
to $a
and the $l
ast roll (done so we enter the loop at least once). Then, so long as the last roll is -eq
ual to the input, we keep rolling. Inside the loop we accumulate into $o
the last roll, which is updated by creating a range from 1
to input $a
and picking a Random
element thereof. (Honestly, I'm a little surprised that $o+=$l=
works.) Once we're out of the loop, we leave $o
on the pipeline and output is implicit.
answered 8 hours ago
AdmBorkBorkAdmBorkBork
27.9k467241
27.9k467241
add a comment |
add a comment |
$begingroup$
Forth (gforth), 72 bytes
include random.fs
: f >r 0 begin i random 1+ >r i + r> i < until rdrop ;
Try it online!
Code Explanation
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
$endgroup$
add a comment |
$begingroup$
Forth (gforth), 72 bytes
include random.fs
: f >r 0 begin i random 1+ >r i + r> i < until rdrop ;
Try it online!
Code Explanation
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
$endgroup$
add a comment |
$begingroup$
Forth (gforth), 72 bytes
include random.fs
: f >r 0 begin i random 1+ >r i + r> i < until rdrop ;
Try it online!
Code Explanation
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
$endgroup$
Forth (gforth), 72 bytes
include random.fs
: f >r 0 begin i random 1+ >r i + r> i < until rdrop ;
Try it online!
Code Explanation
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
edited 7 hours ago
answered 11 hours ago
reffureffu
73126
73126
add a comment |
add a comment |
$begingroup$
Charcoal, 17 bytes
NθW⁼Lυ№υθ⊞υ⊕‽θIΣυ
Try it online! Link is to verbose version of code. Explanation:
Nθ
Input n
.
W⁼Lυ№υθ
Repeat while the predefined empty list only contains n
s (i.e. its length equals its count of n
s)...
⊞υ⊕‽θ
... push a random integer from 1
to n
to the list.
IΣυ
Print the total.
$endgroup$
add a comment |
$begingroup$
Charcoal, 17 bytes
NθW⁼Lυ№υθ⊞υ⊕‽θIΣυ
Try it online! Link is to verbose version of code. Explanation:
Nθ
Input n
.
W⁼Lυ№υθ
Repeat while the predefined empty list only contains n
s (i.e. its length equals its count of n
s)...
⊞υ⊕‽θ
... push a random integer from 1
to n
to the list.
IΣυ
Print the total.
$endgroup$
add a comment |
$begingroup$
Charcoal, 17 bytes
NθW⁼Lυ№υθ⊞υ⊕‽θIΣυ
Try it online! Link is to verbose version of code. Explanation:
Nθ
Input n
.
W⁼Lυ№υθ
Repeat while the predefined empty list only contains n
s (i.e. its length equals its count of n
s)...
⊞υ⊕‽θ
... push a random integer from 1
to n
to the list.
IΣυ
Print the total.
$endgroup$
Charcoal, 17 bytes
NθW⁼Lυ№υθ⊞υ⊕‽θIΣυ
Try it online! Link is to verbose version of code. Explanation:
Nθ
Input n
.
W⁼Lυ№υθ
Repeat while the predefined empty list only contains n
s (i.e. its length equals its count of n
s)...
⊞υ⊕‽θ
... push a random integer from 1
to n
to the list.
IΣυ
Print the total.
answered 7 hours ago
NeilNeil
82.8k745179
82.8k745179
add a comment |
add a comment |
$begingroup$
Batch, 70 bytes
@set t=0
:g
@set/at+=d=%random%%%%1+1
@if %d%==%1 goto g
@echo %t%
Takes input n
as a command-line parameter %1
. d
is the current roll, t
the cumulative total. Simply keeps rolling until d
is not equal to n
.
$endgroup$
add a comment |
$begingroup$
Batch, 70 bytes
@set t=0
:g
@set/at+=d=%random%%%%1+1
@if %d%==%1 goto g
@echo %t%
Takes input n
as a command-line parameter %1
. d
is the current roll, t
the cumulative total. Simply keeps rolling until d
is not equal to n
.
$endgroup$
add a comment |
$begingroup$
Batch, 70 bytes
@set t=0
:g
@set/at+=d=%random%%%%1+1
@if %d%==%1 goto g
@echo %t%
Takes input n
as a command-line parameter %1
. d
is the current roll, t
the cumulative total. Simply keeps rolling until d
is not equal to n
.
$endgroup$
Batch, 70 bytes
@set t=0
:g
@set/at+=d=%random%%%%1+1
@if %d%==%1 goto g
@echo %t%
Takes input n
as a command-line parameter %1
. d
is the current roll, t
the cumulative total. Simply keeps rolling until d
is not equal to n
.
answered 7 hours ago
NeilNeil
82.8k745179
82.8k745179
add a comment |
add a comment |
$begingroup$
Jelly, 9 bytes
x⁹X€Ä%ƇµḢ
Try it online!
A monadic link that takes n as its argument and returns a number generated by an exploding n-sided die. This generates 256 numbers from 1 to n and returns the first cumulative sum that is not a multiple of n. In theory this could return 256n, but even for a 2-sided die this would happen only one every $2^{256}$ times.
An alternative that doesn’t have this limitation is:
Jelly, 10 bytes
X³X¤+¥³ḍ¥¿
Try it online!
Note both TIO links generate 400 numbers to show the distribution.
$endgroup$
add a comment |
$begingroup$
Jelly, 9 bytes
x⁹X€Ä%ƇµḢ
Try it online!
A monadic link that takes n as its argument and returns a number generated by an exploding n-sided die. This generates 256 numbers from 1 to n and returns the first cumulative sum that is not a multiple of n. In theory this could return 256n, but even for a 2-sided die this would happen only one every $2^{256}$ times.
An alternative that doesn’t have this limitation is:
Jelly, 10 bytes
X³X¤+¥³ḍ¥¿
Try it online!
Note both TIO links generate 400 numbers to show the distribution.
$endgroup$
add a comment |
$begingroup$
Jelly, 9 bytes
x⁹X€Ä%ƇµḢ
Try it online!
A monadic link that takes n as its argument and returns a number generated by an exploding n-sided die. This generates 256 numbers from 1 to n and returns the first cumulative sum that is not a multiple of n. In theory this could return 256n, but even for a 2-sided die this would happen only one every $2^{256}$ times.
An alternative that doesn’t have this limitation is:
Jelly, 10 bytes
X³X¤+¥³ḍ¥¿
Try it online!
Note both TIO links generate 400 numbers to show the distribution.
$endgroup$
Jelly, 9 bytes
x⁹X€Ä%ƇµḢ
Try it online!
A monadic link that takes n as its argument and returns a number generated by an exploding n-sided die. This generates 256 numbers from 1 to n and returns the first cumulative sum that is not a multiple of n. In theory this could return 256n, but even for a 2-sided die this would happen only one every $2^{256}$ times.
An alternative that doesn’t have this limitation is:
Jelly, 10 bytes
X³X¤+¥³ḍ¥¿
Try it online!
Note both TIO links generate 400 numbers to show the distribution.
answered 6 hours ago
Nick KennedyNick Kennedy
1,53649
1,53649
add a comment |
add a comment |
$begingroup$
C# (Visual C# Interactive Compiler), 60 bytes
int f(int n,int k=1)=>(k=new Random().Next(n)+1)<n?k:k+f(n);
Saved 4 bytes thanks to @ExpiredData!
Try it online!
$endgroup$
$begingroup$
60 bytes
$endgroup$
– Expired Data
6 hours ago
$begingroup$
@ExpiredData Using new Random() gives it the same seed if you call it again, which doesn't make it truly random
$endgroup$
– Embodiment of Ignorance
5 hours ago
$begingroup$
Nah it's a new seed, run my tio a few times. But even if it was same seed random() isn't true random anyway it's a prng....
$endgroup$
– Expired Data
5 hours ago
add a comment |
$begingroup$
C# (Visual C# Interactive Compiler), 60 bytes
int f(int n,int k=1)=>(k=new Random().Next(n)+1)<n?k:k+f(n);
Saved 4 bytes thanks to @ExpiredData!
Try it online!
$endgroup$
$begingroup$
60 bytes
$endgroup$
– Expired Data
6 hours ago
$begingroup$
@ExpiredData Using new Random() gives it the same seed if you call it again, which doesn't make it truly random
$endgroup$
– Embodiment of Ignorance
5 hours ago
$begingroup$
Nah it's a new seed, run my tio a few times. But even if it was same seed random() isn't true random anyway it's a prng....
$endgroup$
– Expired Data
5 hours ago
add a comment |
$begingroup$
C# (Visual C# Interactive Compiler), 60 bytes
int f(int n,int k=1)=>(k=new Random().Next(n)+1)<n?k:k+f(n);
Saved 4 bytes thanks to @ExpiredData!
Try it online!
$endgroup$
C# (Visual C# Interactive Compiler), 60 bytes
int f(int n,int k=1)=>(k=new Random().Next(n)+1)<n?k:k+f(n);
Saved 4 bytes thanks to @ExpiredData!
Try it online!
edited 5 hours ago
answered 6 hours ago
Embodiment of IgnoranceEmbodiment of Ignorance
2,956127
2,956127
$begingroup$
60 bytes
$endgroup$
– Expired Data
6 hours ago
$begingroup$
@ExpiredData Using new Random() gives it the same seed if you call it again, which doesn't make it truly random
$endgroup$
– Embodiment of Ignorance
5 hours ago
$begingroup$
Nah it's a new seed, run my tio a few times. But even if it was same seed random() isn't true random anyway it's a prng....
$endgroup$
– Expired Data
5 hours ago
add a comment |
$begingroup$
60 bytes
$endgroup$
– Expired Data
6 hours ago
$begingroup$
@ExpiredData Using new Random() gives it the same seed if you call it again, which doesn't make it truly random
$endgroup$
– Embodiment of Ignorance
5 hours ago
$begingroup$
Nah it's a new seed, run my tio a few times. But even if it was same seed random() isn't true random anyway it's a prng....
$endgroup$
– Expired Data
5 hours ago
$begingroup$
60 bytes
$endgroup$
– Expired Data
6 hours ago
$begingroup$
60 bytes
$endgroup$
– Expired Data
6 hours ago
$begingroup$
@ExpiredData Using new Random() gives it the same seed if you call it again, which doesn't make it truly random
$endgroup$
– Embodiment of Ignorance
5 hours ago
$begingroup$
@ExpiredData Using new Random() gives it the same seed if you call it again, which doesn't make it truly random
$endgroup$
– Embodiment of Ignorance
5 hours ago
$begingroup$
Nah it's a new seed, run my tio a few times. But even if it was same seed random() isn't true random anyway it's a prng....
$endgroup$
– Expired Data
5 hours ago
$begingroup$
Nah it's a new seed, run my tio a few times. But even if it was same seed random() isn't true random anyway it's a prng....
$endgroup$
– Expired Data
5 hours ago
add a comment |
$begingroup$
Haskell, 77 76 bytes
import System.Random
f x=randomRIO(1,x)>>=(x!)
x!y|y<x=pure y|0<1=(y+)<$>f x
Try it online!
Thanks to killmous for one byte.
$endgroup$
$begingroup$
You can save a byte if you define g as an infix function.
$endgroup$
– killmous
6 hours ago
$begingroup$
@killmous, thanks. At first glance I figured that would be the same or worse, but it's better.
$endgroup$
– dfeuer
4 hours ago
add a comment |
$begingroup$
Haskell, 77 76 bytes
import System.Random
f x=randomRIO(1,x)>>=(x!)
x!y|y<x=pure y|0<1=(y+)<$>f x
Try it online!
Thanks to killmous for one byte.
$endgroup$
$begingroup$
You can save a byte if you define g as an infix function.
$endgroup$
– killmous
6 hours ago
$begingroup$
@killmous, thanks. At first glance I figured that would be the same or worse, but it's better.
$endgroup$
– dfeuer
4 hours ago
add a comment |
$begingroup$
Haskell, 77 76 bytes
import System.Random
f x=randomRIO(1,x)>>=(x!)
x!y|y<x=pure y|0<1=(y+)<$>f x
Try it online!
Thanks to killmous for one byte.
$endgroup$
Haskell, 77 76 bytes
import System.Random
f x=randomRIO(1,x)>>=(x!)
x!y|y<x=pure y|0<1=(y+)<$>f x
Try it online!
Thanks to killmous for one byte.
edited 4 hours ago
answered 8 hours ago
dfeuerdfeuer
9161011
9161011
$begingroup$
You can save a byte if you define g as an infix function.
$endgroup$
– killmous
6 hours ago
$begingroup$
@killmous, thanks. At first glance I figured that would be the same or worse, but it's better.
$endgroup$
– dfeuer
4 hours ago
add a comment |
$begingroup$
You can save a byte if you define g as an infix function.
$endgroup$
– killmous
6 hours ago
$begingroup$
@killmous, thanks. At first glance I figured that would be the same or worse, but it's better.
$endgroup$
– dfeuer
4 hours ago
$begingroup$
You can save a byte if you define g as an infix function.
$endgroup$
– killmous
6 hours ago
$begingroup$
You can save a byte if you define g as an infix function.
$endgroup$
– killmous
6 hours ago
$begingroup$
@killmous, thanks. At first glance I figured that would be the same or worse, but it's better.
$endgroup$
– dfeuer
4 hours ago
$begingroup$
@killmous, thanks. At first glance I figured that would be the same or worse, but it's better.
$endgroup$
– dfeuer
4 hours ago
add a comment |
$begingroup$
Haskell, 94 bytes
import System.Random
f n=do
i<-randomRIO(1,n)
if i<n
then return i
else (i+)<$>f n
Try it online!
Quite similar to @dfeur's, but using do
notation.
New contributor
$endgroup$
add a comment |
$begingroup$
Haskell, 94 bytes
import System.Random
f n=do
i<-randomRIO(1,n)
if i<n
then return i
else (i+)<$>f n
Try it online!
Quite similar to @dfeur's, but using do
notation.
New contributor
$endgroup$
add a comment |
$begingroup$
Haskell, 94 bytes
import System.Random
f n=do
i<-randomRIO(1,n)
if i<n
then return i
else (i+)<$>f n
Try it online!
Quite similar to @dfeur's, but using do
notation.
New contributor
$endgroup$
Haskell, 94 bytes
import System.Random
f n=do
i<-randomRIO(1,n)
if i<n
then return i
else (i+)<$>f n
Try it online!
Quite similar to @dfeur's, but using do
notation.
New contributor
edited 3 hours ago
New contributor
answered 8 hours ago
bugsbugs
1314
1314
New contributor
New contributor
add a comment |
add a comment |
$begingroup$
perl -Minteger -pe, 34 bytes
$s+=1+rand$_;$s%$_||redo;$_=$s
$endgroup$
add a comment |
$begingroup$
perl -Minteger -pe, 34 bytes
$s+=1+rand$_;$s%$_||redo;$_=$s
$endgroup$
add a comment |
$begingroup$
perl -Minteger -pe, 34 bytes
$s+=1+rand$_;$s%$_||redo;$_=$s
$endgroup$
perl -Minteger -pe, 34 bytes
$s+=1+rand$_;$s%$_||redo;$_=$s
answered 2 hours ago
AbigailAbigail
45617
45617
add a comment |
add a comment |
$begingroup$
TI-BASIC, 28 23 bytes
-5 bytes thanks to this meta post!
Ans→N:0:Repeat fPart(Ans/N:Ans+randInt(1,N:End:Ans
Input is in Ans
.
Output is in Ans
and is implicitly printed.
Examples:
4
4
prgmCDGF11
5
6
6
prgmCDGF11
3
Explanation:
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"
Notes:
- TI-BASIC is a tokenized language. Character count does not equal byte count.
$endgroup$
$begingroup$
SincestartTmr
is no longer necessary, this submission will now work for versions of TI-BASIC earlier than the TI-84+
$endgroup$
– Tau
1 hour ago
add a comment |
$begingroup$
TI-BASIC, 28 23 bytes
-5 bytes thanks to this meta post!
Ans→N:0:Repeat fPart(Ans/N:Ans+randInt(1,N:End:Ans
Input is in Ans
.
Output is in Ans
and is implicitly printed.
Examples:
4
4
prgmCDGF11
5
6
6
prgmCDGF11
3
Explanation:
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"
Notes:
- TI-BASIC is a tokenized language. Character count does not equal byte count.
$endgroup$
$begingroup$
SincestartTmr
is no longer necessary, this submission will now work for versions of TI-BASIC earlier than the TI-84+
$endgroup$
– Tau
1 hour ago
add a comment |
$begingroup$
TI-BASIC, 28 23 bytes
-5 bytes thanks to this meta post!
Ans→N:0:Repeat fPart(Ans/N:Ans+randInt(1,N:End:Ans
Input is in Ans
.
Output is in Ans
and is implicitly printed.
Examples:
4
4
prgmCDGF11
5
6
6
prgmCDGF11
3
Explanation:
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"
Notes:
- TI-BASIC is a tokenized language. Character count does not equal byte count.
$endgroup$
TI-BASIC, 28 23 bytes
-5 bytes thanks to this meta post!
Ans→N:0:Repeat fPart(Ans/N:Ans+randInt(1,N:End:Ans
Input is in Ans
.
Output is in Ans
and is implicitly printed.
Examples:
4
4
prgmCDGF11
5
6
6
prgmCDGF11
3
Explanation:
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"
Notes:
- TI-BASIC is a tokenized language. Character count does not equal byte count.
edited 1 hour ago
answered 10 hours ago
TauTau
1,043519
1,043519
$begingroup$
SincestartTmr
is no longer necessary, this submission will now work for versions of TI-BASIC earlier than the TI-84+
$endgroup$
– Tau
1 hour ago
add a comment |
$begingroup$
SincestartTmr
is no longer necessary, this submission will now work for versions of TI-BASIC earlier than the TI-84+
$endgroup$
– Tau
1 hour ago
$begingroup$
Since
startTmr
is no longer necessary, this submission will now work for versions of TI-BASIC earlier than the TI-84+$endgroup$
– Tau
1 hour ago
$begingroup$
Since
startTmr
is no longer necessary, this submission will now work for versions of TI-BASIC earlier than the TI-84+$endgroup$
– Tau
1 hour ago
add a comment |
$begingroup$
Jelly, 7 bytes
X+ß}¥=¡
Try it online!
Uses recursion. Runs the program again (ß
) and adds (+
) if (¡
) the random number (X
) is equal (=
) to the program input. }
makes ß
act on the program input and ¥
combines +ß}
into a single link for ¡
to consume.
Here a distribution of 1000 outputs for n=6 which I collected using this program. Plotted with python/matplotlib.
Here is a 5000 data points from n=3 on a semilog plot which shows the (approximately?) exponential distribution.
$endgroup$
add a comment |
$begingroup$
Jelly, 7 bytes
X+ß}¥=¡
Try it online!
Uses recursion. Runs the program again (ß
) and adds (+
) if (¡
) the random number (X
) is equal (=
) to the program input. }
makes ß
act on the program input and ¥
combines +ß}
into a single link for ¡
to consume.
Here a distribution of 1000 outputs for n=6 which I collected using this program. Plotted with python/matplotlib.
Here is a 5000 data points from n=3 on a semilog plot which shows the (approximately?) exponential distribution.
$endgroup$
add a comment |
$begingroup$
Jelly, 7 bytes
X+ß}¥=¡
Try it online!
Uses recursion. Runs the program again (ß
) and adds (+
) if (¡
) the random number (X
) is equal (=
) to the program input. }
makes ß
act on the program input and ¥
combines +ß}
into a single link for ¡
to consume.
Here a distribution of 1000 outputs for n=6 which I collected using this program. Plotted with python/matplotlib.
Here is a 5000 data points from n=3 on a semilog plot which shows the (approximately?) exponential distribution.
$endgroup$
Jelly, 7 bytes
X+ß}¥=¡
Try it online!
Uses recursion. Runs the program again (ß
) and adds (+
) if (¡
) the random number (X
) is equal (=
) to the program input. }
makes ß
act on the program input and ¥
combines +ß}
into a single link for ¡
to consume.
Here a distribution of 1000 outputs for n=6 which I collected using this program. Plotted with python/matplotlib.
Here is a 5000 data points from n=3 on a semilog plot which shows the (approximately?) exponential distribution.
edited 1 hour ago
answered 2 hours ago
dylnandylnan
4,3532729
4,3532729
add a comment |
add a comment |
$begingroup$
APL (Dyalog Unicode), 15 14 bytes
{×r←?⍵:r⋄⍵+∇⍵}
Try it online!
$endgroup$
add a comment |
$begingroup$
APL (Dyalog Unicode), 15 14 bytes
{×r←?⍵:r⋄⍵+∇⍵}
Try it online!
$endgroup$
add a comment |
$begingroup$
APL (Dyalog Unicode), 15 14 bytes
{×r←?⍵:r⋄⍵+∇⍵}
Try it online!
$endgroup$
APL (Dyalog Unicode), 15 14 bytes
{×r←?⍵:r⋄⍵+∇⍵}
Try it online!
edited 1 hour ago
answered 1 hour ago
ngnngn
7,42612660
7,42612660
add a comment |
add a comment |
If this is an answer to a challenge…
…Be sure to follow the challenge specification. However, please refrain from exploiting obvious loopholes. Answers abusing any of the standard loopholes are considered invalid. If you think a specification is unclear or underspecified, comment on the question instead.
…Try to optimize your score. For instance, answers to code-golf challenges should attempt to be as short as possible. You can always include a readable version of the code in addition to the competitive one.
Explanations of your answer make it more interesting to read and are very much encouraged.…Include a short header which indicates the language(s) of your code and its score, as defined by the challenge.
More generally…
…Please make sure to answer the question and provide sufficient detail.
…Avoid asking for help, clarification or responding to other answers (use comments instead).
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodegolf.stackexchange.com%2fquestions%2f183073%2fsimulating-exploding-dice%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
$begingroup$
does the program have to be perfect? Like can its distribution be off by some extremely low amount?
$endgroup$
– Maltysen
11 hours ago
$begingroup$
To: Riker; RE: @Maltysen's comment above; or extremely high amount?
$endgroup$
– Artemis Fowl
10 hours ago
2
$begingroup$
@ArtemisFowl See our standards for randomness. Also, here.
$endgroup$
– Rɪᴋᴇʀ
3 hours ago