This will eventually stop…

41

3

Given an input string S, print S followed by a non-empty separator in the following way:

  • Step 1: S has a 1/2 chance of being printed, and a 1/2 chance for the program to terminate.

  • Step 2: S has a 2/3 chance of being printed, and a 1/3 chance for the program to terminate.

  • Step 3: S has a 3/4 chance of being printed, and a 1/4 chance for the program to terminate.

  • Step n: S has a n/(n+1) chance of being printed, and a 1/(n+1) chance for the program to terminate.

Notes

  • The input string will only consist of characters that are acceptable in your language's string type.

  • Any non-empty separator can be used, as long as it is always the same. It is expected that the separator is printed after the last print of S before the program terminates.

  • The program has a 1/2 chance of terminating before printing anything.

  • A trailing new line is acceptable.

  • Your answer must make a genuine attempt at respecting the probabilities described. Obviously, when n is big this will be less and less true. A proper explanation of how probabilities are computed in your answer (and why they respect the specs, disregarding pseudo-randomness and big numbers problems) is sufficient.

Scoring

This is , so the shortest answer in bytes wins.

Fatalize

Posted 2017-06-12T06:54:02.633

Reputation: 32 976

Can the separator be an empty string? – rturnbull – 2017-06-12T07:13:54.133

16@rturnbull Well no, because in that case there is no separator. – Fatalize – 2017-06-12T07:18:29.167

Do we have to print these one after the other, or can we just print all of them when the program terminates? – Dennis – 2017-06-12T18:21:34.760

@Dennis One after the other. – Fatalize – 2017-06-13T06:42:46.447

Answers

18

Pyth, 7 bytes

WOh=hZQ

Try it online!

How it works

Pseudocode:

while rand_int_below(1 + (Z += 1)):
    print(input)

Leaky Nun

Posted 2017-06-12T06:54:02.633

Reputation: 45 011

Pyth beats 05AB1E again doesn't it? – Erik the Outgolfer – 2017-06-12T08:47:28.287

Doesn't the print statement need it's own probability along with the termination probability? – tuskiomi – 2017-06-14T15:13:56.073

1@tuskiomi Nah, n/(n+1) is just 1-1/(n+1), or 1 - (probabilty of termination). – Adowrath – 2017-06-14T21:41:57.137

29

C#, 94 85 bytes

My first answer!

using System;s=>{var r=new Random();for(var i=2;r.Next(i++)>0;)Console.Write(s+" ");}

Previous attempt (I liked that goto):

using System;s=>{var i=2;var r=new Random();a:if(r.Next(i++)>0){Console.Write(s+" ");goto a;}}

Ungolfed:

using System;
class P
{
    static void Main()
    {
        Action<string> f = s =>
        {
            var r = new Random();
            for (var i = 2; r.Next(i++) > 0;) Console.Write(s + " ");
        };

        f("test");

        Console.ReadKey();
    }
}

Note: in C# the Random.Next(N) method returns a nonnegative integer in the [0, N-1] range, so we can just check that the number returned is greater than 0.

Charlie

Posted 2017-06-12T06:54:02.633

Reputation: 11 448

1You need to include using System; into your byte count. You can declare r inline, no need to set it to a variable: new Random().Next(i++). You don't need the trailing semicolon on the golfed func. – TheLethalCoder – 2017-06-12T08:25:49.353

1Oh and nice first answer! Would have been shorter than my attempt :) – TheLethalCoder – 2017-06-12T08:27:17.113

@TheLethalCoder thank you for your comments! I tried to use new Random().Next(i++) but when I tried to execute that, the result was always either the program stops without printing anything, or the program never stops. When I declare r=new Random() and use the r variable, the program stops more randomly as the OP asks. – Charlie – 2017-06-12T08:34:13.723

Ahhh probs because the loop is so tight. – TheLethalCoder – 2017-06-12T08:36:10.880

2

@TheLethalCoder - Yes, thight loop means a chance that the seed of the generator will be the same. See: https://msdn.microsoft.com/en-us/library/system.random.aspx#Instantiate

– Erno – 2017-06-14T06:04:11.750

12

R, 47 46 43 bytes

43 bytes due to Robin Ryder in the comments.

s=scan(,"")
while(sample(T<-T+1)-1)print(s)

Try it online!

Explanation

