A-M baby
This commit is contained in:
parent
764da6cbbb
commit
db842d013d
19005 changed files with 197040 additions and 7 deletions
23
Task/Knuths-algorithm-S/0DESCRIPTION
Normal file
23
Task/Knuths-algorithm-S/0DESCRIPTION
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
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 #2 for any subsequent items.
|
||||
|
||||
;The Task:
|
||||
# Create a function <code>s_of_n_creator</code> that given <math>n</math> the maximum sample size, returns a function <code>s_of_n</code> that takes one parameter, <code>item</code>.
|
||||
# Function <code>s_of_n</code> 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:
|
||||
:# Use the s_of_n_creator with n == 3 to generate an s_of_n.
|
||||
:# 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
|
||||
|
||||
;Cf.
|
||||
* [[One of n lines in a file]]
|
||||
* [[Accumulator factory]]
|
||||
12
Task/Knuths-algorithm-S/Ada/knuths-algorithm-s-1.ada
Normal file
12
Task/Knuths-algorithm-S/Ada/knuths-algorithm-s-1.ada
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
generic
|
||||
Sample_Size: Positive;
|
||||
type Item_Type is private;
|
||||
package S_Of_N_Creator is
|
||||
|
||||
subtype Index_Type is Positive range 1 .. Sample_Size;
|
||||
type Item_Array is array (Index_Type) of Item_Type;
|
||||
|
||||
procedure Update(New_Item: Item_Type);
|
||||
function Result return Item_Array;
|
||||
|
||||
end S_Of_N_Creator;
|
||||
38
Task/Knuths-algorithm-S/Ada/knuths-algorithm-s-2.ada
Normal file
38
Task/Knuths-algorithm-S/Ada/knuths-algorithm-s-2.ada
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
with Ada.Numerics.Float_Random, Ada.Numerics.Discrete_Random;
|
||||
|
||||
package body S_Of_N_Creator is
|
||||
|
||||
package F_Rnd renames Ada.Numerics.Float_Random;
|
||||
F_Gen: F_Rnd.Generator;
|
||||
|
||||
package D_Rnd is new Ada.Numerics.Discrete_Random(Index_Type);
|
||||
D_Gen: D_Rnd.Generator;
|
||||
|
||||
Item_Count: Natural := 0; -- this is a global counter
|
||||
Sample: Item_Array; -- also used globally
|
||||
|
||||
procedure Update(New_Item: Item_Type) is
|
||||
begin
|
||||
Item_Count := Item_Count + 1;
|
||||
if Item_Count <= Sample_Size then
|
||||
-- select the first Sample_Size items as the sample
|
||||
Sample(Item_Count) := New_Item;
|
||||
else
|
||||
-- for I-th item, I > Sample_Size: Sample_Size/I chance of keeping it
|
||||
if (Float(Sample_Size)/Float(Item_Count)) > F_Rnd.Random(F_Gen) then
|
||||
-- randomly (1/Sample_Size) replace one of the items of the sample
|
||||
Sample(D_Rnd.Random(D_Gen)) := New_Item;
|
||||
end if;
|
||||
end if;
|
||||
end Update;
|
||||
|
||||
function Result return Item_Array is
|
||||
begin
|
||||
Item_Count := 0; -- ready to start another run
|
||||
return Sample;
|
||||
end Result;
|
||||
|
||||
begin
|
||||
D_Rnd.Reset(D_Gen); -- at package instantiation, initialize rnd-generators
|
||||
F_Rnd.Reset(F_Gen);
|
||||
end S_Of_N_Creator;
|
||||
34
Task/Knuths-algorithm-S/Ada/knuths-algorithm-s-3.ada
Normal file
34
Task/Knuths-algorithm-S/Ada/knuths-algorithm-s-3.ada
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
with S_Of_N_Creator, Ada.Text_IO;
|
||||
|
||||
procedure Test_S_Of_N is
|
||||
|
||||
Repetitions: constant Positive := 100_000;
|
||||
type D_10 is range 0 .. 9;
|
||||
|
||||
-- the instantiation of the generic package S_Of_N_Creator generates
|
||||
-- a package with the desired functionality
|
||||
package S_Of_3 is new S_Of_N_Creator(Sample_Size => 3, Item_Type => D_10);
|
||||
|
||||
Sample: S_Of_3.Item_Array;
|
||||
Result: array(D_10) of Natural := (others => 0);
|
||||
|
||||
begin
|
||||
for J in 1 .. Repetitions loop
|
||||
-- get Sample
|
||||
for Dig in D_10 loop
|
||||
S_Of_3.Update(Dig);
|
||||
end loop;
|
||||
Sample := S_Of_3.Result;
|
||||
|
||||
-- update current Result
|
||||
for Item in Sample'Range loop
|
||||
Result(Sample(Item)) := Result(Sample(Item)) + 1;
|
||||
end loop;
|
||||
end loop;
|
||||
|
||||
-- finally: output Result
|
||||
for Dig in Result'Range loop
|
||||
Ada.Text_IO.Put(D_10'Image(Dig) & ":"
|
||||
& Natural'Image(Result(Dig)) & "; ");
|
||||
end loop;
|
||||
end Test_S_Of_N;
|
||||
54
Task/Knuths-algorithm-S/BBC-BASIC/knuths-algorithm-s.bbc
Normal file
54
Task/Knuths-algorithm-S/BBC-BASIC/knuths-algorithm-s.bbc
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
HIMEM = PAGE + 20000000
|
||||
|
||||
PRINT "Single run samples for n = 3:"
|
||||
SofN% = FNs_of_n_creator(3)
|
||||
FOR I% = 0 TO 9
|
||||
!^a%() = FN(SofN%)(I%)
|
||||
PRINT " For item " ; I% " sample(s) = " FNshowarray(a%(), I%+1)
|
||||
NEXT
|
||||
|
||||
DIM cnt%(9)
|
||||
PRINT '"Digit counts after 100000 runs:"
|
||||
FOR rep% = 1 TO 100000
|
||||
IF (rep% MOD 1000) = 0 PRINT ; rep% ; CHR$(13) ;
|
||||
F% = FNs_of_n_creator(3)
|
||||
FOR I% = 0 TO 9
|
||||
!^a%() = FN(F%)(I%)
|
||||
NEXT
|
||||
cnt%(a%(1)) += 1 : cnt%(a%(2)) += 1 : cnt%(a%(3)) += 1
|
||||
NEXT
|
||||
FOR digit% = 0 TO 9
|
||||
PRINT " " ; digit% " : " ; cnt%(digit%)
|
||||
NEXT
|
||||
END
|
||||
|
||||
REM Dynamically creates this function:
|
||||
REM DEF FNfunction(item%) : PRIVATE samples%(), index%
|
||||
REM DIM samples%(n%) : = FNs_of_n(item%, samples%(), index%)
|
||||
DEF FNs_of_n_creator(n%)
|
||||
LOCAL p%, f$
|
||||
f$ = "(item%) : " + CHR$&0E + " samples%(), index% : " + \
|
||||
\ CHR$&DE + " samples%(" + STR$(n%) + ") : = " + \
|
||||
\ CHR$&A4 + "s_of_n(item%, samples%(), index%)"
|
||||
DIM p% LEN(f$) + 4 : $(p%+4) = f$ : !p% = p%+4
|
||||
= p%
|
||||
|
||||
DEF FNs_of_n(D%, s%(), RETURN I%)
|
||||
LOCAL N%
|
||||
N% = DIM(s%(),1)
|
||||
I% += 1
|
||||
IF I% <= N% THEN
|
||||
s%(I%) = D%
|
||||
ELSE
|
||||
IF RND(I%) <= N% s%(RND(N%)) = D%
|
||||
ENDIF
|
||||
= !^s%()
|
||||
|
||||
DEF FNshowarray(a%(), n%)
|
||||
LOCAL i%, a$
|
||||
a$ = "["
|
||||
IF n% > DIM(a%(),1) n% = DIM(a%(),1)
|
||||
FOR i% = 1 TO n%
|
||||
a$ += STR$(a%(i%)) + ", "
|
||||
NEXT
|
||||
= LEFT$(LEFT$(a$)) + "]"
|
||||
36
Task/Knuths-algorithm-S/C++/knuths-algorithm-s-1.cpp
Normal file
36
Task/Knuths-algorithm-S/C++/knuths-algorithm-s-1.cpp
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
#include <iostream>
|
||||
#include <functional>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
|
||||
template <typename T>
|
||||
std::function<std::vector<T>(T)> s_of_n_creator(int n) {
|
||||
std::vector<T> sample;
|
||||
int i = 0;
|
||||
return [=](T item) mutable {
|
||||
i++;
|
||||
if (i <= n) {
|
||||
sample.push_back(item);
|
||||
} else if (std::rand() % i < n) {
|
||||
sample[std::rand() % n] = item;
|
||||
}
|
||||
return sample;
|
||||
};
|
||||
}
|
||||
|
||||
int main() {
|
||||
std::srand(std::time(NULL));
|
||||
int bin[10] = {0};
|
||||
for (int trial = 0; trial < 100000; trial++) {
|
||||
auto s_of_n = s_of_n_creator<int>(3);
|
||||
std::vector<int> sample;
|
||||
for (int i = 0; i < 10; i++)
|
||||
sample = s_of_n(i);
|
||||
for (int s : sample)
|
||||
bin[s]++;
|
||||
}
|
||||
for (int x : bin)
|
||||
std::cout << x << std::endl;
|
||||
return 0;
|
||||
}
|
||||
38
Task/Knuths-algorithm-S/C++/knuths-algorithm-s-2.cpp
Normal file
38
Task/Knuths-algorithm-S/C++/knuths-algorithm-s-2.cpp
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
|
||||
template <typename T>
|
||||
class SOfN {
|
||||
std::vector<T> sample;
|
||||
int i;
|
||||
const int n;
|
||||
public:
|
||||
SOfN(int _n) : i(0), n(_n) { }
|
||||
std::vector<T> operator()(T item) {
|
||||
i++;
|
||||
if (i <= n) {
|
||||
sample.push_back(item);
|
||||
} else if (std::rand() % i < n) {
|
||||
sample[std::rand() % n] = item;
|
||||
}
|
||||
return sample;
|
||||
}
|
||||
};
|
||||
|
||||
int main() {
|
||||
std::srand(std::time(NULL));
|
||||
int bin[10] = {0};
|
||||
for (int trial = 0; trial < 100000; trial++) {
|
||||
SOfN<int> s_of_n(3);
|
||||
std::vector<int> sample;
|
||||
for (int i = 0; i < 10; i++)
|
||||
sample = s_of_n(i);
|
||||
for (std::vector<int>::const_iterator i = sample.begin(); i != sample.end(); i++)
|
||||
bin[*i]++;
|
||||
}
|
||||
for (int i = 0; i < 10; i++)
|
||||
std::cout << bin[i] << std::endl;
|
||||
return 0;
|
||||
}
|
||||
72
Task/Knuths-algorithm-S/C/knuths-algorithm-s.c
Normal file
72
Task/Knuths-algorithm-S/C/knuths-algorithm-s.c
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
struct s_env {
|
||||
unsigned int n, i;
|
||||
size_t size;
|
||||
void *sample;
|
||||
};
|
||||
|
||||
void s_of_n_init(struct s_env *s_env, size_t size, unsigned int n)
|
||||
{
|
||||
s_env->i = 0;
|
||||
s_env->n = n;
|
||||
s_env->size = size;
|
||||
s_env->sample = malloc(n * size);
|
||||
}
|
||||
|
||||
void sample_set_i(struct s_env *s_env, unsigned int i, void *item)
|
||||
{
|
||||
memcpy(s_env->sample + i * s_env->size, item, s_env->size);
|
||||
}
|
||||
|
||||
void *s_of_n(struct s_env *s_env, void *item)
|
||||
{
|
||||
s_env->i++;
|
||||
if (s_env->i <= s_env->n)
|
||||
sample_set_i(s_env, s_env->i - 1, item);
|
||||
else if ((rand() % s_env->i) < s_env->n)
|
||||
sample_set_i(s_env, rand() % s_env->n, item);
|
||||
return s_env->sample;
|
||||
}
|
||||
|
||||
int *test(unsigned int n, int *items_set, unsigned int num_items)
|
||||
{
|
||||
int i;
|
||||
struct s_env s_env;
|
||||
s_of_n_init(&s_env, sizeof(items_set[0]), n);
|
||||
for (i = 0; i < num_items; i++) {
|
||||
s_of_n(&s_env, (void *) &items_set[i]);
|
||||
}
|
||||
return (int *)s_env.sample;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
unsigned int i, j;
|
||||
unsigned int n = 3;
|
||||
unsigned int num_items = 10;
|
||||
unsigned int *frequencies;
|
||||
int *items_set;
|
||||
srand(time(NULL));
|
||||
items_set = malloc(num_items * sizeof(int));
|
||||
frequencies = malloc(num_items * sizeof(int));
|
||||
for (i = 0; i < num_items; i++) {
|
||||
items_set[i] = i;
|
||||
frequencies[i] = 0;
|
||||
}
|
||||
for (i = 0; i < 100000; i++) {
|
||||
int *res = test(n, items_set, num_items);
|
||||
for (j = 0; j < n; j++) {
|
||||
frequencies[res[j]]++;
|
||||
}
|
||||
free(res);
|
||||
}
|
||||
for (i = 0; i < num_items; i++) {
|
||||
printf(" %d", frequencies[i]);
|
||||
}
|
||||
puts("");
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
s_of_n_creator = (n) ->
|
||||
arr = []
|
||||
cnt = 0
|
||||
(elem) ->
|
||||
cnt += 1
|
||||
if cnt <= n
|
||||
arr.push elem
|
||||
else
|
||||
pos = Math.floor(Math.random() * cnt)
|
||||
if pos < n
|
||||
arr[pos] = elem
|
||||
arr.sort()
|
||||
|
||||
sample_size = 3
|
||||
range = [0..9]
|
||||
num_trials = 100000
|
||||
|
||||
counts = {}
|
||||
|
||||
for digit in range
|
||||
counts[digit] = 0
|
||||
|
||||
for i in [1..num_trials]
|
||||
s_of_n = s_of_n_creator(sample_size)
|
||||
for digit in range
|
||||
sample = s_of_n(digit)
|
||||
for digit in sample
|
||||
counts[digit] += 1
|
||||
|
||||
for digit in range
|
||||
console.log digit, counts[digit]
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
> coffee knuth_sample.coffee
|
||||
0 29899
|
||||
1 29841
|
||||
2 29930
|
||||
3 30058
|
||||
4 29932
|
||||
5 29948
|
||||
6 30047
|
||||
7 30114
|
||||
8 29976
|
||||
9 30255
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
(defun s-n-creator (n)
|
||||
(let ((sample (make-array n :initial-element nil))
|
||||
(i 0))
|
||||
(lambda (item)
|
||||
(if (<= (incf i) n)
|
||||
(setf (aref sample (1- i)) item)
|
||||
(when (< (random i) n)
|
||||
(setf (aref sample (random n)) item)))
|
||||
sample)))
|
||||
|
||||
(defun algorithm-s ()
|
||||
(let ((*random-state* (make-random-state t))
|
||||
(frequency (make-array '(10) :initial-element 0)))
|
||||
(loop repeat 100000
|
||||
for s-of-n = (s-n-creator 3)
|
||||
do (flet ((s-of-n (item)
|
||||
(funcall s-of-n item)))
|
||||
(map nil
|
||||
(lambda (i)
|
||||
(incf (aref frequency i)))
|
||||
(loop for i from 0 below 9
|
||||
do (s-of-n i)
|
||||
finally (return (s-of-n 9))))))
|
||||
frequency))
|
||||
|
||||
(princ (algorithm-s))
|
||||
|
|
@ -0,0 +1 @@
|
|||
#(30026 30023 29754 30017 30267 29997 29932 29990 29965 30029)
|
||||
30
Task/Knuths-algorithm-S/D/knuths-algorithm-s-1.d
Normal file
30
Task/Knuths-algorithm-S/D/knuths-algorithm-s-1.d
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import std.stdio, std.random;
|
||||
|
||||
auto sofN_creator(in int n) {
|
||||
size_t i;
|
||||
int[] sample;
|
||||
|
||||
return (in int item) {
|
||||
i++;
|
||||
if (i <= n)
|
||||
sample ~= item;
|
||||
else if (uniform(0.0, 1.0) < (cast(double)n / i))
|
||||
sample[uniform(0, n)] = item;
|
||||
return sample;
|
||||
};
|
||||
}
|
||||
|
||||
void main() {
|
||||
enum nRuns = 100_000;
|
||||
size_t[10] bin;
|
||||
|
||||
foreach (trial; 0 .. nRuns) {
|
||||
auto sofn = sofN_creator(3);
|
||||
int[] sample;
|
||||
foreach (item; 0 .. bin.length)
|
||||
sample = sofn(item);
|
||||
foreach (s; sample)
|
||||
bin[s]++;
|
||||
}
|
||||
writefln("Item counts for %d runs:\n%s", nRuns, bin);
|
||||
}
|
||||
30
Task/Knuths-algorithm-S/D/knuths-algorithm-s-2.d
Normal file
30
Task/Knuths-algorithm-S/D/knuths-algorithm-s-2.d
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
import std.stdio, std.random, std.algorithm;
|
||||
|
||||
struct SOfN(int n) {
|
||||
size_t i;
|
||||
int[n] sample = void;
|
||||
static rng = Xorshift(0);
|
||||
|
||||
int[] next(in int item) {
|
||||
i++;
|
||||
if (i <= n)
|
||||
sample[i - 1] = item;
|
||||
else if (uniform(0.0, 1.0, rng) < (cast(double)n / i))
|
||||
sample[uniform(0, n, rng)] = item;
|
||||
return sample[0 .. min(i, $)];
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
enum nRuns = 100_000;
|
||||
size_t[10] bin;
|
||||
|
||||
foreach (trial; 0 .. nRuns) {
|
||||
SOfN!(3) sofn;
|
||||
foreach (item; 0 .. bin.length - 1)
|
||||
sofn.next(item);
|
||||
foreach (s; sofn.next(bin.length - 1))
|
||||
bin[s]++;
|
||||
}
|
||||
writefln("Item counts for %d runs:\n%s", nRuns, bin);
|
||||
}
|
||||
38
Task/Knuths-algorithm-S/Go/knuths-algorithm-s.go
Normal file
38
Task/Knuths-algorithm-S/Go/knuths-algorithm-s.go
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
)
|
||||
|
||||
func sOfNCreator(n int) func(byte) []byte {
|
||||
s := make([]byte, 0, n)
|
||||
m := n
|
||||
return func(item byte) []byte {
|
||||
if len(s) < n {
|
||||
s = append(s, item)
|
||||
} else {
|
||||
m++
|
||||
if rand.Intn(m) < n {
|
||||
s[rand.Intn(n)] = item
|
||||
}
|
||||
}
|
||||
return s
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
var freq [10]int
|
||||
for r := 0; r < 1e5; r++ {
|
||||
sOfN := sOfNCreator(3)
|
||||
for d := byte('0'); d < '9'; d++ {
|
||||
sOfN(d)
|
||||
}
|
||||
for _, d := range sOfN('9') {
|
||||
freq[d-'0']++
|
||||
}
|
||||
}
|
||||
fmt.Println(freq)
|
||||
}
|
||||
24
Task/Knuths-algorithm-S/Icon/knuths-algorithm-s.icon
Normal file
24
Task/Knuths-algorithm-S/Icon/knuths-algorithm-s.icon
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import Utils
|
||||
|
||||
procedure main(A)
|
||||
freq := table(0)
|
||||
every 1 to (\A[2] | 100000)\1 do {
|
||||
s_of_n := s_of_n_creator(\A[1] | 3)
|
||||
every sample := s_of_n(0 to 9)
|
||||
every freq[!sample] +:= 1
|
||||
}
|
||||
every write(i := 0 to 9,": ",right(freq[i],6))
|
||||
end
|
||||
|
||||
procedure s_of_n_creator(n)
|
||||
items := []
|
||||
itemCnt := 0.0
|
||||
return makeProc {
|
||||
repeat {
|
||||
item := (items@&source)[1]
|
||||
itemCnt +:= 1
|
||||
if *items < n then put(items, item)
|
||||
else if ?0 < (n/itemCnt) then ?items := item
|
||||
}
|
||||
}
|
||||
end
|
||||
25
Task/Knuths-algorithm-S/J/knuths-algorithm-s-1.j
Normal file
25
Task/Knuths-algorithm-S/J/knuths-algorithm-s-1.j
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
coclass'inefficient'
|
||||
create=:3 :0
|
||||
N=: y
|
||||
ITEMS=: ''
|
||||
K=:0
|
||||
)
|
||||
|
||||
s_of_n=:3 :0
|
||||
K=: K+1
|
||||
if. N>#ITEMS do.
|
||||
ITEMS=: ITEMS,y
|
||||
else.
|
||||
if. (N%K)>?0 do.
|
||||
ITEMS=: (((i.#ITEMS)-.?N){ITEMS),y
|
||||
else.
|
||||
ITEMS
|
||||
end.
|
||||
end.
|
||||
)
|
||||
|
||||
|
||||
s_of_n_creator_base_=: 1 :0
|
||||
ctx=: conew&'inefficient' m
|
||||
s_of_n__ctx
|
||||
)
|
||||
19
Task/Knuths-algorithm-S/J/knuths-algorithm-s-2.j
Normal file
19
Task/Knuths-algorithm-S/J/knuths-algorithm-s-2.j
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
run=:3 :0
|
||||
nl=. conl 1
|
||||
s3_of_n=. 3 s_of_n_creator
|
||||
r=. {: s3_of_n"0 i.10
|
||||
coerase (conl 1)-.nl
|
||||
r
|
||||
)
|
||||
|
||||
(~.,._1 + #/.~) (i.10),,D=:run"0 i.1e5
|
||||
0 30099
|
||||
1 29973
|
||||
2 29795
|
||||
3 29995
|
||||
4 29996
|
||||
5 30289
|
||||
6 29903
|
||||
7 29993
|
||||
8 30215
|
||||
9 29742
|
||||
37
Task/Knuths-algorithm-S/Java/knuths-algorithm-s-1.java
Normal file
37
Task/Knuths-algorithm-S/Java/knuths-algorithm-s-1.java
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import java.util.*;
|
||||
|
||||
class SOfN<T> {
|
||||
private static final Random rand = new Random();
|
||||
|
||||
private List<T> sample;
|
||||
private int i = 0;
|
||||
private int n;
|
||||
public SOfN(int _n) {
|
||||
n = _n;
|
||||
sample = new ArrayList<T>(n);
|
||||
}
|
||||
public List<T> process(T item) {
|
||||
i++;
|
||||
if (i <= n) {
|
||||
sample.add(item);
|
||||
} else if (rand.nextInt(i) < n) {
|
||||
sample.set(rand.nextInt(n), item);
|
||||
}
|
||||
return sample;
|
||||
}
|
||||
}
|
||||
|
||||
public class AlgorithmS {
|
||||
public static void main(String[] args) {
|
||||
int[] bin = new int[10];
|
||||
for (int trial = 0; trial < 100000; trial++) {
|
||||
SOfN<Integer> s_of_n = new SOfN<Integer>(3);
|
||||
List<Integer> sample = null;
|
||||
for (int i = 0; i < 10; i++)
|
||||
sample = s_of_n.process(i);
|
||||
for (int s : sample)
|
||||
bin[s]++;
|
||||
}
|
||||
System.out.println(Arrays.toString(bin));
|
||||
}
|
||||
}
|
||||
37
Task/Knuths-algorithm-S/Java/knuths-algorithm-s-2.java
Normal file
37
Task/Knuths-algorithm-S/Java/knuths-algorithm-s-2.java
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
import java.util.*;
|
||||
|
||||
interface Function<S, T> {
|
||||
public T call(S x);
|
||||
}
|
||||
|
||||
public class AlgorithmS {
|
||||
private static final Random rand = new Random();
|
||||
public static <T> Function<T, List<T>> s_of_n_creator(final int n) {
|
||||
return new Function<T, List<T>>() {
|
||||
private List<T> sample = new ArrayList<T>(n);
|
||||
private int i = 0;
|
||||
public List<T> call(T item) {
|
||||
i++;
|
||||
if (i <= n) {
|
||||
sample.add(item);
|
||||
} else if (rand.nextInt(i) < n) {
|
||||
sample.set(rand.nextInt(n), item);
|
||||
}
|
||||
return sample;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
int[] bin = new int[10];
|
||||
for (int trial = 0; trial < 100000; trial++) {
|
||||
Function<Integer, List<Integer>> s_of_n = s_of_n_creator(3);
|
||||
List<Integer> sample = null;
|
||||
for (int i = 0; i < 10; i++)
|
||||
sample = s_of_n.call(i);
|
||||
for (int s : sample)
|
||||
bin[s]++;
|
||||
}
|
||||
System.out.println(Arrays.toString(bin));
|
||||
}
|
||||
}
|
||||
28
Task/Knuths-algorithm-S/PHP/knuths-algorithm-s.php
Normal file
28
Task/Knuths-algorithm-S/PHP/knuths-algorithm-s.php
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
<?php
|
||||
function s_of_n_creator($n) {
|
||||
$sample = array();
|
||||
$i = 0;
|
||||
return function($item) use (&$sample, &$i, $n) {
|
||||
$i++;
|
||||
if ($i <= $n) {
|
||||
// Keep first n items
|
||||
$sample[] = $item;
|
||||
} else if (rand(0, $i-1) < $n) {
|
||||
// Keep item
|
||||
$sample[rand(0, $n-1)] = $item;
|
||||
}
|
||||
return $sample;
|
||||
};
|
||||
}
|
||||
|
||||
$items = range(0, 9);
|
||||
|
||||
for ($trial = 0; $trial < 100000; $trial++) {
|
||||
$s_of_n = s_of_n_creator(3);
|
||||
foreach ($items as $item)
|
||||
$sample = $s_of_n($item);
|
||||
foreach ($sample as $s)
|
||||
$bin[$s]++;
|
||||
}
|
||||
print_r($bin);
|
||||
?>
|
||||
34
Task/Knuths-algorithm-S/Perl/knuths-algorithm-s.pl
Normal file
34
Task/Knuths-algorithm-S/Perl/knuths-algorithm-s.pl
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
use strict;
|
||||
|
||||
sub s_of_n_creator {
|
||||
my $n = shift;
|
||||
my @sample;
|
||||
my $i = 0;
|
||||
sub {
|
||||
my $item = shift;
|
||||
$i++;
|
||||
if ($i <= $n) {
|
||||
# Keep first n items
|
||||
push @sample, $item;
|
||||
} elsif (rand() < $n / $i) {
|
||||
# Keep item
|
||||
@sample[rand $n] = $item;
|
||||
}
|
||||
@sample
|
||||
}
|
||||
}
|
||||
|
||||
my @items = (0..9);
|
||||
my @bin;
|
||||
|
||||
foreach my $trial (1 .. 100000) {
|
||||
my $s_of_n = s_of_n_creator(3);
|
||||
my @sample;
|
||||
foreach my $item (@items) {
|
||||
@sample = $s_of_n->($item);
|
||||
}
|
||||
foreach my $s (@sample) {
|
||||
$bin[$s]++;
|
||||
}
|
||||
}
|
||||
print "@bin\n";
|
||||
13
Task/Knuths-algorithm-S/PicoLisp/knuths-algorithm-s.l
Normal file
13
Task/Knuths-algorithm-S/PicoLisp/knuths-algorithm-s.l
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
(de s_of_n_creator (@N)
|
||||
(curry (@N (I . 0) (Res)) (Item)
|
||||
(cond
|
||||
((>= @N (inc 'I)) (push 'Res Item))
|
||||
((>= @N (rand 1 I)) (set (nth Res (rand 1 @N)) Item)) )
|
||||
Res ) )
|
||||
|
||||
(let Freq (need 10 0)
|
||||
(do 100000
|
||||
(let S_of_n (s_of_n_creator 3)
|
||||
(for I (mapc S_of_n (0 1 2 3 4 5 6 7 8 9))
|
||||
(inc (nth Freq (inc I))) ) ) )
|
||||
Freq )
|
||||
34
Task/Knuths-algorithm-S/Python/knuths-algorithm-s-1.py
Normal file
34
Task/Knuths-algorithm-S/Python/knuths-algorithm-s-1.py
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
from random import randrange
|
||||
|
||||
def s_of_n_creator(n):
|
||||
sample, i = [], 0
|
||||
def s_of_n(item):
|
||||
nonlocal i
|
||||
|
||||
i += 1
|
||||
if i <= n:
|
||||
# Keep first n items
|
||||
sample.append(item)
|
||||
elif randrange(i) < n:
|
||||
# Keep item
|
||||
sample[randrange(n)] = item
|
||||
return sample
|
||||
return s_of_n
|
||||
|
||||
if __name__ == '__main__':
|
||||
bin = [0]* 10
|
||||
items = range(10)
|
||||
print("Single run samples for n = 3:")
|
||||
s_of_n = s_of_n_creator(3)
|
||||
for item in items:
|
||||
sample = s_of_n(item)
|
||||
print(" Item: %i -> sample: %s" % (item, sample))
|
||||
#
|
||||
for trial in range(100000):
|
||||
s_of_n = s_of_n_creator(3)
|
||||
for item in items:
|
||||
sample = s_of_n(item)
|
||||
for s in sample:
|
||||
bin[s] += 1
|
||||
print("\nTest item frequencies for 100000 runs:\n ",
|
||||
'\n '.join("%i:%i" % x for x in enumerate(bin)))
|
||||
16
Task/Knuths-algorithm-S/Python/knuths-algorithm-s-2.py
Normal file
16
Task/Knuths-algorithm-S/Python/knuths-algorithm-s-2.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
class S_of_n_creator():
|
||||
def __init__(self, n):
|
||||
self.n = n
|
||||
self.i = 0
|
||||
self.sample = []
|
||||
|
||||
def __call__(self, item):
|
||||
self.i += 1
|
||||
n, i, sample = self.n, self.i, self.sample
|
||||
if i <= n:
|
||||
# Keep first n items
|
||||
sample.append(item)
|
||||
elif randrange(i) < n:
|
||||
# Keep item
|
||||
sample[randrange(n)] = item
|
||||
return sample
|
||||
1
Task/Knuths-algorithm-S/Python/knuths-algorithm-s-3.py
Normal file
1
Task/Knuths-algorithm-S/Python/knuths-algorithm-s-3.py
Normal file
|
|
@ -0,0 +1 @@
|
|||
s_of_n = S_of_n_creator(3)
|
||||
45
Task/Knuths-algorithm-S/REXX/knuths-algorithm-s.rexx
Normal file
45
Task/Knuths-algorithm-S/REXX/knuths-algorithm-s.rexx
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
/*REXX program using Knuth's algorithm S (random sampling n of M items).*/
|
||||
parse arg trials size . /*obtain the arguments from C.L. */
|
||||
if trials=='' then trials=100000 /*use default if not specified. */
|
||||
if size=='' then size=3 /* " " " " " */
|
||||
#.=0 /*a couple handfuls of counters. */
|
||||
do trials /*OK, let's light this candle. */
|
||||
call s_of_n_creator size /*create initial list of n items.*/
|
||||
|
||||
do gener=0 for 10 /*and then call SofN for each dig*/
|
||||
call s_of_n gener /*call s_of_n with a single dig*/
|
||||
end /*gener*/
|
||||
|
||||
do count=1 for size /*let's see what s_of_n wroth. */
|
||||
_=!.count /*get a digit from the Nth item, */
|
||||
#._=#._+1 /* ... and count it, of course. */
|
||||
end /*count*/
|
||||
end /*trials*/
|
||||
|
||||
say "Using Knuth's algorihm S for" comma(trials) 'trials, and with size='comma(size)":"
|
||||
say
|
||||
do dig=0 to 9 /*show & tell time for frequency.*/
|
||||
say copies(' ',15) "frequency of the" dig 'digit is:' comma(#.dig)
|
||||
end /*dig*/
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────S_OF_N_CREATOR subroutine───────────*/
|
||||
s_of_n_creator: parse arg item 1 items /*generate ITEM number of items*/
|
||||
do k=1 for item /*traipse through the 1st N items*/
|
||||
!.k=random(0,9) /*set the Kth item with rand dig.*/
|
||||
end /*k*/
|
||||
return /*out piddly work is done for now*/
|
||||
/*──────────────────────────────────S_OF_N subroutine───────────────────*/
|
||||
s_of_n: parse arg item; items=items+1 /*get "item", bump items counter.*/
|
||||
c=random(1,items) /*should we replace a prev item? */
|
||||
if c>size then return /*probability isn't good, skip it*/
|
||||
_=random(1,size) /*now, figure out which previous */
|
||||
!._=item /* ... item to replace with ITEM.*/
|
||||
return /*and back to the caller we go. */
|
||||
/*──────────────────────────────────COMMA subroutine────────────────────*/
|
||||
comma: procedure; parse arg _,c,p,t;arg ,cu;c=word(c ",",1)
|
||||
if cu=='BLANK' then c=' '; o=word(p 3,1); p=abs(o); t=word(t 999999999,1)
|
||||
if \datatype(p,'W') | \datatype(t,'W') | p==0 | arg()>4 then return _
|
||||
n=_'.9'; #=123456789; k=0; if o<0 then do; b=verify(_,' '); if b==0 then return _
|
||||
e=length(_)-verify(reverse(_),' ')+1; end; else do; b=verify(n,#,"M")
|
||||
e=verify(n,#'0',,verify(n,#"0.",'M'))-p-1; end
|
||||
do j=e to b by -p while k<t; _=insert(c,_,j); k=k+1; end; return _
|
||||
29
Task/Knuths-algorithm-S/Racket/knuths-algorithm-s.rkt
Normal file
29
Task/Knuths-algorithm-S/Racket/knuths-algorithm-s.rkt
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#lang racket
|
||||
|
||||
(define (s-of-n-creator n)
|
||||
(let* ([count 0] ; 'i' in the description
|
||||
[vec (make-vector n)]) ; store the elts we've seen so far
|
||||
(lambda (item)
|
||||
(if (< count n)
|
||||
; we're not full, so, kind of boring
|
||||
(begin
|
||||
(vector-set! vec count item)
|
||||
(set! count (+ count 1))
|
||||
(vector-copy vec 0 count))
|
||||
; we've already seen n elts; fun starts
|
||||
(begin
|
||||
(set! count (+ count 1))
|
||||
(when (< (random) (/ n count))
|
||||
(vector-set! vec (random n) item))
|
||||
(vector-copy vec))))))
|
||||
|
||||
(define counts (make-hash '((0 . 0) (1 . 0) (2 . 0) (3 . 0) (4 . 0) (5 . 0) (6 . 0) (7 . 0) (8 . 0) (9 . 0))))
|
||||
(for ([iter (in-range 0 100000)]) ; trials
|
||||
(let ([s-of-n (s-of-n-creator 3)]) ; set up the chooser
|
||||
(for ([d (in-vector ; iterate over the chosen digits
|
||||
(for/last ([digit (in-range 0 10)]) ; loop through the digits
|
||||
(s-of-n digit)))]) ; feed them in
|
||||
(hash-update! counts d add1)))) ; update counts
|
||||
|
||||
(for ([d (in-range 0 10)])
|
||||
(printf "~a ~a~n" d (hash-ref counts d)))
|
||||
23
Task/Knuths-algorithm-S/Ruby/knuths-algorithm-s.rb
Normal file
23
Task/Knuths-algorithm-S/Ruby/knuths-algorithm-s.rb
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
def s_of_n_creator(n)
|
||||
sample = []
|
||||
i = 0
|
||||
Proc.new do |item|
|
||||
i += 1
|
||||
if i <= n
|
||||
sample << item
|
||||
elsif rand(i) < n
|
||||
sample[rand(n)] = item
|
||||
end
|
||||
sample
|
||||
end
|
||||
end
|
||||
|
||||
frequency = Array.new(10,0)
|
||||
100_000.times do
|
||||
s_of_n = s_of_n_creator(3)
|
||||
sample = nil
|
||||
(0..9).each {|digit| sample = s_of_n[digit]}
|
||||
sample.each {|digit| frequency[digit] += 1}
|
||||
end
|
||||
|
||||
(0..9).each {|digit| puts "#{digit}\t#{frequency[digit]}"}
|
||||
29
Task/Knuths-algorithm-S/Tcl/knuths-algorithm-s.tcl
Normal file
29
Task/Knuths-algorithm-S/Tcl/knuths-algorithm-s.tcl
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
package require Tcl 8.6
|
||||
|
||||
oo::class create SofN {
|
||||
variable items size count
|
||||
constructor {n} {
|
||||
set size $n
|
||||
}
|
||||
method item {item} {
|
||||
if {[incr count] <= $size} {
|
||||
lappend items $item
|
||||
} elseif {rand()*$count < $size} {
|
||||
lset items [expr {int($size * rand())}] $item
|
||||
}
|
||||
return $items
|
||||
}
|
||||
}
|
||||
|
||||
# Test code
|
||||
for {set i 0} {$i < 100000} {incr i} {
|
||||
set sOf3 [SofN new 3]
|
||||
foreach digit {0 1 2 3 4 5 6 7 8 9} {
|
||||
set digs [$sOf3 item $digit]
|
||||
}
|
||||
$sOf3 destroy
|
||||
foreach digit $digs {
|
||||
incr freq($digit)
|
||||
}
|
||||
}
|
||||
parray freq
|
||||
Loading…
Add table
Add a link
Reference in a new issue