Print random integers until 0

You are to write a program which generates random integers between $$\0\$$ and $$\99\$$ inclusive, outputting each integer in turn, until $$\0\$$ is generated. You may choose which single-order random distribution (uniform, binomial, Poisson etc.) you use so long as each integer has a non-zero chance of being generated and is chosen independently. The output should always end with 0. As each integer must be chosen independently, the output cannot be some permutation of the integers $$\\{0, 1, 2, ..., 99\}\$$ trimmed to end with $$\0\$$.

You may follow another method to accomplish the same task, so long as the result is identical to the described method here (for example: you may generate a number $$\K\$$ geometrically distributed with parameter $$\\frac 1 {99}\$$, then output $$\K\$$ independent numbers with a uniform distribution on the set $$\\{1, 2, ..., 99\}\$$, then output a $$\0\$$).

The integers may be separated by any non-digit, non-empty separator (e.g. newlines, spaces etc.), and may be output in any consistent base. You may output in any convenient method or format.

This is so the shortest code in bytes wins.

• @KevinCruijssen No, the integers do not have to be unique (aside from 0, which should appear exactly once), and yes, you may output them as a list Jan 28 '21 at 14:52
• Surely if the integers must be chosen independently, then the output cannot be unique? Jan 28 '21 at 15:50
• @cairdcoinheringaahing for example, if a 5 is chosen, the chance of choosing another 5 has changed to 0. That isn't independent. Jan 28 '21 at 16:06
• @pxeger FWIW I agree with pxeger. The output numbers being unique is not compatible with independence Jan 28 '21 at 16:15
• @LuisMendo Yep, that’s fine Jan 28 '21 at 16:40

Scratch 3.0, 9 blocks/76 bytes As SB Syntax:

define
set[N v]to(1
repeat until<(N)=(0
set[N v]to(pick random(0)to(99
say(N

Try it on Scratch

It just wouldn't be right if I didn't golf this in scratch. This is a function that achieves the desired result

Explained

define                             // Create a function with no name (not a lambda)
set[N v]to(1                       // Initalise the variable we will use to generate random numbers with
// If we didn't set it to 1, the next loop wouldn't start, as it would see that N = 0.
repeat until<(N)=(0                // Pretty self-explanatory
set[N v]to(pick random(0)to(99     // Also pretty self-explanatory. But putting this here means we don't have to include two calls to this block: we've essentially created a post-test loop instead of a pre-test loop
say(N                              // Output the randomly generated number and repeat
• Given that you can execute blocks of code by single-clicking in Scratch, do you need the define line? Jan 30 '21 at 0:37
• @wizzwizz4 without the define, this submission is no longer a function/full program. What you're describing is somewhat analogous to using a repl. Jan 30 '21 at 0:39
• I'm not familiar with SB syntax, but wouldn't it be better to pick Ns from 1 to 100 and say N-1 to avoid the set N to 1 problem? I'm not sure how costly subtraction is though. Mar 18 '21 at 15:16

R, 25 bytes

c(sample(99,rexp(1),T),0)

Try it online!

p(0) at each iteration is (e-1)/e.
p(each other number) at each iteration is (1/e)*(1/99).

Obviously this choice of random distribution gives a rather unsatisfying-looking output (since most of the runs are rather short). So this link uses the same approach, but changes p(0) to roughly 0.01 to illustrate some longer runs...

What's going on?

rexp(1)         # First determine where the '0' will occur:
# We generate a single random number using
# an exponential distribution with a
# rate parameter equal to 1
# (so the chance of any value x is e^-x).
c(                    ,0)   # Now place '0' at the subsequent position,
sample(99,rexp(1),T)      # and fill all the previous positions with
# numbers sampled from 1 to 99,
# with replacement (specified by the 'T' for TRUE).
• I see, you need the replace=T since there's a nonzero probability that the sample size will be larger than 99, though in practice, it seems...unlikely. exp(-100) or so? Jan 28 '21 at 20:21
• @Giuseppe - Yup. Also, the output needs to be the same as independent sampling, so this would be violated without replacement. Jan 28 '21 at 20:22

Python 3, 58 bytes

from random import*
print(*iter(lambda:randint(0,99),0),0)

Try it online!

Random Brainfuck, 676665 49 bytes

+[>>-[>++<-----]>--<?[>->+<[>]>[<+>-]<<[<]>-]>>.]

Try it online!

Finally found a use for this silly variant.

Assumes wrapping cells and that the tape will never overflow (which would be statistically improbable).

Basically, Random Brainfuck is just normal Brainfuck, except it adds the ? opcode which reads a byte from /dev/urandom.

All I have to do is modulo 100.

I move forward 6 bytes each iteration.

Outputs random bytes to stdout.

+                             (1) 0 0 0 0
[ do
# advance tape two places for sentinel
>>                        0 (0) 0 0
# set 100
# https://esolangs.org/wiki/Brainfuck_constants#100
-[>++<-----]>--           0 0 0 (100) 0
<?                        0 (rng) 100 0
# mod 100
# https://esolangs.org/wiki/Brainfuck_algorithms#Modulus_algorithm
[>->+<[>]>[<+>-]<<[<]>-]  0 (0) * rng % 100
# move left and print
>>                        0 0 * (rng % 100)
.                         print
] while rng % 100 != zero     note: start

The equivalent C algorithm:

void print_random(void)
{
uint8_t rng;
do {
rng = randbyte() % 100;
putchar(rng);
} while (rng != 0);
}
• Thanks for introducing me to random brainfuck. I posted my own solution Jan 31 '21 at 14:21

Ruby, 19 18 bytes

-1 byte thanks to Dingus!

loop{1/p(rand~99)}

Try it online!

rand~99 generates a random integer below abs(~99)=abs(-100)=100, p prints it to the output and returns the integer as a function and 1/x fails for x==0, stopping the program.

• @Dingus thats non-intuitive behaviour, thank you ;)
– ovs
Jan 28 '21 at 21:33
• Yes, I can't imagine the intended use case for negative arguments. Now a tip. Jan 29 '21 at 0:39

R, 30 29 bytes

while(print(sample(0:99,1)))T

Try it online!

print returns its argument invisibly, so this will choose an integer from 0-99 uniformly at random until a 0 is printed, because 0 is falsey in R.

Uses the "do-while" tip.

Thanks to Robin Ryder for saving a byte.

• Nice. I can't see any way to easily beat this without resorting to a highly-tweaked distribution... Jan 28 '21 at 18:53
• 29 bytes Jan 28 '21 at 19:08
• @RobinRyder very nice, thank you! Jan 28 '21 at 20:12
• @RobinRyder - Well, that'll teach me... Jan 28 '21 at 20:16

MathGolf, 5 bytes

♀(wo▲

Try it online.

Explanation:

▲  # Do-while true (!=0) with pop,
# using the entire program implicitly as inner code-block:
♀      #  Push 100
(     #  Decrease it to 99
w    #  Pop and push a random integer within the range [0,99]
o   #  Print it with trailing newline (without popping)

Batch, 48 bytes

@set n=%random:~-2%
@echo %n%
@if %n% gtr 0 %0

Works by taking the random number as a string and extracting the last two digits. (But the comparison is a numeric comparison so 00 still compares equal to 0.) 50 bytes if leading zeros are not allowed:

@set/an=%random%%%100
@echo %n%
@if %n% gtr 0 %0

Python 3.8, 52 50 bytes

-2 bytes inspired by EasyasPi's answer.

Produces some integers with probability $$\\frac 2 {256}\$$ and some with probability $$\\frac 3 {256}\$$ in each iteration.

import os
while id:print(id:=os.urandom(1)%100)

Try it online!

Uses the builtin function id to avoid assigning a new variable before the loop.
os.urandom(size) returns a bytes object with size random bytes. The bytes object behaves quite similar to a list of integers, which means os.urandom(1) gives a single random integer from $$\[0,255]\$$, which we map to an integer from $$\[0,99]\$$ with a modulo operation.

Python 3.8, 53 bytes

Generates integers from a uniform distribution over $$\[0, 99]\$$.

from random import*
while id:print(id:=randint(0,99))

Try it online!

• Python needs a do-while loop Jan 28 '21 at 15:46
• @pxeger Charcoal and Retina probably do too :-(
– Neil
Jan 28 '21 at 17:09
• Nice solution! I figured the walrus operator could come in handy here. Jan 31 '21 at 1:10
• I like the misuse of id here :) Mar 16 '21 at 18:38

PowerShell, 24 bytes

for(;$x=random 100){$x}0

Try it online!

Pyth, 6 bytes

W
O100

Try it online!

Python 3 translation:

from random import randrange
def n(b):
print(b)
return b

while n(randrange(100)):
pass

Bash (coreutils), 22 bytes

shuf -ri0-99|sed /^0/q

Try it online!

Bash is amazingly short here.

Using the little-known sed q (quit) command.

x86-16 DOS .COM file, 15 10 bytes

Machine code:

00000000: 0f c7 f0 d4 64 cd 29 75 f7 c3                    ....d.)u..

Assembly:

// sed -i -e 's#//#;#g' dosrand.asm
// nasm -f bin dosrand.asm -o dosrand.com
[bits 16]
org 100h
section .text
start:
.loop:
// don't mind the completely non-suspicious AVX instruction
// ax -> rand()
rdrand  ax
// al -> al % 100
// ah -> al / 100
// set flags on al
aam     100
// putchar(al)
int     29h
// Loop if aam didn't return zero
jnz     .loop
.end:
ret

Try it online! (int 29h simulated with pushf/popf and putchar)

This binary needs a 2013 processor running a 1981 operating system. Nothing weird here. 😛

Specifically, it requires the rdrand instruction introduced in Ivy Bridge. However, QEMU supports this even on non-x86 hosts with -cpu max.

Prints raw bytes to stdout.

I might make a version for i386 using printf later, but I like this meme better.

Thanks to 2x-1 for recommending int 29h and saving 5 bytes!

Note that a solution using mov al, 100; out 41h, al; in al, 41h was suggested for a portable alternative, but I was unable to get it to work properly; they either infinite looped or the data wasn't random enough depending on the DOS implementation I used (NTVDMx64, DOSBOX, and QEMU/FreeDOS).

• Could int 29h work here?
– user99151
Jan 29 '21 at 5:11
• Ooh, it might. I didn't know about that interrupt! I will test it all on my PC tomorrow. Jan 29 '21 at 5:22
• @2x-1 nice one! I think you can omit the TEST AL, AL since the DEC AL will set the ZF for you. Also, DEC AL is actually 2 bytes, whereas DEC AX is 1 (though you can't use that without zero'ing out the contents of AH which would cost you at least that byte back). Also, you do need a RET at the end to make it legal, either as a callable function OR a standalone COM it's necessary updated Jan 29 '21 at 16:38
• @2x-1 actually if you submitted that as a standalone executable you could use DEC AX since we can assume registers are in known startup states and most common DOS version zero out AX ( Tips for golfing in x86 ). That'd get you to 12 bytes (b064 e641 e441 48 cd29 75f5 c3)! Jan 29 '21 at 16:44
• Using int 29h should save you total 5 bytes since you can eliminate 3 bytes from xchg and mov ah, 2. Also aam 100 will set ZF when al == 0 so you can eliminate 2 more bytes by removing test dl,dl too. Great suggestion @2x-1! Jan 29 '21 at 16:53

Java (JDK), 61 bytes (recursive)

Object f(){int r=100;return(r*=Math.random())<1?r:r+" "+f();}

Try it online!

Object f(){         // Method returning an Object because it either returns an Integer or a String.
int r=100;         // Initialize r as an int(eger) to 100.
return             // The rest can be inlined, so use the return here.
(
r*=Math.random() // Multiply 100 by a random double number in range [0,1).
// Also, *= is a compound operator that implies a cast,
// therefore changing the double to an int at no cost.
// So now, r is an integer in range [0,100).
)<1?              // If the multiplied number is zero (the only possible value below 1)
r               // Return r as an int, which is automatically boxed to an Integer.
// Technically, r is 0, so I could have written 0 instead of r
// This is the recursion-closing branch.
:                // Otherwise
r+" "+f();      // Return a String, composed of r, a space and the result of the next call to f()
// which may either be another String or 0.
}

Java (JDK), 64 bytes (iterative)

v->{for(int r=1;r>0;System.out.println(r*=Math.random()))r=100;}

Try it online!

Credits

• Recursion beating iteration in Java is rare enough to notice! Jan 28 '21 at 15:22
• You actually can do recursion with lambda, but no one on this site ever uses it, so I am not sure how it should be counted. 57 bytes Mar 7 '21 at 5:19
• It's called named lambda and it's not usable in Java because the full lambda type should've present, that means having all the parameter types. Unless you use an existing functional interface, in which case you need to give the full interface name. In short, it's usable in some languages but not in Java. Mar 7 '21 at 9:28
• Oh, my apologies. Could you do something like this, then? @Olivier Grégoire Mar 7 '21 at 10:14
• I'm not so sure... Now it looks more like a snippet instead of a function, lambda or full program. Mar 7 '21 at 11:29

Raku, 19 bytes

{{100.rand+|0}...0}

Try it online!

• 18 bytes
– bb94
Feb 2 '21 at 6:54

Retina, 25 bytes

./^0/^{L$^ 99* \L@$
$. Try it online! Explanation: . Suppress the default output. /^0/^{ Repeat until the value is zero. L$^
99*

Replace the value with 99 _s.

\L@$$.

Take the length of a random prefix and also output it on its own line.

Factor, 29 bytes

-4 bytes thanks to @Bubbler.

[ 100 random dup . 0 > ] loop

Try it online!

• 29. Using loop saves a [ ] here. Jan 29 '21 at 4:40

Javascript (V8), 39 bytes

-4 bytes thanks to Redwolf Programs and aaaidan.

do print(a=Math.random()*99|0);while(a)

Javascript (V8), 45 43 bytes

-2 bytes thanks to EasyasPi.

do{a=~~(Math.random()*99);print(a)}while(a)
do {
a = ~~ (Math.random()*99);
print(a)
} while(a)

Uses a double bitwise NOT operator (~), as a substitute for Math.floor.

Try it online!

• Welcome to Code Golf! I think you can golf this down by at least four bytes: Try it online! Jan 29 '21 at 23:58
• You can also just do while(a). (Pun intended) Jan 30 '21 at 1:31
• Building on Redwolf Programs's golf ... do print(a=Math.random()*99|0);while(a) Jan 30 '21 at 1:49
• Or what about while(print(a=Math.random()*99|0)||a){} 39 bytes Jan 30 '21 at 1:50
• Suggested golf by mydarkstar: while(print(a=Math.random()*99|0)|a); for 37 bytes Jan 31 '21 at 8:48

Random Brainfuck, 37 bytes

+[>-[>++<-----]>--[->?[<<+>>[-]]<]<.]

Try it online!

This answer is inspired by EasyasPi's solution, but I am avoiding modulo by not even trying to get a uniform distribution. This theoretically should work, but practically will take a long time to finish. If you change the code setting the cell to 100 to a lower number you will see that it indeed terminates at some point.

+                          ; initialise cell with 1
[
>                      ; make cell the new cell
-[>++<-----]           ; set cell to 100
>--
[->?[<<+>>[-]]<]   ; 100 times increment cell with some probability
<
.                      ; print cell
]                          ; until cell is 0
• Ooh, that's really clever! Jan 31 '21 at 15:05

Jelly, 8 bytes

³X’+ƲƬI;

Try it online!

Explanation

Ƭ     Repeat and collect results until there's a duplicate result
Ʋ      (
³            100
X           Choose a random number from 1 to 100
’          Decrement (to get a number from 0 to 99)
+         Add to the current value
Ʋ      )
I    Increments (deltas)
;   Join with the implicit argument, 0

APL (Dyalog Unicode), 15 11 10 33 16 bytes

100,∘?⍨⍣{0=⊃⌽⍺}⍬

Try it online!

A full program which outputs the numbers separated by spaces.

Uses ⎕IO←0 (0-indexing).

-4 then -1 byte from Adám.

-19 bytes from 1_am_Jack.

• Is x guaranteed to always contain 0? Jan 28 '21 at 15:00
• 11: ∪×∘×⍨\?⍨100
Jan 28 '21 at 15:18
• Note sure if interesting, but ×∘×⍨ is ×⍛× in Extended.
Jan 28 '21 at 15:26
• Here's another approach {⍵,?100}⍣(1>(¯1↑⊣))⍬ Mar 16 '21 at 21:24
• Our chat in TNB was asking about the first version; I wasn't sure exactly how ? sampled it's output. There must have been a misunderstanding between us :) Mar 17 '21 at 2:37

05AB1E, 8 bytes

[99ÝΩ=_#

Try it online.

Explanation:

[         # Start an infinite loop:
99Ý      #  Push a list in the range [0,99]
Ω     #  Pop and push a random integer from this list
=    #  Print it with trailing newline (without popping)
_   #  Pop and if this integer is 0:
#  #   Stop the infinite loop

CJam, 10 9 bytes

{S100mr}h

Try it online!

Prints each number with a space before it.

How it works

{       }h    e# Do-while loop, withput consuming the condition. Nonzero is truthy
S            e# Push space
100         e# Push 100
mr      e# Random integer with uniform distribution on [0 1 2 ... 99]
e# Implicit output

C (gcc), 59 $$\\cdots\$$ 44 42 bytes

Saved 2 bytes thanks to dingledooper!!!
Saved a byte thanks to Davide!!!

f(i){for(;printf("%d ",i=rand()%100),i;);}

Try it online!

Keeps on printing random integers in $$\[0,99]\$$ until $$\0\$$ is printed.

• 55 bytes But is srand() necessary? Jan 28 '21 at 18:06
• @Davide Yup, there's another rule about random number generation in functions can't be the same for all first and subsequent runs. Also unsure about your golf, i could be $0$ at the onset. But having it as a parameter saves a byte - thanks! :D Jan 28 '21 at 18:35
• Oh you are right. Then 57 bytes One byte from the i as a parameter and another byte by swapping i=! with ++ Jan 28 '21 at 19:15
• @Davide Incrementing i before checking if its $0$ never stops! T_T Jan 28 '21 at 20:28
• Ahaha I am sorry, my brain needs some rest. Jan 28 '21 at 20:45

Python 3, 66 56 bytes

from random import*
x=1
while x:x=randint(0,99);print(x)

Try it online!

Thank you to xnor, danis and mhawke for showing new stuff and helping improve the code!

• Welcome to the site, and nice first answer! Be sure to check out our Tips for golfing in Python page for more ways you could golf your answer. Jan 28 '21 at 16:50
• tio.run/##K6gsycjPM/7/… Jan 28 '21 at 18:37
• Shaved down to 56 bytes (1 better than @Danis's improvements). See tio.run/##K6gsycjPM/7/… Jan 29 '21 at 5:34
• Oh wow. I've tried doing this without indent, but Jupyter didn't allow me to do that for some reason. Also, I was looking at how to make a proper post, so I clicked edit on one of the existing ones and four space were there so I used the same method Jan 29 '21 at 12:30

Ohm v2, 10 bytes

⁸‹#£D§D,X‽

Try it online!

Commented:

⁸‹#          push a list containing the integers in the range [0-99]
£    X‽   while the the picked number is not 0
D        duplicate the list and
§D,     pick a random number from the list and display it

C (gcc), 40 bytes

f(r){printf("%3d",r=rand()%100)*r&&f();}

Try it online!

• This isn't valid, rs value is whatever was left on the stack so it could be $0$ at the onset. This is basically my answer without the init of r. Jan 29 '21 at 10:26
• @Noodle I removed the iterative one :) Jan 29 '21 at 12:58

Phooey, 9 bytes

(&~r99$c) Try it online! Dumps raw bytes to stdout. ( do & set cell to 0 by popping from empty stack ~r99 generate random from cell to 99$c     print as byte
)      while cell is nonzero

(&~r99$i" ") Try it online! Does the same thing, only instead of printing as a raw byte, it prints it as an integer and adds a space. Perl 5, 26 23 21 bytes @KjetilS's comment inspired me to save even more bytes than suggested, and @DomHastings got another 2 bytes off by changing to$=

say$==rand 100while$=

Try it online!

• Shave a byte with say$_=0|rand 100until/^0/ Try it online! Jan 28 '21 at 16:48 • Nice one! You can save a couple more if you use$- too! Try it online! Jan 29 '21 at 12:48
• @DomHastings - That doesn't output 0 at the end. Required by "The output should always end with 0". Jan 29 '21 at 14:56
• @KjetilS. Ah nice, I didn't read the spec and made assumptions! Using \$= works instead then: Try it online! Jan 29 '21 at 16:28

Lua, 43 bytes

repeat a=math.random(0,99)print(a)until a<1

Try it online!

• Welcome to Code Golf! This is a nice first answer. Be sure to check out our tips for golfing in Lua.
– user
Jan 29 '21 at 19:59