s=scan(,"")  # Takes input from stdin.
             T<-T+1    # T is 1 by default, so this
                       # evaluates to 2, and will increment
                       # at each step.
      sample(T<-T+1)   # Take a sample of size 2, i.e. generate
                       # a list of integers from 1 to 2 in random order
      sample(T<-T+1)-1 # Subtract one from every element of this list.
while(sample(T<-T+1)-1)# while() will treat the first value in this list
                       # as a logical value, i.e. FALSE for zero and TRUE
                       # for nonzero values. The other elements of the list
                       # are ignored, triggering a warning.
                       print(s) # print s

rturnbull

Posted 2017-06-12T06:54:02.633

Reputation: 3 689

Does this ever terminate? – mflo-ByeSE – 2017-06-13T04:53:23.650

@mfloren Yes, like all the other answers here, it's stochastic, with termination chance decreasing as it progresses, but it will eventually terminate. There's a .5 chance it will print nothing! Try running it several times and compare the outputs. – rturnbull – 2017-06-13T07:59:27.817

function(s) is shorter than s=scan(,''); – JAD – 2017-06-13T13:55:27.553

1And pryr::f(while(runif(1)<T/(T<-T+1))print(s)) is even shorter. – JAD – 2017-06-13T13:59:22.253

Ran it about 25 times, each time the number of iterations continued until I stopped the operation. – mflo-ByeSE – 2017-06-13T14:35:06.727

Update: Ran it on R 3.3.2 and worked fine. Just updated to R 3.4.0 and didn't ever terminate (after another 20 tries). – mflo-ByeSE – 2017-06-13T14:47:04.153

1

@JarkoDubbeldam Unfortunately you can't (ab)use T and F with anonymous functions, as it modifies a global variable and means that the function can only be called once. See here: "the solution function performs consistently regardless of how many times it has been called previously".

– rturnbull – 2017-06-14T08:36:07.287

@mfloren That's very odd! I can't see anything in the update notes to suggest what might have changed about the language spec to cause that. For now, I've modified the post to specify that it's just R version 3.2 and below. – rturnbull – 2017-06-14T08:38:16.483

@mfloren After testing around with the latest version of R, it seems to work fine on my machine. Half the time it doesn't output anything. – rturnbull – 2017-06-14T08:55:03.423

@rturnbull Bizarre! Well: sorry for the fuss! I'll start hunting around on my installations and see what is going on... – mflo-ByeSE – 2017-06-14T13:33:24.597

@rturnbull Ah, I think I have it! I was not resetting T=1 on every new run (so T was constantly building). Again, apologize for the fuss and thanks for the help! – mflo-ByeSE – 2017-06-14T13:36:41.267

As far as I can tell, your code is 47 bytes, not 46. Here is a 43 byte version.

– Robin Ryder – 2019-10-06T07:59:55.710

@RobinRyder It's 46, not 47. I've updated the post with your (excellent!) version now. – rturnbull – 2019-10-07T18:50:01.603

11

05AB1E, 8 bytes

