Randomizing until 0

29

5

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
  • Your program must finish.
  • 0 must be the final output, Optionally an empty line instead 0

Luis felipe De jesus Munoz

Posted 2018-07-09T12:11:17.537

Reputation: 9 639

If the submission is a function, may it return 0 in addition to printing it? – Adám – 2018-07-09T12:55:45.997

1@Adám yes, you can return in addition – Luis felipe De jesus Munoz – 2018-07-09T12:59:33.070

Do I need to seed my RNG? – SIGSTACKFAULT – 2018-07-09T16:16:41.110

May we print without delimiters? – Titus – 2018-07-30T15:44:28.760

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.

– J.Doe – 2018-09-21T14:02:42.187

Answers

19

Pyth, 6 5 4 bytes

.uOW

Try it here!

How it works

.uOW    Full program. Takes an integer from  STDIN and outputs a list to STDOUT.
.u      Cumulative fixed-point. Apply the given function with a given initial value,
        which is implicitly assigned to the input, until a result that has occurred 
        before is found. Returns the list of intermediate results.
   W    Conditional application. If the argument (the current value) is truthy, then
        apply the function below, otherwise leave it unchanged.
  O     Random integer in the range [0, N).
        IOW: at each iteration of .u, assign a variable N to the current value, starting
        with the input. If N is not 0, then choose a random integer in [0, N), else
        return N unchanged. Whenever we encounter a 0, the next iteration must also
        result in a 0, and therefore the loop stops there.

Mr. Xcoder

Posted 2018-07-09T12:11:17.537

Reputation: 39 774

1I saw a way to do this in Pyth but I am a beginner. Respect. Language of the month in August maybe? – ElPedro – 2018-07-09T22:17:22.120

15

C (gcc), 42 bytes

f(_){printf("%d\n",_);(_=rand()%_)&&f(_);}

Try it online!

Uses short-circuited logical and.

f(_){                 // f(int _) {
    printf("%d\n",_); // print argument and a newline
    (_=rand()%_)      // set _ to rand()%_
    &&f(_);}          // short-circuit AND to recursively call f if _ not zero

C (gcc), 40 bytes (w/o printing initial value)

f(_){printf("%d\n",_=rand()%_);_&&f(_);}

Try it online!

Uses short-circuited logical and.

f(_){              // f(int _) {
    printf("%d\n", // print an integer and a newline 
    _=             // The integer is _ which we set to...
    rand()%_);     // a random value modulo the input _
    _&&f(_);}      // short-circuit AND to recursively call f if _ not zero

LambdaBeta

Posted 2018-07-09T12:11:17.537

Reputation: 2 499

4rand()%_ is not uniform – njzk2 – 2018-07-09T17:01:47.477

(if you are not convinced, try using a 6-sided dice to generate a [1,5] value using this method.) – njzk2 – 2018-07-10T02:44:04.403

3I'm fully aware that rand() is almost always biased (due to truncation), but the standard doesn't guarantee it (RAND_MAX could in theory be a multiple of all our numbers, just by luck :P though usually it's ~65k). In practice for the ranges we're dealing with it will appear sufficiently random to not stand out against similar submissions in this challenge. – LambdaBeta – 2018-07-10T02:47:56.770

1that's from the challenge "Output a uniformly-random integer", so, strictly speaking, this is not valid – njzk2 – 2018-07-10T02:53:55.487

3Strictly speaking all languages here use prng's. None of them will give a true uniform random number (which would require a perfect source of entropy). While many are more uniform than this, that isn't noticeable in log(k) iterations. – LambdaBeta – 2018-07-10T11:37:02.430

Strictly speaking, Linux supports random number generation. Refer to man 4 random. "The random number generator gathers environmental noise from device drivers and other sources into an entropy pool." – Geo – 2018-07-11T16:54:41.943

ya can take "\n" -> " " and save a byte – George V. Williams – 2018-07-12T02:06:35.407

@Geo that sort of depends on your definition of randomness, you could take the view that computers can't generate random numbers anyway. (Besides, the entropy is an estimation anyway and so it's misleading regardless.) – George V. Williams – 2018-07-12T02:10:36.960

@GeorgeV.Williams why not?

– Ruslan – 2018-07-12T09:49:06.487

@Ruslan why?

– George V. Williams – 2018-07-12T22:34:14.343

10

R, 66 60 56 43 41 bytes

function(n)while(print(n))n=sample(n,1)-1

Try it online!

ngm

Posted 2018-07-09T12:11:17.537

Reputation: 3 974

I don't think you need >0 and cat(n,"") (empty string) will also work. – Giuseppe – 2018-07-09T12:56:54.423

But I think print is more efficient here, as it returns its argument: 56 bytes

– Giuseppe – 2018-07-09T13:26:26.843

Also 56 bytes: k=scan();while(x<-sample(1:k-1,1))k=c(x,k);cat(rev(k),0) – JAD – 2018-07-09T14:04:01.970

Sorry, am I missing something or this is valid ? Try it online!

– digEmAll – 2018-07-09T17:59:22.337

1

I forgot to remove the curly brackets, so you can save 2 more bytes ;) Try it online!

– digEmAll – 2018-07-09T18:07:57.730

btw, congrats on 1K! :-) – Giuseppe – 2018-07-09T18:09:10.243

Just back from vacation... same bytecount, recursive tio

– JayCe – 2018-07-09T22:58:58.510

239 bytes: n=scan();while(print(n))n=sample(n,1)-1 – djhurio – 2018-07-10T13:45:03.263

6

MATL, 6 bytes

