# Challenge

I'm under attack by the larcenous Midnight Crew and I need to summon the Catenative Doomsday Dice Cascader in order to defend myself. Since I'm low on space, I need the code to be as short as possible.

The algorithm for the Catenative Doomsday Dice Cascader is as follows:

First, the six sided die in the Prime Bubble is rolled, and the result will determine how many iterations of the next step take place.

Start with a six sided die. For as many times as the roll of the Prime Bubble die, multiply the number of sides on the next die by the result of the roll of the current die. For example, if on your first roll of the six-sided die your roll is 2, then your next die will have 6*2 = 12 sides.

Your goal is to write a function or program that takes no input and outputs the final result of the last die rolled. Since this is , the lowest byte count in each language wins!

# Examples

Example #1 (Taken directly from the link above):

The Prime Bubble rolls a 6, meaning that the Cascader will iterate six times

#1: We always start with a 6 sided die, and it rolls a 2, so the next die has 6x2=12 sides
#2: The 12 sided die rolls an 8, meaning that the third die has 12x8=96 sides
#3: The 96 sided die rolls a 35, meaning that die 4 has 96x35=3360 sides
#4: The 3360 sided die rolls a 2922, so die 5 has 3360x2922 = 9,817,920 sides
#5: The 9.8 million sided die rolls a 5,101,894, so the final die has 50,089,987,140,480 sides
#6: The 50 trillion sided die rolls a one. Hooray.
Since the last die rolled gave a 1, your function or program should output 1.

Example #2

The Prime Bubble rolls a 2, meaning that the Cascader will iterate twice.

#1: We always start with a 6 sided die, and it rolls a 4, so the next die has 6x4 = 24 sides
#2: The 24 sided die rolls a 14

Since the last die rolled gave a 14, your function or program should output 14.

• Whats the maximum output? If every roll results in the maximum side? I think it's 7958661109946400884391936 = ((((6^2)^2)^2)^2)^2 = 6^(2^5) = 6^32 Jun 1 '19 at 11:53
• @KjetilS. Indeed, and the likelihood of that output should be $\frac{1}{6*\prod_{i=0}^5(6^{2^i})}=\frac{1}{6\times 6\times 6^2\times 6^4\times 6^8\times 6^{16}\times 6^{32}}=\frac{1}{2155416739906037495048372267884096782336}$ Jun 1 '19 at 12:50
• Is this supposed to be random? The question doesn't mention anything about randomness at all? Jun 1 '19 at 16:35
• @SriotchilismO'Zaic Dice-rolling implies randomness. Jun 1 '19 at 21:34
• @SriotchilismO'Zaic xkcd.com/221
– Neyt
Jun 3 '19 at 9:52

# Python 2, 76 69 bytes

from random import*
R=randint
v=6;exec"p=R(1,v);v*=p;"*R(1,6)
print p


Try it online!

# Perl 6, 43 37 bytes

-6 bytes thanks to nwellnhof

{(6,{roll 1..[*] @_:}...*)[1+6.rand]}


Try it online!

Anonymous code block that returns the doomsday dice result.

### Explanation:

{                                   }   # Anonymous code block
(                       )[1+6.rand]    # Take a random number from
...*               # The infinite list of
6,{roll 1..[*] @_:}                   # Cascading dice values
6,                                    # Starting from 6
{roll          :}                   # And choosing a random value from
1..                           # One to
[*] @_                     # The product of every value so far


# Wolfram Language (Mathematica), 43 bytes

