Randomizing until 0

Challenge

Sandbox post

Given a positive integer (K) Output a uniformly-random integer (Y) between [0, K).

If Y > 0 Assume K = Y and repeat the process until Y = 0.

Rules

• Input must be printed at first
• Output format as you wish
• 0 must be the final output, Optionally an empty line instead 0
• If the submission is a function, may it return 0 in addition to printing it?
Commented Jul 9, 2018 at 12:55
• @Adám yes, you can return in addition Commented Jul 9, 2018 at 12:59
• Do I need to seed my RNG? Commented Jul 9, 2018 at 16:16
• May we print without delimiters? Commented Jul 30, 2018 at 15:44
• I got curious. It's quite easy to prove that the average number of steps this program takes before it terminates is H(K-1) + 1 where H(K) is the K'th harmonic number. For n=1000, that's 8.484 steps on average. Commented Sep 21, 2018 at 14:02

Common Lisp - 52 Bytes

(loop while (/= a 0) do (print (setf a (random a))))


Assumes a is already defined.

Test case:

(setf a 5000000)
(loop while (/= a 0) do (print (setf a (random a))))


Elixir, 157 148 bytes

-9 bytes from Okx

defmodule N do def f(0,k)do IO.puts 0 end;def f(n,k)do IO.puts n;f Enum.random(0..k),k end end;k=String.to_integer IO.gets"";N.f Enum.random(0..k),k


Try it online!

Formatted:

defmodule N do
def f(0,k) do
IO.puts n
end

def f(n,k) do
IO.puts n
f Enum.random(0..k), k
end
end
{k,_} = Integer.parse IO.gets""
N.f Enum.random(0..k),k


We define a module with 2 functions - one is recursive, the other is the base case with a guard so it only executes when our random is 0 (Elixir doesn't necessarily assign anything, it does pattern matching for e.g. arguments- and thus f(0,k) only matches when n=0, otherwise f(n,k) matches). After defining that module (since functions can't be defined outside a module), we parse an integer from input and start our recursive looping.

Notably, k=String.to_integer IO.gets"" is the same length as the other method I've found to parse integers from input, {k,_}=Integer.parse IO.gets"", which is kinda neat.

• def f(n,k) when n <= 0 can be shortened to def f(0,k)
– Okx
Commented Jul 29, 2018 at 11:34

Elixir, 87 bytes

fn n->[n]++Enum.take_while(Stream.repeatedly(fn->Enum.random(0..n)end),&(&1>1))++[0]end


Try it online!

• This isn't actually valid as an answer - it doesn't uniformly randomize, the sequence is strictly decreasing due to how you recurse (if your first iteration is 50>25, it can never generate numbers 26-50 again). Commented Jul 30, 2018 at 13:50
• @Delioth fixed.
– Okx
Commented Jul 30, 2018 at 14:13

PHP, 44 bytes

<?=$a=$argn;while($a--)echo _,$a=rand(0,$a);  or <?for(;$a=&$argn;$a=rand(0,$a))echo$a--,_?>0


print integers delimited by underscore. Save to file, run as pipe with -nF.

Noether, 9 bytes

I~n0(nRP)


Try it online!

Output is given in the form

735920


Explanation:

I~n        - Store input in the variable n
0(   ) - Loop until the top of the stack equals zero
nR    - Push a random integer between 0 and n
P   - Print the top of the stack


Swift 4, 30 bytes

while n>0{n=rand()%n;print(n)}


Try it online!

n is the value of input

Forth (gforth), 57 bytes

include random.fs
: f begin dup . random dup 0= until . ;


Try it online!

Explanation

Get Random integer in range, loop until result is 0.

Code Explanation

include random.fs     \ import the file that implements the "random" word
:f                    \ start a word defintion
begin               \ start an indefinite loop
dup .             \ duplicate the top of the stack and print it
random            \ get random int between 0 and n - 1
dup 0=            \ duplicate the top of the stack and then check if it's 0
until               \ if it's zero end the loop
.                   \ output the top of the stack (always 0)
;                     \ end the word definition


Julia 1.0, 53 bytes

function q(N)println(N);if N>0;q(rand(0:N-1));end;end


Try it online!

Pyt, 5 bytes

0⇹ɾł


Try it online!

Explanation:

         Implicit input
ł    Do ... while top of stack is not 0:
0          Push 0
⇹         Swap top two elements on stack
ɾ        Get random number in [0,top of stack)
Implicit print


• At the TIO link, this always just outputs 0. Am I missing something? Commented Sep 23, 2018 at 4:22

Fortran 90, 56 bytes

read(*,*)i
do while(i>0)
i=rand(i)*i
print*,i
enddo
end


Trying to golf Fortran is always fun.

Also, because seeding the RNG in Fortran is a pain and costs a lot of bytes (and RAND() uses a particularly poor algorithm but has a nice short name), the output is pretty much deterministic - but I'm hoping to get away with it.

Example

Input:

10000000


Output:

 2636923
1681125
264113
17707
2453
47
0


PHP 5.6

$k =$y = 5; do { echo $k. "\n";$k = rand(0, $y-1); } while($k > 0)

• Please specify the name (and if relevant the version) of the used language in a Header at top of your answer, together with the code length measured in bytes. And please use Code and Preformatted Text markup for the code block to make it readable. Then please read the code-golf tag wiki about what is the goal in these challenges. Commented Sep 21, 2018 at 12:39
• To help getting into golfing, there is a collection of Tips for golfing in PHP. And also a generic Tips for golfing in <all languages>. Commented Sep 21, 2018 at 12:54

MathGolf, 4 bytes

orw∟


Try it online.

Explanation:

   ∟  # Do-while true without popping:
o     #  Print the current integer with trailing newline (without popping)
#  (which will be the implicit input-integer in the first iteration)
r    #  Pop and push a list in the range [0,K)
w   #  Pop and push a random integer from this list


Note: builtin w of itself works with an integer argument as well, but it'll output a random integer in the range $$\[0,K]\$$ instead of $$\[0,K)\$$, hence the need for the explicit r.

Thunno 2, 5 bytes

(ß;Lɼ


Attempt This Online!

Explanation

(ß;Lɼ  # Implicit input
( ;    # While loop
ß     # (condition)  Print TOS without popping
Lɼ  # (body)       Choose a random integer in the range [0..TOS)