`tYrqt

Try it online!

Explanation

`        % Do...while
  t      %   Duplicate. Takes input (implicit) the first time
  Yr     %   Uniform random integer from 1 to n, included
  q      %   Subtract 1
  t      %   Duplicate. This will be used as loop condition
         % End (implicit). Proceeds with next iteration if non-zero
         % Display stack (implicit)

Luis Mendo

Posted 2018-07-09T12:11:17.537

Reputation: 87 464

6

Pepe, 25 bytes

Pepe is a programming language made by user Soaku.

REeErEErReEEreeEREEeEEree 

Try it online!

Explanation:

REeErEErReEEreeEREEeEEree # full program

REeE                      # input as num, in stack 1
    rEE                   # create loop in stack 2 with name 0
       rReEE              # - output and preserve the number in stack 1
            reeE          # - output a newline "\n"
                REEeEE    # - random number by 0 to input
                      ree # goto loop with name 0 if stack 1 is not equal
                            to stack 2

u_ndefined

Posted 2018-07-09T12:11:17.537

Reputation: 1 253

5

Perl 6, 18 bytes

{$_,(^*).pick...0}

Try it online!

Anonymous code block that returns a list of values. If you don't mind the numbers being ranges, you can do:

{^$_,^*.pick...0}

for 17 bytes. Funnily enough, another builtin random function, roll, has the same behaviour in this instance for the same amount of bytes.

Jo King

Posted 2018-07-09T12:11:17.537

Reputation: 38 234

5

Perl 5.10.0 -pl, 26 bytes

say;say while$_=int rand$_

Try it online!

wastl

Posted 2018-07-09T12:11:17.537

Reputation: 3 089

2

Nice! Came up with a very similar approach for 22: Try it online!

– Dom Hastings – 2018-07-09T14:03:58.297

Аnother similar: 20 + 2 bytes.

– Denis Ibaev – 2018-07-12T15:35:42.353

5

Jelly,  4  3 bytes

XƬ0

This is a monadic link (function) that prints an array and returns 0.

Try it online!

How it works

XƬ0  Monadic link. Argument: n

XƬ   Pseudo-randomly pick (X) an integer k in [1, ..., n], set n = k, and repeat.
     Do this 'til (Ƭ) the results are no longer unique and return the array of
     unique results, including the initial value of n.
     This stops once X returns k with argument k. The second k will be omitted
     from the return value.
  0  Print the resulting array and set the return value to 0.

Dennis

Posted 2018-07-09T12:11:17.537

Reputation: 196 637

Very nice strikethrough of the 4! – ngm – 2018-07-09T14:50:54.940

1We wouldn't like crossed out 4 to look like regular 4, would we? – Dennis – 2018-07-09T14:54:11.013

4

05AB1E, 8 7 bytes

Δ=L<Ω0M

Try it online!

Explanation

Δ         # loop until value doesn't change
 =        # print current value
  L<Ω     # push a random number in ([1 ... X] - 1)
          # will return -1 when X=0
     0M   # push max of that and 0

Emigna

Posted 2018-07-09T12:11:17.537

Reputation: 50 798

1Δ=ݨΩ0M is equivalent. – Magic Octopus Urn – 2018-07-09T18:01:45.883

4

JavaScript (ES6), 38 37 bytes

-1 byte thanks to @Arnauld

f=n=>[n,...n?f(Math.random()*n|0):[]]

f=n=>[n,...n?f(Math.random()*n|0):[]]
<input type=number id=a><button onclick="console.log(f(+a.value))">Test</button>

Herman L

Posted 2018-07-09T12:11:17.537

Reputation: 3 611

Can you reduce the math.random at all? e.g. with https://codegolf.stackexchange.com/a/35648/67066

– Marie – 2018-07-09T18:56:01.090

1@Marie using new Date%n doesn't really work here, since it doesn't change fast enough to be useful for generating multiple random numbers – Herman L – 2018-07-09T19:10:38.333

4

Brachylog, 8 bytes

ẉ?ℕ₁-₁ṙ↰

Try it online!

Explanation

ẉ          Write the input followed by a linebreak
 ?ℕ₁       The input must be in [1, …, +∞)
    -₁ṙ    Generate an integer in [0, …, input - 1] uniformly at random
       ↰   Recursive call with that random integer as the new input

The recursion will stop once ?ℕ₁ fails, that is, when the input is 0.

Fatalize

Posted 2018-07-09T12:11:17.537

Reputation: 32 976

4

J, 13 bytes

[:}:? ::]^:a:

On the subway, so apologies for lack of TIO (hopefully there isn’t a lack of correctness).

Outputs a list of values.

Presumably the APL approach will be shorter, but this is what I thought of.

How it works

^:a: apply repeatedly until convergence, storing intermediate results in an array.

? random integer in range [0, K) for K greater than 0. For 0, it gives a random integer in range (0,1). For a floating point number, it errors.

::] catch an error for an input to ? and instead of erroring, output the input that caused the error.

}: get rid of the last value in the array (this is so that a floating point number isn’t output).

Try it online!

cole

Posted 2018-07-09T12:11:17.537

Reputation: 3 526

It is just me or the code returns the same output? – Luis felipe De jesus Munoz – 2018-07-09T14:10:13.623

@LuisfelipeDejesusMunoz someone who knows J better than I might be able to explain but I think that RNG always starts with the same seed. There is also the fixed seed ?., but I don’t think I’m using that. – cole – 2018-07-09T14:22:15.700

@cole you are correct. – Jonah – 2018-07-09T14:46:09.840

4

C, 38 bytes

f(k){printf("%d ",k);k?f(rand()%k):0;}

Try it online

Ungolfed

void f(int k){
    printf("%d ",k);
    if(k)
        f(rand()%k);
}

Geo

Posted 2018-07-09T12:11:17.537

Reputation: 91

1