[NÌL.R#,

Try it online!

Explanation

[         # start loop
 NÌL      # push range [1 ... current_iteration+2]
    .R    # pick a random number
      #   # if true (1), exit loop
       ,  # print input

Emigna

Posted 2017-06-12T06:54:02.633

Reputation: 50 798

@Fatalize: It does for me. Try running it a few times. It has a 50% chance of not outputting anything so you may have been "unlucky". – Emigna – 2017-06-12T08:08:58.897

11The inherit problem of random tasks. Sometimes all odds are against you. – J_F_B_M – 2017-06-12T08:34:11.467

@J_F_B_M inherent? – Leaky Nun – 2017-06-12T14:55:59.417

1@LeakyNun No, it's the "Inherit Problem" (the probability of events is not inherited from previous events). J_F_B_M was clearly referring to the Gambler's Fallacy. – aebabis – 2017-06-12T19:52:47.500

11

Javascript, 60 58 54 bytes

f=(s,n=1)=>Math.random()<n/++n?console.log(s)+f(s,n):0

Will output string s. The seperator which is printed if the program terminates is NaN or 0.

f=(s,n=1)=>Math.random()<n/++n?console.log(s)+f(s,n):0

f('test')

Math.random() returns a value between 0 and 1. If that value is under n/(n+1), then s will be pritned.

4 bytes saved thanks to @Neil

Thomas W

Posted 2017-06-12T06:54:02.633

Reputation: 746

1Why not use n/++n? – Neil – 2017-06-12T09:00:24.567

1@Neil thanks, saved 4 bytes! – Thomas W – 2017-06-12T09:03:28.277

2If your environment was a browser you could use alert instead of console.log to save 6 bytes - the snippet could set alert = console.log to show non obtrusive output if desired (if allowed - doesn't save bytes, just helps keep one sane) – Craig Ayre – 2017-06-12T13:45:05.497

10

Java 8, 72 62 61 bytes

s->{for(int n=2;Math.random()<1f/n++;System.out.println(s));}

-10 bytes thanks to @cliffroot.
-1 byte thanks to @JollyJoker.

Delimiter is a new-line.

Explanation:

Try it here.

s->{                          // Method with String parameter and no return-type
  for(                        //  Loop
    int n=2;                  //   Start `n` on 2
    Math.random()<1f/n++;     //   Continue loop as long as a random decimal (0.0-1.0)
                              //   is smaller than 1/`n` (and increase `n` by 1 afterwards)
    System.out.println(s)     //   Print the input-String
  );                          //  End of loop
}                             // End of method

Kevin Cruijssen

Posted 2017-06-12T06:54:02.633

Reputation: 67 575

2i am unable to check in the moment but why not put if condition inside for condition block? – cliffroot – 2017-06-12T08:01:33.847

@cliffroot It is in the for loop. – Okx – 2017-06-12T08:54:46.457

1@Okx I meant condition when for loop should end so that it does not need explicit return. The second expression inside for statement. – cliffroot – 2017-06-12T09:01:00.177

@cliffroot Ah, I understand. – Okx – 2017-06-12T09:07:51.177

@cliffroot Thanks.. that was pretty stupid to miss.. ;) – Kevin Cruijssen – 2017-06-12T09:45:56.247

1Would int n=2 and 1f/n++ work? – JollyJoker – 2017-06-13T11:42:58.993

9

Mathematica, 43 bytes

(n=1;While[RandomInteger@n>0,Print@#;n++])&

JungHwan Min saved 1 byte (above) and suggested something better (below)

Mathematica, 37 bytes

For[n=1,RandomInteger@n++>0,Print@#]&

J42161217

Posted 2017-06-12T06:54:02.633

Reputation: 15 931

1RandomInteger@n!=0 is the same as RandomInteger@n<1 in this case, and n++ can be merged with RandomInteger@n. Also, For is (almost always) shorter than While: -5 bytes For[n=1,RandomInteger@n++>0,Print@#]& – JungHwan Min – 2017-06-12T07:30:00.460

"For" wins! I posted your answer too – J42161217 – 2017-06-12T07:39:52.170

For[n=1,!n∣Hash[# n++],Print@#]& would also work at 34 bytes, assuming the hash is fairly random. The randomness depends on the input, however. For example try % /@ Alphabet[] – Kelly Lowder – 2017-06-13T06:57:08.520

8

Clojure, 61 56 bytes

Oh why didn't I go with a for in the first place? But actually to be pedantic doseq has to be used as for is evaluated lazily.

#(doseq[n(range):while(>(rand-int(+ n 2))0)](println %))

Original:

#(loop[n 2](if(>(rand-int n)0)(do(println %)(recur(inc n)))))

NikoNyrh

Posted 2017-06-12T06:54:02.633

Reputation: 2 361

isn't (>(+(rand-int n)2)0) always true? – cliffroot – 2017-06-12T08:47:17.403

Ah good catch, I meant to increment n! – NikoNyrh – 2017-06-12T08:56:43.420

8

><>, 124 112 bytes

i:0( ?v
 &5a ~/
&p0[^ >"\_\^x0!>"0&1+:&p1&:&p2&:&p3&:&p4&:&p0&1+:&p3&:&p4&:
=?v[/!}l]:?!;1
{:   ?^  >
:o>_ {:?!^

Try it online! (You can also watch it at the fish playground, but due to some bugs you have to add a } after the l in the fourth line and add a bunch of newlines after the code to make it work properly.)

Randomness is tricky in ><>. The only random instruction is x, which picks the fish's direction randomly from four choices (left, right, up and down), so turning that into something with probability 1/n is not straightforward.

The way this code does it is by using ><>'s self-modifying capabilities to build a Tower of Randomness below the code, so at the fourth stage, for example, the code looks like:

i:0( ?v
 &5a ~/
&p0[^ >"\_\^x0!>"0&1+:&p1&:&p2&:&p3&:&p4&:&p0&1+:&p3&:&p4&:
=?v[/!}l]:?!;1
{:   ?^  >
:o>_ {:?!^
>!0x^
\  _\
>!0x^
\  _\
>!0x^
\  _\
>!0x^
\  _\

The fish starts at the bottom of the tower. At each level of the tower, the x is trapped between two mirrors, so the fish can only escape by going left or right. Either of these directions sends the fish up to the next level of the tower, but going left also pushes a 0 to the stack. By the time the fish gets to the top of the tower, the stack contains some number of 0s, and this number follows a binomial distribution with n trials and p = 1/2.

If the length of the stack is 0 (which has probability 1/2n), the program halts. If the length is 1 (with probability n/2n), the fish prints the input and a newline and builds another level of the tower. If the length is anything else, the fish discards the stack and goes back to the bottom of the tower. In effect, out of the possibilities that actually do something, n of them print the input string and one of them halts the program, giving the required probabilities.

Not a tree

Posted 2017-06-12T06:54:02.633

Reputation: 3 106

7

Python 3, 72 69 66 bytes

  • Saved 3 bytes thanks to Jonathan Allan: Import shorthand and start count from 2.
  • Saved 3 bytes thanks to L3viathan : Pointed randint() was inclusive and also shortened while condition.
from random import*
s=input();i=1
while randint(0,i):print(s);i+=1

Try it online!

officialaimm

Posted 2017-06-12T06:54:02.633

Reputation: 2 739

1

There's a setting to turn off the output cache - like so

– Jonathan Allan – 2017-06-12T07:21:24.473

2I think it's acceptable to be "off" for large n (I can't get English brain in gear, "...(and why they respect the specs, disregarding pseudo-randomness and big numbers problems)..." disregarding - right?) If so then you can do random()<1/i. – Jonathan Allan – 2017-06-12T07:34:07.250

1Doesn't this start with probability ⅓? randint is inclusive. You could then shorten that line to while randint(0,i):print(s);i+=1 – L3viathan – 2017-06-12T08:22:52.233

1I just came up with the same solution. – Esolanging Fruit – 2017-06-12T17:52:39.020

Updated TIO link. Now the byte count is the same as the floating point version too. – Jonathan Allan – 2017-06-12T22:31:32.967

6

QBIC, 19 17 bytes

Dropped =1, switched conditionals, saved 2 bytes

{p=p+1~_rp||?;\_X

Explanation

{       Infinitely DO
p=p+1   Add 1 to p (p starts as 0, so on first loop is set to 1, then 2 etc...)
~       IF
  _rp|| a random number between 0 and p
        (implicitly: is anything but 0)
?;      THEN print A$ (which gets read from the cmd line)
\_X     ELSE QUIT
        END IF and LOOP are auto-added at EOF

steenbergh

Posted 2017-06-12T06:54:02.633

Reputation: 7 772

6

Braingolf, 23 bytes

#|V12[R!&@v!r?<1+>1+]|;

Try it online!

Generates random number x where 0 <= x < n+1, terminates if x is 0, otherwise increments n and loops. Separator is |

Explanation:

#|V12[R!&@v!r?<1+>1+]|;  Implicit input of commandline args to stack
#|                       Push |
  V                      Create stack2 and switch to it
   12                    Push 1, then 2
     [..............]    Do-While loop, will run indefinitely unless conditional skips
                         Closing bracket
      R                  Return to stack1
       !&@               Print entire stack without popping
          v              Switch to stack2
           !r            Generate random number 0 <= x < n where n is last item on stack
             ?           If last item is greater than 0..
              <          ..Move first item to end of stack
               1+        ..and increment, this is the loop counter number
                 >       ..Move back
                  1+     ..and increment, this is the upper range of the RNG
                    ]    ..end loop
                     |   Endif
                      ;  Suppress implicit output

Skidsdev

Posted 2017-06-12T06:54:02.633

Reputation: 9 656

6

Alice, 18 bytes

/?!\v
\iO/>]qhUn$@

Try it online!

Explanation

/     Reflect to SE. Switch to Ordinal.
i     Read all input as a string and push it to the stack.
!     Store the string on the tape.
/     Reflect to E. Switch to Cardinal.
>     Ensure that the IP moves east. This begins the main loop.

  ]   Move the tape head to the right. We'll be using the tape head's 
      position as a counter variable. Note that this tape head is independent
      of the one used in Ordinal mode to point at the input string.
  q   Push the tape head's position to the stack.
  h   Increment it (so that it's 2 initially).
  U   Get a uniformly random number in [0,n).
  n   Logical NOT. Gives 1 with probability 1/n and 0 otherwise.
  $@  Terminate the program if we got a  1.
  \   Reflect to NE. Switch to Ordinal.
  ?   Retrieve the input from the tape.
  O   Print it with a trailing linefeed.
  \   Reflect to E. Switch to Cardinal.

v     Send the IP south where it runs into the > to start the next
      loop iteration.

Martin Ender

Posted 2017-06-12T06:54:02.633

Reputation: 184 808

6

PHP, 31 bytes

for(;rand()%~++$c;)echo$argn._;

Try it online!

Jörg Hülsermann

Posted 2017-06-12T06:54:02.633

Reputation: 13 026

6

Perl, 26 bytes

24 bytes code + 2 for -nl.

print while rand++$i+1|0

Try it online!

Dom Hastings

Posted 2017-06-12T06:54:02.633

Reputation: 16 415

3

Charcoal, 14 bytes

A²γW‽γ«θ_A⁺γ¹γ

Try it online! Link is to verbose version of code. Uses _ as the separator. Note: output caching is disabled, so please don't hammer Dennis's server!

Neil

Posted 2017-06-12T06:54:02.633

Reputation: 95 035

3

MATL, 9 bytes

`G@QYrq]x

Try it online!

Explanation

`        % Do...while
  G      %   Push input
  @      %   Push iteration index k, starting at 1
  QYrq   %   Random integer uniformly distributed in {0, 1, ..., k}. This is the
         %   loop condition. If non-zero (which occurs with probability k/(1+k))
         %   proceed with next iteration; else exit loop
]        % End
x        % Delete, as there are one too many strings. Implicitly display the stack

Luis Mendo

Posted 2017-06-12T06:54:02.633

Reputation: 87 464

3

Perl 6,  50 41 38 36  26 bytes

{put $_//last for (($,$_),*⊎$_...*).map(*.pick)}

Try it

{eager ->{(++$).rand>.5??.put!!last}...*}

Try it

{eager ->{(++$).rand>.5??.put!!0}...0}

Try it

{eager ->{(++$).rand>.5&&.put}...!*}

Try it

.put while (++$/).rand>.5

(with -n commandline argument)

Try it

Brad Gilbert b2gills

Posted 2017-06-12T06:54:02.633

Reputation: 12 713

3

Python 3, 55 bytes

v=s=input();i=2
while hash(v)%i:print(s);i+=1;v=hash(v)

Explanation

To save having to import random, I've exploited the fact that the hash built-in is randomly seeded each time a python process is fired up (at least in MacOS). Each hash of the last hash should generate a series of pseudo-random integers.

If the hash is pseudo-random enough, the modulo with i is zero with probability 1/i.

Notes

I'm a little bothered by the redundant hash, but without a do-while, or in-condition assignment in Python, I'm a little stuck.

Kit Ham

Posted 2017-06-12T06:54:02.633

Reputation: 31

Do you know whether iterated hashing is always going to cover the full space of random numbers, or can it potentially get stuck in a cycle? Most programming languages use randomized hash algorithms nowadays in order to avoid people intentionally causing hash collisions, but I'm not sure how the randomness guarantees of the hash algorithms compare to those of a PRNG. – None – 2017-06-13T03:30:31.603

It's a fair point. And I'm not sure, it would take some analysis of the Python hash implementation to check (without a more exhaustive check). I thought it was a fun solution, even if there's a chance it might not be 100% pseudo-random =p – Kit Ham – 2017-06-13T03:38:07.213

I'm a little bothered... recursion? – Felipe Nardi Batista – 2017-06-13T12:00:25.180

3

C#

This is same length as the top C# answer, but:

using System;s=>{var x=(1<<31)/new Random().Next();for(;++x>0;)Console.Write(s+" ");}

Just wanted to point out that some math can produce the correct probability.

int.MaxValue/new Random().Next()-1

Is equivalent to

(int)(1 / new Random().NextDouble()) - 1;

And the function f(x)=1/x-1 is:

f(1) = 0

f(1/2) = 1

f(1/3) = 2

f(1/4) = 3

So 1/2 a chance to be rounded down to 0, 1/6 a chance to be rounded down to 1, and 1/(n+1)(n+2) a chance to be rounded down to n.

Maybe some other language could capitalize on this.

EDIT: Fixed my mistake

I thought of something to make it smaller.

EDIT EDIT: I am just all kinds of wrong. Pulled the Random out of the loop because if it's evaluated multiple times, it won't work.

EDIT EDIT EDIT: I got rid of the variable i. I'm going to stop trying to shrink it now. Nope, lied. Got rid of another byte.

Geoffrey

Posted 2017-06-12T06:54:02.633

Reputation: 191

2

Charcoal, 17 bytes

SαA²βW‽β«⁺α¶A⁺β¹β

Try it online! Verbose code included. Respects specs because it uses a random range from 0 to n.

ASCII-only

Posted 2017-06-12T06:54:02.633

Reputation: 4 687

2

C++, 97 96 57 bytes

Here my first try on codegolf :)

#include<iostream>
int main(){std::string S;std::cin>>S;int i=1;while(rand()%++i)puts(S.data());}

I saved one byte by using for

#include<iostream>
int main(){std::string S;std::cin>>S;for(int i=1;rand()%++i;)puts(S.data());}

Saved 39 bytes since nobody seems to count the includes

void p(string S){for(int i=1;rand()%++i;)puts(S.data());}

ungolfed

#include <iostream>
int main()
{
  // Create and read string from inputstream
  std::string S;
  std::cin >> S;       

  // rand % i: create random int in range [0, i-1]
  // Zero is seen as false and all positive int as true
  int i = 1;
  while (rand() % ++i) 
    puts(S.data());    
}

Michiel uit het Broek

Posted 2017-06-12T06:54:02.633

Reputation: 131

You may take the string as an argument from the command line – Maliafo – 2017-06-12T21:43:01.657

Includes are counted, unless you find a compiler that includes them by default – Felipe Nardi Batista – 2017-06-13T12:24:01.363

2

braingasm, 22 bytes

edit: Same byte count, but I realized I could sneak in the new tape Limit feature.

,[>,]>L+[+$rzQ>[.>]:>]

Uses 0 as separator. Works like this:

,[>,]                   Read a byte and move to next cell until end of input.
     >                  After the loop we're in an empty cell;
                          Leave it empty and move to the next.
      L                 Set tape limit here:
                          The tape will then wrap around if we move further.
       +                Increase current cell by one.
                          This cell will be our counter.
        [            ]  Loop until the counter is zero.
                          That won't happen, so it's an infinite loop.
         +              Increase again, so the first time the counter is 2.
          $r            Get a random number, 0 <= r > current cell
            zQ          Quit the program if that random number was 0
              >         Wrap around to the start of the tape.
               [.>]     Print the input stored on the tape
                          The loop will stop at the blank cell.
                   :    Print the blank cell as a number ("0")
                    >   Go to the next (last) cell

daniero

Posted 2017-06-12T06:54:02.633

Reputation: 17 193

2

C, 41 bytes

n;f(char*s){for(n=1;rand()%++n;puts(s));}

Assumes rand is seeded. Try it online!

MD XF

Posted 2017-06-12T06:54:02.633

Reputation: 11 605

"Assumes rand is seeded." -- Is that a valid assumption to make? rand is required by the standard to have a fixed seed value of 1 by default and all implementations I know of do just that. If this function only does what the challenge asks when combined with other code, I think that other code needs to be included in the answer and in the byte count. – hvd – 2017-06-13T10:36:57.583

2

Python, 54 bytes

lambda s:int(1/random()-1)*(s+'|')
from random import*

Try it online!

Generated the number of copies as floor(1/p)-1 with p uniformly chosen from the unit interval. The number of copies is n when 1/p-1 falls between n and n+1, which happens when 1/(n+2) < p < 1/(n+1). This happens with probability 1/(n+1)-1/(n+2) or 1/((n+1)*(n+2). This is the desired probability of outputting n copies: 1/2 prob of 0, 1/6 prob of 1, 1/12 prob of 2,...

xnor

Posted 2017-06-12T06:54:02.633

Reputation: 115 687

Why is form random import* at the bottom? – CalculatorFeline – 2017-06-12T17:25:09.170

@CalculatorFeline The order doesn't matter. The function definition works either way. – xnor – 2017-06-12T19:48:00.780

@CalculatorFeline In order to drop to bytes by not writing f= and placing it in the TIO Header – Mr. Xcoder – 2017-06-14T19:39:46.210

That makes sense. – CalculatorFeline – 2017-06-16T19:47:12.380

2

F#, 161 bytes

Definitely not the best language to golf, but I decided to give it a try (besides, I do not know anything about F#, so any tips on how to improve my answer will be welcome).

let f s=
 let r,z=System.Random(),(<>)0
 let p _=printfn"%s"s
 seq {for i in 2|>Seq.unfold(fun i->Some(i,i+1))do yield r.Next(i)}|>Seq.takeWhile z|>Seq.iter p

Execute with:

[<EntryPoint>]
let main argv =
    "test" |> f
    0

Writes a new line as separator.

Charlie

Posted 2017-06-12T06:54:02.633

Reputation: 11 448

2

Ruby, 29+1 = 30 bytes

Uses the -n flag.

i=1;puts$_ while i>rand(i+=1)

Try it online!

Value Ink

Posted 2017-06-12T06:54:02.633

Reputation: 10 608

Since you're taking exactly one line of input, you can use the $. special variable instead of i. Arguably you can also replace puts$_ with print but it's not clear the rules support that.

– histocrat – 2019-10-08T16:30:29.357

2

JS (ES6), 47 bytes

x=>{for(i=1;Math.random()<i/(i+1);i++)alert(x)}

Unlike the other ES6 answer, this uses a for loop and alert bombs instead of recursion. The seperator that is printed when the program stops is undefined.

user70700

Posted 2017-06-12T06:54:02.633

Reputation:

2

PowerShell, 31 bytes

for($i=2;random($i++)){"$args"}

Get-Random $i outputs an n where 0 <= n < $i, separator is implicit newline.

TessellatingHeckler

Posted 2017-06-12T06:54:02.633

Reputation: 2 412

129 bytes? – Veskah – 2019-10-08T19:39:03.050

1

Python, 75 bytes

The other Python answer is shorter, but I wanted to try it a different way:

from random import*
f=lambda d=1,s=input():randint(0,d)and s+'!'+f(d+1)or''

L3viathan

Posted 2017-06-12T06:54:02.633

Reputation: 3 151

1

Dart - 73 chars

import"dart:math";p(s,{i=2}){while(new Random().nextInt(i++)>0)print(s);}

This function implements the algorithm by taking a string as input and printing it as necessary. The separator is obviously newline. To run it, you need a main method like main(){p("foo");}.

It's hard to be small when you need to import the math library and instantiate the Random class.

Try it online

lrn

Posted 2017-06-12T06:54:02.633

Reputation: 521

1

APL (Dyalog), 17 bytes

Requires ⎕IO←0 which is default on many systems.

{⎕←⍺⋄×?⍵:⍺∇1+⍵}∘2

This is a monadic function derived from a dyadic function by currying the right argument.

{ anonymous function

⎕←⍺ print ⍺ (the string)

 ⋄  then

×?⍵: if the signum of a random int in the range [0,-1] is 1, then:

⍺ ∇ 1+⍵ recurse with 1+ as new right argument

 (implicit, else: stop)

}∘2 with 2 as bound right argument

Try it online! Sets ⎕RL←0 (Random Link) to avoid TIO's regeneration of the same random number.)

Adám

Posted 2017-06-12T06:54:02.633

Reputation: 37 779

1

C# 79 bytes

does a divide by 0 error count as terminating?

using System;s=>{for(int i=1;2>1/new Random().Next(++i);Console.Write(s+' '));}

Broom

Posted 2017-06-12T06:54:02.633

Reputation: 211

1

Scala 76 72 Bytes

def w[T](s:T)={var x=2;while(Random.nextFloat>1f/x){x=x+1;print(s+" ")}

This uses a template because it works fine for strings, and saves a character. Other than that, it's a pretty basic implementation. Scala picks up a couple bytes by not having a proper++ operator. Random.nextFloat returns a random value between 0 and 1, and 1f/x forces float division. This implementation uses a space as a separator, with no trailing newline.

Ethan

Posted 2017-06-12T06:54:02.633

Reputation: 271

1

Lua, 50 46 bytes

i=2while 1<math.random(i)do i=i+1print(...)end

Assumes that it is already seeded

Try it online!

Felipe Nardi Batista

Posted 2017-06-12T06:54:02.633

Reputation: 2 345

1

k, 20 bytes

`0:((*1?2+)(1+)/0)#,

Explanation:

`0:((*1?2+)(1+)/0)#,
                0    /set x to 0
           (1+)      /add 1 to x...
    (*1?2+)    /     /...while randint [0,2+x) is > 0
   (             )#, /make array with that many copies of the string
`0:                  /output array line by line

Probabilities:

 5#{(((#:'=x{(*1?2+)(1+)/0}\0)@!x))%x}2000000      /experimental
0.5001625 0.1667005 0.083024   0.050034 0.0333645
 {(1%x)*-1_1.,*\{(x-1)%x}x}2+!5                    /calculated
0.5       0.1666667 0.08333333 0.05     0.03333333

zgrep

Posted 2017-06-12T06:54:02.633

Reputation: 1 291

@ValueInk Oh, I believe I misread! Fixing this now... – zgrep – 2017-06-15T22:44:31.487

@ValueInk Fixed. – zgrep – 2017-06-15T23:12:35.540

1

Forth (gforth), 71 bytes

include random.fs
: f 1 1 do i 1+ random i = ?leave 2dup type cr loop ;

Try it online!

Technically will end after the [maximum single-cell number]th iteration, but the chance of that happening is at least 2-64 on most systems (and likely 2-32 on others)

Code Explanation

include random.fs  \ load the random library to generate random numbers

: f                \ start a new word definition
  1 1 do           \ loop from 1 to 0 (start at 1 stop when we reach 0 via integer overflow)
    i 1+ random    \ get a random integer from 0 to n
    i =            \ check if the value equals n
    ?leave         \ end the loop if true
    2dup type cr   \ otherwise, print the input string followed by newline
  loop             \ go back to beginning of loop
;                  \ end the word definition

reffu

Posted 2017-06-12T06:54:02.633

Reputation: 1 361

0

Bash, 71 59 bytes

i=1;while((0<`shuf -i0-$i -n1`));do echo $1;i=$((i++));done

Try it online!

While is a better tool for this job

DrnglVrgs

Posted 2017-06-12T06:54:02.633

Reputation: 145

0

TI-BASIC, 24 22 bytes

-2 thanks to @lirtosiast

:Prompt Str1           //4 bytes
:While randInt(0,Ans+1 //9 bytes
:Disp Str1             //4 bytes
:Ans+1                 //4 bytes
:End                   //1 byte

Since all non-zero values are truthy, taking a random integer in between 0 and n-1 will give a random boolean with the correct probability.

Scott Milner

Posted 2017-06-12T06:54:02.633

Reputation: 1 806

Why not Ans instead of A? – lirtosiast – 2017-07-11T01:30:07.733

@lirtosiast Either works, but they have the same byte count and there is no reason to use Ans over A. A takes up less screen space, so I chose it. – Scott Milner – 2017-07-15T16:41:17.310

I was thinking you could avoid the →A, since you don't use Ans for anything else, and both Ans and A default to 0. – lirtosiast – 2017-07-15T22:40:52.490

@lirtosiast Ah, OK, thanks. – Scott Milner – 2017-07-16T00:36:15.330

0

Runic Enchantments, 20 bytes

i0q11+:'RA0=?;S:$S4?

Try it online!

Note that input is implicitly split on whitespace characters, so they need to be escaped.

Explanation

>                        Implicit entry
 i0q1                    Read input and set up stack
     1+                  Increment counter (value needs to be 2 for first loop)
       :'RA0=            Generate random value (non destructive to stack) and compare with 0
             ?;          If *not* 0, terminate
               S:$S      Otherwise duplicate and print string
                   4?    Skip next 4 instructions (implicit loop)

Newline variant, as printing a whitespace character as a separator costs an extra byte.

Draco18s no longer trusts SE

Posted 2017-06-12T06:54:02.633

Reputation: 3 053