# 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 – caird coinheringaahing Jan 28 at 14:52
• Surely if the integers must be chosen independently, then the output cannot be unique? – pxeger Jan 28 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. – pxeger Jan 28 at 16:06
• @pxeger FWIW I agree with pxeger. The output numbers being unique is not compatible with independence – Luis Mendo Jan 28 at 16:15
• @LuisMendo Yep, that’s fine – caird coinheringaahing Jan 28 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? – wizzwizz4 Jan 30 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. – Lyxal Jan 30 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. – Ethan Chapman Mar 18 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? – Giuseppe Jan 28 at 20:21
• @Giuseppe - Yup. Also, the output needs to be the same as independent sampling, so this would be violated without replacement. – Dominic van Essen Jan 28 at 20:22

# Python 3, 58 bytes

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

Try it online!

# 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 at 21:33
• Yes, I can't imagine the intended use case for negative arguments. Now a tip. – Dingus Jan 29 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... – Dominic van Essen Jan 28 at 18:53
• 29 bytes – Robin Ryder Jan 28 at 19:08
• @RobinRyder very nice, thank you! – Giuseppe Jan 28 at 20:12
• @RobinRyder - Well, that'll teach me... – Dominic van Essen Jan 28 at 20:16

# 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
# Read random byte
<?                        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 – Helena Jan 31 at 14:21

# 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)

# 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)[0]%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)[0] 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 – pxeger Jan 28 at 15:46
• @pxeger Charcoal and Retina probably do too :-( – Neil Jan 28 at 17:09
• Nice solution! I figured the walrus operator could come in handy here. – Spencer D Jan 31 at 1:10
• I like the misuse of id here :) – movatica Mar 16 at 18:38

# 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

# 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.

# 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! – Olivier Grégoire Jan 28 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 – branboyer Mar 7 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. – Olivier Grégoire Mar 7 at 9:28
• Oh, my apologies. Could you do something like this, then? @Olivier Grégoire – branboyer Mar 7 at 10:14
• I'm not so sure... Now it looks more like a snippet instead of a function, lambda or full program. – Olivier Grégoire Mar 7 at 11:29

# 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:
// return to dos (jumps to 0000h which is int 20h)
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 at 5:11
• Ooh, it might. I didn't know about that interrupt! I will test it all on my PC tomorrow. – EasyasPi Jan 29 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 – 640KB Jan 29 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)! – 640KB Jan 29 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! – 640KB Jan 29 at 16:53

# Raku, 19 bytes

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

Try it online!

• 18 bytes – bb94 Feb 2 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. – Bubbler Jan 29 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! – Redwolf Programs Jan 29 at 23:58
• You can also just do while(a). (Pun intended) – EasyasPi Jan 30 at 1:31
• Building on Redwolf Programs's golf ... do print(a=Math.random()*99|0);while(a) – aaaidan Jan 30 at 1:49
• Or what about while(print(a=Math.random()*99|0)||a){} 39 bytes – aaaidan Jan 30 at 1:50
• Suggested golf by mydarkstar: while(print(a=Math.random()*99|0)|a); for 37 bytes – caird coinheringaahing Jan 31 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[0] with 1
[
>                      ; make cell[1] the new cell[0]
-[>++<-----]           ; set cell[1] to 100
>--
[->?[<<+>>[-]]<]   ; 100 times increment cell[0] with some probability
<
.                      ; print cell[0]
]                          ; until cell[0] is 0
• Ooh, that's really clever! – EasyasPi Jan 31 at 15:05

# Jelly, 8 bytes

³X’+ƲƬI;

Try it online!

## Explanation

³X’+ƲƬI;   Main niladic link
Ƭ     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? – caird coinheringaahing Jan 28 at 15:00
• 11: ∪×∘×⍨\?⍨100 – Adám Jan 28 at 15:18
• Note sure if interesting, but ×∘×⍨ is ×⍛× in Extended. – Adám Jan 28 at 15:26
• Here's another approach {⍵,?100}⍣(1>(¯1↑⊣))⍬ – Andrew Ogden Mar 16 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 :) – caird coinheringaahing Mar 17 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? – Sheik Yerbouti Jan 28 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 – Noodle9 Jan 28 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 ++ – Sheik Yerbouti Jan 28 at 19:15
• @Davide Incrementing i before checking if its $0$ never stops! T_T – Noodle9 Jan 28 at 20:28
• Ahaha I am sorry, my brain needs some rest. – Sheik Yerbouti Jan 28 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. – caird coinheringaahing Jan 28 at 16:50
• tio.run/##K6gsycjPM/7/… – Danis Jan 28 at 18:37
• Shaved down to 56 bytes (1 better than @Danis's improvements). See tio.run/##K6gsycjPM/7/… – mhawke Jan 29 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 – Gotoro Jan 29 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. – Noodle9 Jan 29 at 10:26
• @Noodle I removed the iterative one :) – Sheik Yerbouti Jan 29 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! – Kjetil S. Jan 28 at 16:48 • Nice one! You can save a couple more if you use$- too! Try it online! – Dom Hastings Jan 29 at 12:48
• @DomHastings - That doesn't output 0 at the end. Required by "The output should always end with 0". – Kjetil S. Jan 29 at 14:56
• @KjetilS. Ah nice, I didn't read the spec and made assumptions! Using \$= works instead then: Try it online! – Dom Hastings Jan 29 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 at 19:59