You can save a byte by replacing the ternary operator with a &&; also, you may want to consider seeding the RNG in your main function: Try it online!

– ErikF – 2018-07-09T18:56:49.477

1

You can also get rid of the ternary altogether and terminate in an error. 34 bytes

– Jo King – 2018-07-10T06:43:16.490

4

Pyth, 4 bytes

W
~O

Try it online!

This basically implements the algorithm:

\$ \begin{align} % Unknown environment algorithm :( &Q \gets \text{input} \\ &\mathbf{Repeat} \\ &\begin{array}{cl} 1. & temp \gets Q \\ 2. & Q \gets \text{unif}\{ 0, Q - 1 \} \\ 3. & \mathtt{Print}(temp) \end{array} \\ &\mathbf{Until} \quad temp = 0 \end{align} \$

To translate the Pyth into the algorithm, we can mostly just examine what each character means. Since Pyth is written in prefix notation (i.e. * + 1 2 3 is (1 + 2) * 3) we can start from the left and fill in the arguments as we go.

W begins a traditional while loop. The first statement after it is the loop condition and the second statement after it is the loop body. If the second statement is empty it becomes a no-op. This while works exactly like the Python while, so it will evaluate non-zero integers as True and zero as false.

The first statement after the while begins with the newline character. This corresponds to Pyth's "print and return with a newline" function. This takes one argument, which is then printed and also returned unmodified. This allows us to print the intermediate steps while also performing the needed operations.

The argument passed to this print function begins with ~ which is a bit special. If the character immediately after ~ is a variable it takes two arguments, otherwise it takes one. Since O is not a variable ~ will consume only one argument. ~ functions a bit like += does in many conventional languages, though the closest operator would be the post-increment operator ++ from C. You may know that x++ will be like using x as the current value, but thereafter x will be x+1. ~ is the same idea, but generalised to whatever the result of the first argument is. How it picks what variable to assign to will be addressed later.

The argument of ~ is O which is very simple. When its one argument is an integer O returns a value from 0 to one less than that integer uniformly at random.

Now you may have noticed O does not have an argument. Here the Pyth interpreter kindly fills in a guess, which here is the variable Q. Q has a special meaning in Pyth: whenever it is present in a program the Pyth program begins with assigning Q to the input of the program. Since this is the first variable occurring in ~'s argument Q is also now the variable that ~ will assign a value to.

Summed up our "readable" program might look like:

while print_and_return( assign_variable( Q, unif(0, Q-1) ) ):
    pass

And one sample "run-through" might look like:

  1. Q = 5
  2. O returns 3, ~ returns 5, \n returns and prints 5 which is true
  3. Q = 3
  4. O returns 0, ~ returns 3, \n returns and prints 3 which is true
  5. Q=0
  6. O returns something irrelevant, ~ returns 0, \n returns and prints 0 which is false
  7. Q = something irrelevant
  8. Terminate

FryAmTheEggman

Posted 2018-07-09T12:11:17.537

Reputation: 16 206

3

Python 2, 64 62 60 bytes

from random import*
k=input()
while k:print k;k=randrange(k)

Try it online!


Saved

  • -2 bytes, thanks to Jonathan Allan

TFeld

Posted 2018-07-09T12:11:17.537

Reputation: 19 246

"Input must be printed at first"... while 1:print k;k=randint(0,~-k) should work (with an error at the end) – Jonathan Allan – 2018-07-09T16:28:14.283

...and then while 1:print k;k=randrange(k) saves two. – Jonathan Allan – 2018-07-09T16:30:18.683

1@JonathanAllan Thanks :), The questions says I can use an empty line instead of 0, so no error. – TFeld – 2018-07-10T06:56:47.300

3

APL (Dyalog Unicode), 12 9 bytes

Anonymous tacit prefix function. Assumes ⎕IO (Index Origin) to be 0, which is default on many systems. Returns the final value (0) in addition to printing while run.

{⌊?⎕←⍵}⍣=

Try it online!

{}⍣= apply the following function until stable:

⎕←⍵ output the argument

? return a uniformly distributed random number in the range 0 through that–1

 round down (because ?0 gives a (0,1) float)

Adám

Posted 2018-07-09T12:11:17.537

Reputation: 37 779

3

C++ (gcc), 98 bytes

#import<cstdio>
#import<cstdlib>
#define d printf("%i ",x 
int p(int x){d);while(x>0)d=rand()%x);}

Try it here!

Usage

int main() {
    p(100);
}

This is my first code golf attempt. Any feedback or remarks are welcome.

Edit: Removed the main function as suggested to make it valid.

eKKiM

Posted 2018-07-09T12:11:17.537

Reputation: 131

