39
\$\begingroup\$

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.

\$\endgroup\$
18
  • 1
    \$\begingroup\$ @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 \$\endgroup\$ Jan 28 at 14:52
  • 2
    \$\begingroup\$ Surely if the integers must be chosen independently, then the output cannot be unique? \$\endgroup\$
    – pxeger
    Jan 28 at 15:50
  • 4
    \$\begingroup\$ @cairdcoinheringaahing for example, if a 5 is chosen, the chance of choosing another 5 has changed to 0. That isn't independent. \$\endgroup\$
    – pxeger
    Jan 28 at 16:06
  • 7
    \$\begingroup\$ @pxeger FWIW I agree with pxeger. The output numbers being unique is not compatible with independence \$\endgroup\$
    – Luis Mendo
    Jan 28 at 16:15
  • 1
    \$\begingroup\$ @LuisMendo Yep, that’s fine \$\endgroup\$ Jan 28 at 16:40

72 Answers 72

1 2
3
2
\$\begingroup\$

Befunge-98, 19 13 bytes

-3 bytes thanks to @ovs!

?+<1
<@w.:%d'

Try it online!

Generates each number according to a geometric distribution modulo 100.

Explanation

The instruction pointer (IP) starts at the ? in the top left corner, which sends it in a random direction. If it goes right, the < turns it around back to the ?, and the + (which is executed twice, once in each direction) adds 0 to the current number. If it goes left, 1 puts a 1 on the stack, < sends the IP back to ? again, and + adds the 1 to the number (which, given an empty stack, starts at zero). As long as ? keeps sending the IP left, this can happen arbitrarily many times, so there is a nonzero chance of reaching each number.

If the IP goes up or down, < turns it onto the second line, which processes the number.

 @w.:%d'

    :       Copy
   .             and print
     %                     the number modulo
      d'                                     100.
  w         If the copy is zero,
 @                               end the program.

If the printed result was greater than zero, w sends the IP up to the first line, and < starts the program over from the beginning.

\$\endgroup\$
1
  • \$\begingroup\$ If you take the random number modulo 100 instead of skipping the print if you reach a number higher than 99, this gets a bit simpler: 16 bytes \$\endgroup\$
    – ovs
    Feb 2 at 8:47
2
\$\begingroup\$

Swift, 57 54 51 bytes

var a=1;while a>0{a=Int.random(in:0...99);print(a)}
var a = 1                    // Set last randomly generated value to 1 as magic value
while a > 0 {                // End when a == 0
  a = Int.random(in: 0...99) // Generate new random number
  print(a)                   // Print number
}

-1 byte after reading comment by @Danis saying I can use > instead of !=, other 2 bytes from removing whitespace (a!=0 makes Swift think that I'm unwrapping a)

-1 byte after other comment

-2 bytes after removing whitespace

\$\endgroup\$
4
  • \$\begingroup\$ Welcome to the site, and nice first answer! Be sure to check out our Tips for golfing in Swift page for more ways you could golf your answer. \$\endgroup\$ Jan 29 at 20:06
  • \$\begingroup\$ @cairdcoinheringaahing Thanks! \$\endgroup\$
    – Eric Xue
    Jan 29 at 20:12
  • \$\begingroup\$ var a = -1 --> var a = 1 \$\endgroup\$
    – Danis
    Jan 30 at 8:28
  • \$\begingroup\$ Thank you @Danis! \$\endgroup\$
    – Eric Xue
    Jan 31 at 21:57
2
\$\begingroup\$

><>, 50 bytes

701>x1>$:2*}*+ }1-:?!v}30.>
   ^\0/.;?=0oan:%*aar<

Try it online!

After many iterations, I got down to this version. Pretty happy with it, although I will admit I'm not convinced it's optimal.

Explanation

The ><> language doesn't have a natural builtin for generating a random number in a range. The only source of randomness we have is the x command, which sends the IP in a random direction. This gives us 1 of 4 options, which doesn't immediately fit into the range 0-99. However, we can easily use this command to generate a random bit, 0 or 1, like so:

>x1>
^\0/

Going in a left-to-right direction, the IP can either be sent leftwards back to the >, where it tries again, upwards, wrapping around to try again, rightwards to 1, or downwards to 0. This uniformly generates a random bit, although perhaps it can be made shorter by making that not so.

We're going to loop 7 times each time we generate a random number, for 7 bits. This will give us the binary for numbers from 0 to 127—more than we need, but we'll fix that later. Instead of collecting all the bits and subsequently converting that to a decimal number, we'll do both steps at once. 701 initializes the stack with our configuration. 7 is the loop count, 0 is the running sum, and 1 is the multiplicative factor.

$:2* will make a copy of the multiplicative factor and double that copy for the next iteration. }*+ will multiply the generated bit by the multiplicative factor and add it to the sum. }1-:?!v will decrement the loop counter, and if it's 0, stop looping. }30., in the event we don't stop, will reorganize the stack for the next iteration and jump back to the beginning (past the initialization).

The second line mostly contains the outer loop. It is written "backwards" to save space. First, r will place the generated sum on the top of the stack. %*aa will take that value mod 100, giving us a value from 0 to 99, albeit not uniformly. Then, we simply output that number followed by a newline (oan:). After that, ;?=0 terminates the program if 0.

