user
This is a method of randomly sampling n items from a set of M items, with equal probability; where M >= n and M, the number of items is unknown until the end.
This means that the equal probability sampling should be maintained for all successive items > n as they become available (although the content of successive samples can change).

The algorithm
:   * Select the first n items as the sample as they become available;
    * For the i-th item where i > n, have a random chance of n/i of keeping it. If failing this chance, the sample remains the same. If not, have it randomly (1/n) replace one of the previously selected n items of the sample.
    * Repeat   2nd step   for any subsequent items.

The Task
:   * Create a function `s_of_n_creator` that given 

      n
      {\displaystyle {\displaystyle n}}
       the maximum sample size, returns a function `s_of_n` that takes one parameter, `item`.
    * Function `s_of_n` when called with successive items returns an equi-weighted random sample of up to n of its items so far, each time it is called, calculated using Knuths Algorithm S.
    * Test your functions by printing and showing the frequency of occurrences of the selected digits from 100,000 repetitions of:

    :   :   1. Use the s\_of\_n\_creator with n == 3 to generate an s\_of\_n.
            2. call s\_of\_n with each of the digits 0 to 9 in order, keeping the returned three digits of its random sampling from its last call with argument item=9.

Note: A class taking n and generating a callable instance/function might also be used.

Reference

* The Art of Computer Programming, Vol 2, 3.4.2 p.142

Related tasks

* One of n lines in a file
* Accumulator factory
assistant
(formerly Perl 6)

```
sub s_of_n_creator($n) {
    my (@sample, $i);
    -> $item {
        if    ++$i    <= $n { @sample.push:      $item }
        elsif $i.rand <  $n { @sample[$n.rand] = $item }
        @sample
    }
}

my @bin;
for ^100000 {
    my &s_of_n = s_of_n_creator 3;
    sink .&s_of_n for ^9;
    @bin[$_]++ for s_of_n 9;
}

say @bin;

```

Output:

```
29975 30028 30246 30056 30004 29983 29836 29967 29924 29981
```