1Hi, and welcome to PPCG :) You do not need to include the sample call in your byte count (i.e. you don't need to write the main function) since we accept functions as valid submissions. Otherwise, your submission is technically not valid since if the input was some two or more digit number the output could be ambiguous. If you just add a space at the end of the format string in your macro you should be fine. Happy golfing! – FryAmTheEggman – 2018-07-09T15:25:39.703

Adding the compiler flag -Dd='printf("%i,",x' instead of the #define would save you some bytes (-4), and is allowed as long as you count the bytes towards your result (because it is a non-standard preprocessor directive. You can also leave out the imports (at least with -std=c++98 and -w, which don't count for bytes), and the variable types. So, you'd have p(x){d);while(x>0)d=rand()%x;} and -Dd='printf("%i,",x'. – None – 2018-07-25T18:11:01.373

Also, you should probably check out the Standard Loopholes and Tips for golfing in C, if you haven't already :)

– None – 2018-07-25T18:15:51.013

3

C (gcc), 40 42 bytes

Some idiot™ forgot to print the initial value first.

f(K){while(K)printf("%d\n",K,K=rand()%K);}

Don't panic.

SIGSTACKFAULT

Posted 2018-07-09T12:11:17.537

Reputation: 585

You tied me, the question also requires that you print the initial K. Without it I also got 40. You can also get the 42 fully compliant version in a similar way: f(K){while(K)printf("%d\n",K),K=rand()%K;}. Still you got my +1 for an equal solution! – LambdaBeta – 2018-07-09T17:26:08.430

Even better: f(K){while(K)printf("%d\n",K,K=rand()%K);} – SIGSTACKFAULT – 2018-07-09T17:47:02.490

3

x86 + rdrand, 19 bytes

Straightforward implementation. Takes input K in ecx and outputs to a buffer in ebx.

0000000a <start>:
   a:   0f c7 f0                rdrand %eax
   d:   31 d2                   xor    %edx,%edx
   f:   f7 f1                   div    %ecx
  11:   89 13                   mov    %edx,(%ebx)
  13:   83 c3 04                add    $0x4,%ebx
  16:   89 d1                   mov    %edx,%ecx
  18:   85 c9                   test   %ecx,%ecx
  1a:   75 ee                   jne    a <start>
  1c:   c3                      ret  

qwr

Posted 2018-07-09T12:11:17.537

Reputation: 8 929

3

MATLAB (49 46 bytes)

@(k)eval('while k;disp(k);k=randi(k)-1;end;0')

Sample output:

>> @(k)eval('while k;disp(k);k=randi(k)-1;end;0')
ans(5)

ans = 

    @(k)eval('while k;disp(k);k=randi(k)-1;end;0')

     5    
     3    
     2    
     1   

ans =    
     0

aaaaa says reinstate Monica

Posted 2018-07-09T12:11:17.537

Reputation: 381

1I suppose you can do k=randi(k)-1 for a few bytes less. – Sanchises – 2018-07-11T13:16:41.017

3

TI-Basic (TI-84 Plus CE), 17 13 bytes

While Ans
Disp Ans
int(randAns
End
Ans

-4 bytes from Misha Lavrov

Takes input in Ans as 50:prgmNAME.

TI-Basic is a tokenized language. All tokens used here are one byte.

Explanation:

While Ans    # 3 bytes, While the number we hold is not zero:
Disp Ans     # 3 bytes,   Display it on its own line
int(randAns  # 4 bytes,   and replace it with a number randomly
                        # chosen from 0 to one less than it (inclusive)
End          # 2 bytes, end While loop
Ans          # 1 byte,  Display (and return) zero

An 11-byte solution suggested by Misha Lavrov that requires pressing enter after each line following the first.

Ans
While Ans
Pause int(randAns
End

pizzapants184

Posted 2018-07-09T12:11:17.537

Reputation: 3 174

1int(Ansrand is shorter. Also, using Pause instead of Disp, you can make the only statement in the loop be Pause int(Ansrand, which also updates Ans. – Misha Lavrov – 2018-07-10T03:37:19.053

3

Python 3, 39 bytes

f=lambda k:print(k)or f(hash('.'*k)%k)

Probably not the most cryptographically secure random number generator but to the human eye it looks random enough...

Try it online!

Luca Citi

Posted 2018-07-09T12:11:17.537

Reputation: 229

Notes: 1) the entry gives (usually) different results every time it's run in a new interpreter but may give the same result if run within the same python session. 2) I assume that terminating through an error without explicitly checking for k=0 is acceptable. – Luca Citi – 2018-07-10T00:42:45.883

Sorry, but functions must be reusable arbitrarily often in the same environment. Terminating in an error is acceptable though

– Jo King – 2018-07-10T06:36:54.863

The task requires a uniform random number from the given range. hash() tries to maintain but doesn't guarantee this property. For that task you should use the random module. – David Foerster – 2018-07-10T12:41:38.763

With only 57 bytes you can amend your solution to use uniformly random numbers from random.randrange(): from random import*;f=lambda k:print(k)or f(randrange(k)) – David Foerster – 2018-07-10T13:29:27.413

3

><>, 92+2 Bytes

:nao:0=?;0_1>:{:}(?\\
}(?!\$2*1>x~\$+1$*2/\~00:{{:@}
8+1.\~:{:}\+>$1+f
~~@~~47*0.\(a2*1@@?!.

+2B for -v flag

Try it online!

><>'s only source of randomness comes from the 'x' instruction, which sets the instruction pointer's direction to a random value. As such, generating a random number from 0 to n isn't trivial.

I first calculate how many bits are required to represent a number in the range [0,n), then generate random bits to generate a random number. This leaves the possibility that it'll generate a number slightly larger than n, in which case we just discard it and try again.

Explanation:

:nao                              Print the current number followed by a newline
    :0=?;                         If the current n is 0, terminate

Calculate how many random bits we need to be generating:
         0 1                      Initialise the variables for this loop: 
                                      numberOfBits = 0, maxValue = 1
             :{:}(?\              If maxValue >= n, break out of the loop
                 *2               maxValue *= 2
             $+1$                 numberOfBits += 1

Generate the random number:
                     ~            Delete maxValue
                      00          Initialise randomNumber = 0, i = 0
}(?!\                   :{{:@}    If i >= numberOfBits, break out of the (inner) loop
     $2*                          randomNumber *= 2
          _
        1>x~\                     The random bit: If the IP goes up or 
          \+>                     left, it'll be redirected back onto the 'x', 
                                  if it goes down, it adds one to randomNumber
                                  If it goes right, it does nothing to randomNumber

             $1+                  increment i
8+1.            f                 Jump back to the start of the inner loop

After we've generated our number, check that it's actually below n
     ~                            Delete i
      :{:} (      ?               Test that the number is less than n
            a2*1    .             If it's not, jump back to the start 
                                  of the number generation section
  @~~                             Otherwise delete the old value of n, and numberOfBits
     47*0.                        Then jump back to the start of the program

Sasha

Posted 2018-07-09T12:11:17.537

Reputation: 431

Very nice! I came up with the same idea independently; without whitespace, my solution uses several characters fewer than yours, but you've managed to make a much more compact block of code. – Théophile – 2018-07-17T01:05:07.000

2The current meta consensus is that you don't have to count the bytes used on flags – Jo King – 2018-07-17T06:19:35.127

2

Retina, 21 bytes

.+
*
L$`.
$.`
+¶<)G?`

Try it online! Explanation:

+

Repeat until the value stops changing (i.e. 0).

¶<)

Print the value before each pass through the loop.

.+
*

Convert to unary.

L$`.
$.`

Create the range and convert to decimal.

G?`

Pick a random element.

Neil

Posted 2018-07-09T12:11:17.537

Reputation: 95 035

2

PHP, 43 42 bytes

<?while($a=$a?rand(0,$a-1):$argn)echo$a?>0

To run it:

echo '<input>' | php -nF <filename>

Or Try it online!

Example output:

10019128410

-1 byte thanks to Titus's suggestion.

Ethan

Posted 2018-07-09T12:11:17.537

Reputation: 435

rand(0,$a) get a number between 0 and $a included. As $a should not be a possible value, the max argument for rand must be $a-1 – Med – 2018-07-11T09:54:09.760

Right you are @Med! Thanks for letting me know, I've updated my answer. – Ethan – 2018-07-11T11:32:39.767

1Why don´t you just append 0 instad of two newlines? – Titus – 2018-07-30T15:42:02.613

Thanks @Titus! That's very helpful, I've updated my solution (-1 byte). – Ethan – 2018-07-30T16:00:31.087

2

Pyth, 6 7 bytes

QWQ=OQQ

Try it online!

+1 to print the initial input value.

While Q is truthy, set Q to be a random integer between 0 and Q and print Q.

Not the shortest Pyth answer but I'm just learning and only posting because of the recent discussion about no-one using Pyth any more :)

ElPedro

Posted 2018-07-09T12:11:17.537

Reputation: 5 301

2

I managed to tie using cumulative reduce but keeping it as a procedural program. Thanks for the motivation to work on a golf :)

– FryAmTheEggman – 2018-07-09T15:16:18.493

That's cool. Still trying to work out how (why) it works. – ElPedro – 2018-07-09T16:07:44.050

By default, both = and ~ use the first variable of an expression as the variable that will be assigned if one isn't specified. For example ~hT will set T to 11 while returning 10. The only other fancy trick is that the newline character prints its input and then returns that value unmodified, so we can have an empty loop body. Let me know if something else is confusing :) – FryAmTheEggman – 2018-07-09T21:54:50.953

The whole lot is confusing with golfing languages. I'm used to Python and Java every day. Thanks for the explanation though. Much appreciated. I'll keep learning :) – ElPedro – 2018-07-09T22:08:28.907

1@FryAmTheEggman That's beautiful. – isaacg – 2018-07-11T05:31:03.010

1@isaacg Thanks! I originally meant for it to just be edited in here, but I decided to write something up since I wanted to try MathJax. These kinds of Pyth answers were always my favourite since they feel both intentional but also abusive :) – FryAmTheEggman – 2018-07-11T20:26:23.817

2

Haskell, 74 71 bytes

-3 bytes by actually doing what the specs say it should do.

import System.Random
f 0=pure[0]
f x=randomRIO(0::Int,x-1)>>=fmap(x:).f

Try it online!

ბიმო

Posted 2018-07-09T12:11:17.537

Reputation: 15 345

2

Java, 56 bytes

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

Try It Online

Acknowledgments

Jakob

Posted 2018-07-09T12:11:17.537

Reputation: 2 428

2(int)(Math.random()*n) can be golfed to n*=Math.random() – Kevin Cruijssen – 2018-07-19T09:59:18.570

2

IBM/Lotus Notes Formula, 48 bytes

o:=i;@While(i>0;i:=@Integer(i*@Random);o:=o:i);o

Field formula that takes input from another field i.

There's no TIO for formula so here's a screenshot of a sample output:

enter image description here

ElPedro

Posted 2018-07-09T12:11:17.537

Reputation: 5 301

2

Powershell, 36 32 bytes

-4 bytes thanks AdmBorkBork

filter f{$_;if($_){Random $_|f}}

Testscript:

filter f{$_;if($_){Random $_|f}}

100 |f

Output:

100
61
20
8
6
3
0

mazzy

Posted 2018-07-09T12:11:17.537

Reputation: 4 832

2

The Get- is implied, so you can remove it for -4 bytes Try it online!

– AdmBorkBork – 2018-07-09T18:08:16.147

2

PowerShell, 35 bytes

for($a="$args";$a;$a=Random $a){$a}

Try it online!

Full program. Takes input $args, stores it into $a, and enters a for loop. Each iteration we're checking whether $a is still positive (as 0 is falsey in PowerShell). Then we leave $a on the pipeline and move to the next iteration, where we set $a to be the result of Get-Random $a, which returns an integer in the range 0..($a-1).

(Ab)uses the fact that PowerShell outputs an additional trailing newline in lieu of outputting the final zero (allowed by the rules as currently written).

AdmBorkBork

Posted 2018-07-09T12:11:17.537

Reputation: 41 581

"$args" - nice. I was stuck on $args[0] in this case – mazzy – 2018-07-09T20:29:07.047

2

Lua, 58 bytes

p,r=print,...+0 p(r)while r>0 do r=math.random(0,r)p(r)end

Try it online!

For some more Lua love here :)

Lycea

Posted 2018-07-09T12:11:17.537

Reputation: 141

Hey, you can remove the +0 on the r declaration and move it to the r on the while statement, by doing so you'll use 1 less byte for the space (p,r=print,...p(r)while). – Visckmart – 2018-07-29T04:14:11.910

2

C# (Visual C# Interactive Compiler), 84 82 bytes

var k=int.Parse(ReadLine());for(Write(k);k>0;)Write($",{k=new Random().Next(k)}");

Try it online!

-2 Bytes thanks to charliefox2

Explenation:

var k = int.Parse(ReadLine());   //1. Read a line from STDIN and convert it to int
for(Write(k);                    //2. Write the original value of k to STDOUT
        k>0;)                    //3. Loop while k > 0
    Write($",{                   //6. Write the separator and the new value to STDOUT
        k =                      //5. Assign it to k
        new Random().Next(k)}"); //4. Get a random int between 0 (inclusive) and k (exclusive)

raznagul

Posted 2018-07-09T12:11:17.537

Reputation: 424

I think you could save a couple of bytes by using Write() instead of WriteLine() and using string formatting to add a separator, e.g. Write($",{k=new Random().Next(k)}" since OP said output format doesn't matter – charliefox2 – 2018-07-10T21:03:42.380

@charliefox2: No, that would be 2 bytes longer. – raznagul – 2018-07-11T08:41:32.010

How can you use WriteLine and ReadLine without the Console Prefix? – Snowfire – 2018-07-11T11:14:09.860

@raznagul not if you do it for WriteLine(k) as well. var k=int.Parse(ReadLine());for(Write(k);k>0;)Write($",{k=new Random().Next(k)}"); should save you 2 bytes – charliefox2 – 2018-07-11T12:51:40.197

@charliefox2: Thanks, I totally missed that. – raznagul – 2018-07-11T13:32:16.590

1@Snowfire: Try it Online automatically includes using static System.Console for C# Interactive Compiler. – raznagul – 2018-07-11T13:36:27.927

2

CJam, 7 9 bytes

ri{_pmr}h

Try it online!

Annotated

r       e# read input token
i       e# convert to int
{       e# do {
    _   e# duplicate topOfStack
    p   e# pop topOfStack and print it
    mr  e# rand(0, topOfStack)
}h      e# } while(topOfStack != 0)
        e# implicitly convert stack to string and print it

Siguza

Posted 2018-07-09T12:11:17.537

Reputation: 719

2

Bash, 65 58 56 50 bytes

f()(echo ${a=$1};for((;a;)){ echo $[a=RANDOM%a];})

Try it online!

(Improved thanks to manatwork)

Recursive approach

50 28

f()(echo $1&&f $[RANDOM%$1])

Try

Bazil

Posted 2018-07-09T12:11:17.537

Reputation: 31

1

“Input must be printed at first”. Try with more Bash specific syntax.

– manatwork – 2018-07-10T20:08:57.240

Welcome to PPCG! :) – Shaggy – 2018-07-11T09:39:20.347

Grr! I always forget the {..} enclosed for block which can reduce it to 50 characters.

– manatwork – 2018-07-11T14:15:40.197

Thanks for your welcome. I've discovered a few cool bash tricks which i didn't know before. :) – Bazil – 2018-07-11T21:27:19.310

If you reverse the logic, you not need if and exit: f()(echo $1;(($1))&&f $[RANDOM%$1]). Or with an error message even f()(echo $1&&f $[RANDOM%$1]). – manatwork – 2018-07-12T14:16:27.467

Yeah right. I've seen this in post with tips,but for some reason I still thought && is logical AND like in some other languages. – Bazil – 2018-07-12T14:59:08.793

2

Atari 400/800 6502 Assembler – 16 bytes

K set initially to #$FF (but can set to any byte value), then calls the POKEY PRNG at $D20A, if greater than or equal, try again, else save as the new upper limit. Keep going until it reaches zero.

define K $FF
* = $600
    LDA #K
.1: STA $80
    BEQ .3
.2: LDA $D20A
    CMP $80
    BCC .1
    BCS .2
.3: BRK       ; if you assume memory is cleared, can omit for 15 bytes

Which, when assembled, is:

a9 ff 85 80 f0 09 ad 0a d2 c5 80 90 f5 b0 f7 00

Output is by running a monitor, single stepping, and spying on $80! The rules indicated “output format as you wish”!

user15259

Posted 2018-07-09T12:11:17.537

Reputation:

Most likely you need to print or write to buffer. Leaving a value in memory is unreasonable unless it is not possible to print or do any kind of I/O. See https://codegolf.meta.stackexchange.com/questions/2447/default-for-code-golf-input-output-methods

– qwr – 2018-07-26T19:57:12.070

2

C# (.NET Core), 71 bytes

Using recursion.

static int f(int k){Console.WriteLine(k);return k==0?k:f(r.Next(0,k));}

Try it online!

Output:

100
9
3
0

Vincino

Posted 2018-07-09T12:11:17.537

Reputation: 21

2

><>, 147 + 2 bytes

 :0=?\:0&:0=?\:2%-2,&1+&80.
   ;n/       \r:r&:0=?\1-&2*\
          /oan:{/?(}:~/44+\ v
<         \:0=?;>{~00.\*1.^0x
                          \1/

Try it online!

The idea is the same as @Sasha's—generate random bits, making sure not to exceed the original number—but just in a different layout. My solution uses the register to record the number of bits of n.

There is unfortunately a certain amount of wasted space, particularly on the last line.

How it works:

 :0=?\:0&                      n = 0?   No: duplicate n; let reg = 0
   ;n/                                  Yes: print then end

         :0=?\:2%-2,&1+&80.    n = 0?   No: n = floor(n / 2); increment reg; loop to (8,0)
             \                          Yes: enter loop to construct random number r

              r:r&:0=?\1-&2*\  reg = 0? No: r = 2 * r + (0 or 1); loop to (16, 1)
                      /44+\ v           Yes: check if r <= n
<                     \*1.^0x           
                          \1/

          /oan:{/?(}:~         r > n?   No: print r and newline; 
          \:0=?;>

                 {~00.         Go back to (0,0), using either r or n

Théophile

Posted 2018-07-09T12:11:17.537

Reputation: 263

You could do something like this to get rid of that last line

– Jo King – 2018-07-17T06:35:37.077

1

Or reversing the whole thing (91 bytes)

– Jo King – 2018-07-17T07:01:39.007

2

Kotlin, 60 bytes

fun f(k:Int){println(k);if(k>0)f((Math.random()*k).toInt())}

Try it online!

Solution with recursion.

YGolybev

Posted 2018-07-09T12:11:17.537

Reputation: 111

1random is function from java.lang.Math, isn't it? java.lang.Math module is required explicit import or Math.random() code – mazzy – 2018-07-25T07:39:23.560

2

J, 8 bytes

?^:*^:a:

Try it online!

How it works

f^:g^:_ is a J idiom for "do while", which means to repeatedly apply f to the input while g gives true. g should always give 0 or 1. Change the last _ (infinity) to a: (boxed empty), and the resulting verb gives the list of intermediate values.

Monadic ? is "roll", i.e. given N, generates a random integer between 0 and N-1 inclusive. Monadic * is "signum", i.e. gives 1 for positive, 0 for zero, -1 for negative input.

Bubbler

Posted 2018-07-09T12:11:17.537

Reputation: 16 616

1

Charcoal, 11 bytes

IθW⊟θI⊞Oθ‽ι

Try it online! Link is to verbose version of code. Slightly unusual input format. Explanation:

Iθ

Cast the input to string and print it.

W⊟θ

While the input is non-zero...

⊞Oθ‽ι

... replace it with a random number in the implicit range...

... and cast the result to string and print it.

13-byte version with more standard input format:

θNθWθ«≔‽θθ⸿Iθ

Try it online! Link is to verbose version of code.

Neil

Posted 2018-07-09T12:11:17.537

Reputation: 95 035

1

Jelly, 6 bytes

X’$¹Ð¿

Try it online!

Erik the Outgolfer

Posted 2018-07-09T12:11:17.537

Reputation: 38 134

XƬ;0 saves two since it'll stop when the randrange(1,x+1) returns x at which point we have our 0 :) EDIT: Oh, I just scrolled and saw Dennis's answer. – Jonathan Allan – 2018-07-09T16:23:01.423

@JonathanAllan Dennis's previous revision? Bah. – Erik the Outgolfer – 2018-07-09T16:23:58.310

1

JavaScript, 34 bytes

Outputs a space-delimited string of integers.

f=n=>n&&n+" "+f(Math.random()*n|0)

Try it online

Shaggy

Posted 2018-07-09T12:11:17.537

Reputation: 24 623

1

Ruby, 31 29 bytes

->n{n=rand p n until 1>n;p 0}

Try it online!

Reinstate Monica -- notmaynard

Posted 2018-07-09T12:11:17.537

Reputation: 1 053

1

Red, 41 bytes

func[n][print n if 0 < n[f random n - 1]]

Try it online!

Galen Ivanov

Posted 2018-07-09T12:11:17.537

Reputation: 13 815

1

Batch, 54 bytes

@echo %1&if %1 gtr 0 set/an=%random%%%%1&call %0 %%n%%

Four %s in a row... just a typical day for Batch. Only works up to 32768 (and not terribly uniform at that) due to limitations of Batch's random number generator. See my Batch answer to Pick a random number between 0 and n using a constant source of randomness for large uniform randomness.

Neil

Posted 2018-07-09T12:11:17.537

Reputation: 95 035

1

Japt, 10 bytes

Outputs an array of integers.

_Ì}f@NpU=ö

Try it


Explanation

               :Implicit input of integer U
  }f           :Loop until left function returns falsey and return final value of right function
    @          :Right function
         ö     :  Random integer in the range [0,U)
       U=      :  Reassign to U
      p        :  Push
     N         :   To the array of inputs
_              :Left function
 Ì             :Get the last element of N. If it's 0, which is falsey, then the loop will be broken

Alternative, 8 bytes

A direct port of my JavaScript solution.

©U+S+ßUö

Try it

Shaggy

Posted 2018-07-09T12:11:17.537

Reputation: 24 623

1

Excel VBA, 42 bytes

An anonymous function that takes input from range [A1] and outputs to the console.

k=[A1]:?k:While k:y=Int(k*Rnd):?y:k=y:Wend

Taylor Scott

Posted 2018-07-09T12:11:17.537

Reputation: 6 709

1

Python 2.7, 112 bytes

from random import randint
k=int(raw_input())
def r(k):
    y=randint(0, k-1)
    print y
    if y!=0:
        r(y)
r(k)

StealthyPanda

Posted 2018-07-09T12:11:17.537

Reputation: 41

This does not quite meet the spec, as it does not print the first number. Consider modifying your code to something like this

– Taylor Scott – 2018-07-09T18:48:56.747

Also, you can save bytes by removing whitespace and submitting as a function instead of a full program – Jo King – 2018-07-10T06:38:43.560

I see that you've been posting mostly Python answers. Have you had a look at Tips for golfing in Python?

– Jo King – 2018-07-10T06:46:07.247

1

F#, 70 bytes

let r=System.Random()
let rec x K=printfn"%i"K;if K>0 then r.Next K|>x

Try it online!

Ciaran_McCarthy

Posted 2018-07-09T12:11:17.537

Reputation: 689

2The rules say "Input must be printed at first". – Ciaran_McCarthy – 2018-07-09T18:43:45.690

1I do apologise... no idea how I missed that, having already looked at half a dozen answers. – VisualMelon – 2018-07-09T18:47:10.847

1

Julia 0.6, 33 bytes

~n=(println(n);n>0&&~rand(0:n-1))

Try it online!

Defines the function as an operator ~ (to save bytes). Print the given number, and if we haven't reached 0, call itself recursively with a new uniformly random number from range 0:n-1.

(Could've used @show instead of println since OP says "output format as you wish" (@show prints the variable name before the value every time, eg. n = 8 instead of 8), but the 2 byte saving doesn't seem worth it relative to total bytecount, and I like this neater output.)

sundar - Reinstate Monica

Posted 2018-07-09T12:11:17.537

Reputation: 5 296

1

AWK, 56 bytes

{print($0);k=$0;for(srand();k>0;)print(k=int(k*rand()))}

Try it online!

Noskcaj

Posted 2018-07-09T12:11:17.537

Reputation: 421

1

Pascal (FPC), 89 bytes

var K:word;begin Randomize;read(K);repeat writeln(K);K:=Random(K)until K<1;writeln(K)end.

Try it online!

Not only Pascal code is as long as usual, you also need to Randomize; beforehand...

Instead of writing of the initial value before the loop, 0 is written after the loop. This approach saves a byte because 1end. isn't valid; instead od separating this into 2 tokens, it tries to find a meaningful scientific notation.

AlexRacer

Posted 2018-07-09T12:11:17.537

Reputation: 979

1

Ruby, 23 bytes

f=->k{k<1||f[rand p k]}

Try it online!

Non-recursive, 25 bytes

->k{k=rand p k while k>0}

Try it online!

->k{(k=rand p k)>0&&redo}

Try it online!

Asone Tuhid

Posted 2018-07-09T12:11:17.537

Reputation: 1 944

1

MATLAB, 36 bytes

K
Y=1;while Y>0,Y=randi(K)-1;K=Y,end

Sample output: For K = 25

K =

    25


K =

    15


K =

    11


K =

     6


K =

     4


K =

     1


K =

     0

Jacob Watson

Posted 2018-07-09T12:11:17.537

Reputation: 131

1

Racket, 52 bytes

(define(f n)(println n)(unless(= n 0)(f(random n))))

Try it online!

potato

Posted 2018-07-09T12:11:17.537

Reputation: 339

1

Julia 0.6, 49 bytes

~x=(println(x);x-1)
!x=(y=rand(0:~x))>0 ? !y : ~0

Try it online!

If one were willing to accept outputting all output except the last to STDOUT, and the last 0 as returning false, then it can be

~x=(println(x);x-1)
!x=(y=rand(0:~x))>0&&!y

Which is a bit short. But I think mixing outputs like that is not really in spirit.

Lyndon White

Posted 2018-07-09T12:11:17.537

Reputation: 1 021

1

K4, 13 12 11 bytes

Solution:

(*1?)\[0<;]

Examples:

q)k)(*1?)\[0<;] 100
100 77 30 17 12 2 0
q)k)(*1?)\[0<;] 100
100 37 28 20 2 0
q)k)(*1?)\[0<;] 100
100 77 61 55 53 6 2 0
q)k)(*1?)\[0<;] 100
100 12 1 0