(r=RandomInteger)@{1,Nest[r@{1,#}#&,6,r@5]}


Try it online!

# J, 21 bytes

1+[:?(*1+?)^:(?])@6x


Try it online!

+6 bytes thanks to a logic problem spotted by FrownyFrog

NOTE: J has no niladic verbs. However, this verb will work the same no matter what argument you give it. In the TIO example, I'm calling it with 0, but I could have used 99 or '' just as well.

## how

• 1+ add one to...
• [:? a single roll of an n-sided die (sides reading 0 to n-1), where the number n is determined by...
• (*1+?) take the current argument y and roll ? to produce a random number between 0 and y-1. 1+ makes that 1 to y, inclusive. Finally the * creates a J hook, which will multiply that by y again.
• ^: do the above this many times...
• (?]) ? roll the initial argument, which is 6, to determine how many times to repeat. If we roll 0 (corresponding to a 1 on the Prime Bubble), the argument will pass through unchanged. The ] indicates that 6, unchanged, will be the starting value of repeated (*1+?) verb that determines the die value for the final roll.
• @6x attaches the constant verb 6, so that we can call it with anything, and the x forces J to use extended integer computation which we need for the possibly huge numbers.
• in this case 0 executes the previous verb once, 1 twice, etc why is that? Jun 1 '19 at 23:15
• because i made a mistake :(. will fix soon. Jun 1 '19 at 23:42
• Fixed now. Thanks. Jun 1 '19 at 23:55

# K (oK), 32 bytes

Solution:

*|{x,1+1?x:(*).x}/[*a;6,a:1+1?6]


Try it online!

Start with 6 and "1 choose 6", iterate over "1 choose 6" times:

*|{x,1+1?x:(*).x}/[*a;6,a:1+1?6] / the solution
{             }/[n;    c     ] / iterate over lambda n times with starting condition c
1?6  / 1 choose 6, between 0..5 (returns a list of 1 item)
1+     / add 1 (so between 1..6)
a:       / store as 'a'
6,         / prepend 6, the number of sides of the first dice
*a            / we are iterating between 0 and 5 times, take first (*)
(*).x                 / multi-argument apply (.) multiply (*) to x, e.g. 6*2 => 12
x:                      / save that as 'x'
1?                        / 1 choose x, between 0..x-1
1+                          / add 1 (so between 1..x)
x,                            / prepend x
*|                               / reverse-first aka 'last'


You can see the iterations by switching the over for a scan, e.g.

(6 3        / 1 choose 6 => 3, so perform 3 iterations
18 15      / 1 choose (6*3=18) => 15
270 31     / 1 choose (18*15=270) => 31
8370 5280) / 1 choose (270*31=8730) => 5280

• (*).x -> */x and { }/[*a;6,a:1+1?6] -> a{ }/6,a:*1+1?6
– ngn
Jun 7 '19 at 23:16

# Jelly, 9 bytes

6X×$5Ð¡XX  A niladic Link which yields a positive integer. Try it online! Saving a byte over the more obvious 6X×$6X’¤¡X

### How?

6X×$5Ð¡XX - Link: no arguments 6 - initialise left argument to 6 5Ð¡ - repeat five times, collecting up as we go: -> a list of 6 possible dice sizes$      -   last two links as a monad = f(v):           e.g [6,18,288,4032,1382976,216315425088]
X        -     random number in [1,v]                     or [6,6,6,6,6,6]
×       -     multiply (by v)                            or [6,36,1296,1679616,2821109907456,7958661109946400884391936]
X  - random choice (since the input is now a list) -> faces (on final die)
X - random number in [1,faces]

• Nice. I was trying to think of a way from moving beyond my ‘obvious’ answer, but didn’t think of generating all the dice and then picking one at random. Jun 1 '19 at 13:50
• Heh, I missed that you'd posted almost that exact answer! Jun 1 '19 at 14:01

# 05AB1E, 10 bytes

X6DLΩF*DLΩ


The random choice builtin for large lists is pretty slow, so may result in a timeout if the Prime Bubble roll is for example a 6.

Try it online or try it online with added prints to see the rolls. (TIO uses the legacy version of 05AB1E, since it's slightly faster.)

Explanation:

X           # Push a 1 to the stack
6          # Push a 6 to the stack
D         # Push another 6 to the stack
L        # Pop the top 6, and push a list [1,2,3,4,5,6] to the stack
Ω       # Pop and push a random item from this list (this is out Prime Bubble roll)
F      # Loop that many times:
*     #  Multiply the top two values on the stack
#  (which is why we had the initial 1 and duplicated 6 before the loop)
D    #  Duplicate this result
LΩ  #  Pop and push a random value from its ranged list again
# (after the loop, output the top of the stack implicitly)


# Jelly, 9 bytes

6×X$X’$¡X


Try it online!

Jonathan Allan's answer claims that it's

Saving a byte over the more obvious 6X×$6X’¤¡X . In fact, we don't need to make such a big modification. Therefore, this is an alternative approach to Jonathan Allan's answer, and, also, a resting place for my initial invalid 6-byter. :( # Perl 5, 54 bytes $a=6;map$a*=$r=1+int rand$a,0..rand 6;say 1+int rand$r


Try it online!

• That's one rand too many, you should just say$r Jun 1 '19 at 19:25 # Charcoal, 16 bytes ⊞υ⁶Ｆ⊕‽⁶⊞υ⊕‽ΠυＩ⊟υ  Try it online! Link is to verbose version of code. Explanation: ⊞υ⁶  Push 6 to the predefined list. Ｆ⊕‽⁶  Repeat a random number of times from 1 to 6... ⊞υ⊕‽Πυ  ... push a random number between 1 and the product of the list to the list. Ｉ⊟υ  Output the last number pushed to the list. Alternative approach, also 16 bytes ≔⁶θＦ‽⁶≧×⊕‽θθＩ⊕‽θ  Try it online! Link is to verbose version of code. Explanation: ≔⁶θ  Set the number of sides to 6. Ｆ‽⁶  Repeat a random number between 0 and 5 times... ≧×⊕‽θθ  ... multiply the number of sides by a random number from 1 to the number of sides. Ｉ⊕‽θ  Print a random number from 1 to the number of sides. # Python 3, 76 bytes from random import* r=randint a=6 for i in" "*r(0,5):a*=r(1,a) print(r(1,a))  Try it online! -2 bytes thanks to TFeld • -2 bytes by changing the import Jun 1 '19 at 7:34 • @TFeld thanks [filler] Jun 1 '19 at 19:23 # R, 43 bytes s=sample for(i in 1:s(k<-6))T=s(k<-k*T,1) T  Try it online! k keeps track of the current number of faces on the die. Uses the fact that T is initialized as 1. I tried a few other things, but couldn't beat this simple, straightforward approach. # Jelly, 10 bytes 6×X$6X’¤¡X


Try it online!

### Explanation

       ¤   | Following as a nilad:
6X     | - A random number between 1 and 6
’    | - Decrease by 1 (call this N)
6          | Now, start with 6
$¡ | Repeat the following N times, as a monad × | - Multiply by: X | - A random number between 1 and the current total X | Finally, generate a random number between 1 and the output of the above loop  # Ruby, 41 bytes r=6;rand(2..7).times{r*=$s=rand 1..r};p$s  Try it online! Explanation r=6 # Set dice number to 6 rand(2..7).times{ } # Repeat X times, where X=dice roll+1 r*=$s=rand 1..r    # Multiply dice number by a dice roll
# Save the most recent dice roll

p$s # Print last dice roll (this is why # we did the last step one extra time)  # Java 10, 21493 86 bytes v->{int r=6,n=0;for(var d=Math.random()*6;d-->0;n*=Math.random(),r*=++n)n=r;return n;}  -128 bytes by using int instead of java.math.BigInteger. $$\6^{32}\$$, the largest possible result, doesn't fit inside an int nor long, which is why BigInteger was used initially. OP allowed to use int and assuming it's infinitely large, so that saved more than 125 bytes here. :) (Here the previous 214 bytes version using BigIntegers.) Explanation: v->{ // Method with empty unused parameter & integer return-type int r=6, // The range in which to roll, starting at 6 n=0; // The roll itself (which must be initialized, therefor is 0) for(var d=Math.random()*6;// Roll the Prime Bubble Dice d-->0 // Loop that many times: ; // After every iteration: n*=Math.random(), // Roll a random dice in the range [0, n) r*=++n) // Increase n by 1 first with ++n, so the range is [1,n] // And then multiply r by n for the new range n=r; // Set n to r return n;} // After the loop, return n as result  • Post the solution that doesn't do BigInteger as your competing solution. Jun 3 '19 at 16:16 • @Stackstuck Will await what OP has to say to your comment. Was about to make one myself to confirm. I personally use BigIntegers/BigDecimals for challenges where it's necessary, unless OP explicitly states you can use your native max integer size (which is usually $2^{32}$, so int for both Java and .NET C#). Jun 3 '19 at 16:26 • I'll see if I can find anything on meta about this. Jun 3 '19 at 16:29 • OP says don't worry about integer size limits. Use the int type. Jun 8 '19 at 1:26 • @Stackstuck Done, and golfed 7 bytes in the process. :) Jun 8 '19 at 12:00 # PHP, 59 bytes $r=$q=rand(1,$s=6);while($l++<$q)$r=rand(1,$s*=$r);print$r;


expanded:

$r=$q=rand(1,$s=6); while($l++<$q)$
r=rand(1,$s*=$r);
print$r;  Not sure if I'm supposed to include the open tag. On my machine, it crashes if $s*$r is too large, so it doesn't print on $q>=5 sometimes... because the numbers get so big. Not sure of a fix.

# Pyth, 14 bytes

uhO=*|Z6GO6hO6


Try it online!

uhO=*|Z6GO6hO6
O6      Random number in range [0-6)
u                Perform the following the above number of times...
hO6   ... with starting value G a random number in range [1-6]:
*   G          Multiply G with...
|Z6           The value of Z, or 6 if it's the first time through (Z is 0 at program start)
=  Z            Assign the above back into Z
O                Random number in range [0-Z)
h                 Increment
Implicit print result of final iteration


# C# (.NET Core), 136 bytes

class A{static void Main(){var r=new System.Random();int i=r.Next(6),j=6;while(i-->0)j*=1+r.Next(j);System.Console.Write(r.Next(j)+1);}}


Try it online!

I'm pretty sure this works, given the assumption of infinite integer length that we're fond of here. If I have to actually handle the overflow, I'd need to bust out an entirely different class.

• It can now give a System.ArgumentOutOfRangeException: 'maxValue' must be greater than zero error. The max result can be $6^{32}$, which is larger than the max size of both int and long, so you'll have to use BigIntegers instead. Jun 3 '19 at 9:34
• @KevinCruijssen yes, that's the whole point of my comment. Jun 3 '19 at 16:12

# Julia 1.0, 60 bytes

g(b=big(6),r=rand)=(for i in 1:r(0:5) b=b*r(1:b) end;r(1:b))


b=big(6) makes it work with arbitrary sized integers Try it online!

# Gaia, 13 bytes

:(ṛ×
6₅ṛ(↑ₓ(ṛ


Try it online!