We then have a single . command, which pops y and x off the stack and jumps to that location in the code. Since the stack contains [0, 64] at this point (the counter and the multiplicative factor, respectively), this jumps to (0, 64). Of course, this position doesn't exist in the code. In the Python implementation (the standard one), the interpreter will first increment this by the delta, which, at the time of execution, is (-1, 0). So, the IP is then (-1, 64) internally. To resolve this, ><> will first fix the y-coordinate, wrapping it around to 0 since it exceeds the bound, giving (-1, 0). When x < 0, it gets wrapped around to the end of the line, hopping to (28, 0), which is the > command. This puts us back on the right direction and back at the beginning of the line.

Catalogue of Attempts

103 bytes: My first attempt. Completely ungolfed. First collects the bits, then converts it to a decimal in a separate stage.

7>x1>$1-:?!v!
 ^\0^   v$1<
{2*$l2=?\@:}*+
  !     >:0=?v:'d'(?v     >0[700.
           ;n<      >n' 'o^

105 bytes: Post calculating the sum while collecting bits. Longer, but the structure offers us more opportunities to golf.

701>x1>$:}*+}1-:?!v}2*30.
   ^\0^           >r:0=?v:'d'(?v     >0[700.
                      ;n<      >n' 'o^

90 bytes: Introducing the modulus trick, rather than retrying if the number is 100 ('d') or more.

701>x1>$:}*+}1-:?!v}2*30.
   ^\0^           >r:0=?vaa*%nao0[700.
                      ;n<

64 bytes: Inlining the terminate-if-zero condition.

701>x1>$:}*+}1-:?!v}2*30.
   ^\0^           >raa*%:nao0=?;0[700.

54 bytes: Moving the modulo calculation into the main loop so we have enough room to flip the second line and tuck it into the whitespace we have.

701>x1>$:}*+aa*%}1-:?!v}2*30.>
   ^\0/     .;?=0oan:r<

53 bytes: Since we have spare whitespace left, we can use it to set the pointer in the right direction to save the > off the first line. Since that means we're jumping to the beginning of the line, we'd naturally skip 7, so we have to duplicate it before we jump.

701>x1>$:}*+aa*%}1-:?!v}2*30.
   ^\0/ #.!@7;?=0oan:r<

This approach, however, left me at a dead end, so I tried putting the modulo calculation back into the second part, which leaves us with what we currently have.

\$\endgroup\$
2
\$\begingroup\$

Pxem, Filename: 23 17 bytes + Content: 0 bytes = 23 17 bytes, depends on ASCII-compatible encoding.

  • Filename: d.!.t.w.m.r.c.n,.o.a
  • Content: empty

Commented

d.t  # heap = 100
.w # loop
  .m.r # push(random(min=0,max=heap-1))
  .c # dup()
  .n # printf("%d",pop())
  ,.o # putchar(',')
.a # break if pop()==0
\$\endgroup\$
2
\$\begingroup\$

C (clang), 87 60 58 54 bytes

main(a){for(srand(&a);printf("%d ",a=rand()%100),a;);}

Try it online!

Learned new functions thanks to this.

Thanks to caird coinheringaahing, along with the help of a stone arachnid, for golfing 27 bytes. Thanks to a stone arachnid for golfing another 2 bytes. Thanks to ceilingcat for golfing 4 bytes.

\$\endgroup\$
4
1
\$\begingroup\$

Tcl, 54 bytes

while {[set R [expr int(rand()*99)]]} {puts $R}
puts 0

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Japt, 11 bytes

Lö
OpU
?ß:P

Try it online!

Outputs delimited by newlines, with a trailing newline after the 0

Lö      # Get a random number from [0...99] and store it as U
OpU     # Print U and a newline
?       # If U is non-zero:
 ß      #  Run the program again
  :P    # Otherwise end with no further output
\$\endgroup\$
1
\$\begingroup\$

VBScript, 51 bytes

Randomize
Do
r=Int(100*Rnd)
msgbox r
Loop Until r=0
\$\endgroup\$
1
\$\begingroup\$

CSASM v2.2.1, 74 bytes

func main:
.lbl a
push 100
extern Random.Next(i32)
dup
print.n
brtrue a
ret
end

Commented:

func main:
    .lbl loop
        ; Get a random number in [0, 99]
        push 100
        extern Random.Next(i32)
        ; Duplicate it so it can be printed and then checked
        dup
        print.n
        ; Keep looping as long as the i32 generated is truthy (non-zero)
        brtrue loop
    ret
end
\$\endgroup\$
1
\$\begingroup\$

GolfScript, 14/15 bytes

{100rand.}do]`

Try it online!

Uses rand built-in to generate random numbers from 0-99, inside a do loop to terminate once a 0 is generated. The output of the loop is collected into an array and formatted for output. If the brackets and quotation marks invalidate the output, here is another version that sacrifices 1 byte for cleaner output:

{' '100rand.}do

Try it online!

\$\endgroup\$
1
\$\begingroup\$

Knight, 12 bytes

W;O=n%R100nT

Try it online!

Very simple.

# Loop while RANDOM % 100 is non-zero.
# Because we need to output 0 as well, we
# use a semicolon to output first, then check n.
WHILE (; OUTPUT (= n % RANDOM 100):n)
    : TRUE # empty loop body

; can act sort of like the comma operator in C. It evaluates two statements and returns the second value.

Therefore, it is basically this in C:

while (printf("%d\n", n = rand() % 100), n)
    ;
\$\endgroup\$
1
\$\begingroup\$

Pip, 7 bytes

W PRRhx

Try it online!

Explanation

W        While
   RRh   random integer in [0, 100)
  P      printed
         is truthy (nonzero):
      x   No-op
\$\endgroup\$
1 2
3

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.