Explanation:

Iterate over expression while x is greater than zero.

(*1?)\[0<;] / the solution
(   )\[0<;] / iterate over brackets whilst 0< evaluates true
  1?        / 1 choose (returns a 1-item list)
 *          / take the first

Bonus:

A 14 byte solution that also works in K (oK); this one is an if/else version of the same theme:

{$[x;*1?x;x]}\

Try it online!

streetster

Posted 2018-07-09T12:11:17.537

Reputation: 3 635

1

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.

Delioth

Posted 2018-07-09T12:11:17.537

Reputation: 221

def f(n,k) when n <= 0 can be shortened to def f(0,k) – Okx – 2018-07-29T11:34:03.953

1

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

JPeroutek

Posted 2018-07-09T12:11:17.537

Reputation: 734

1

Elixir, 87 bytes

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

Try it online!

Okx

Posted 2018-07-09T12:11:17.537

Reputation: 15 025

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). – Delioth – 2018-07-30T13:50:34.887

@Delioth fixed. – Okx – 2018-07-30T14:13:43.580

1

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.

Titus

Posted 2018-07-09T12:11:17.537

Reputation: 13 814

1

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

Beta Decay

Posted 2018-07-09T12:11:17.537

Reputation: 21 478

1

Swift 4, 30 bytes

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

Try it online!

n is the value of input

buttercrab

Posted 2018-07-09T12:11:17.537

Reputation: 169

1

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

reffu

Posted 2018-07-09T12:11:17.537

Reputation: 1 361

1

Julia 1.0, 53 bytes

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

Try it online!

Rustem B.

Posted 2018-07-09T12:11:17.537

Reputation: 51

1

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

mudkip201

Posted 2018-07-09T12:11:17.537

Reputation: 833

At the TIO link, this always just outputs 0. Am I missing something? – DLosc – 2018-09-23T04:22:15.763

1

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

georgewatson

Posted 2018-07-09T12:11:17.537

Reputation: 291

0

PHP 5.6

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

Sankar Subburaj

Posted 2018-07-09T12:11:17.537

Reputation: 101

2

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.

– manatwork – 2018-09-21T12:39:39.860

1

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

– manatwork – 2018-09-21T12:54:57.503