-
Notifications
You must be signed in to change notification settings - Fork 5
/
random2.ml
50 lines (45 loc) · 1.31 KB
/
random2.ml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
(* From Elm 0.19 *)
let rec get_by_weight : float * 'a -> (float * 'a) list -> float -> 'a =
fun (weight, value) others countdown ->
match others with
| [] ->
value
| second :: other_others ->
if countdown <= abs_float weight then
value
else
get_by_weight second other_others (countdown -. abs_float weight)
(* From Elm 0.19 *)
let weighted : float * 'a -> (float * 'a) list -> 'a =
fun first others ->
let normalize (weight, _) =
abs_float weight
in
let total =
normalize first +. List2.fsum (List.map normalize others)
in
get_by_weight
first
others
(Random.float total)
let rec sample_unique_helper :
'a list -> (int * (unit -> 'a)) list -> 'a list =
fun acc info ->
match info with
| [] ->
acc
| (size, gen) :: rest_info ->
if List.length acc >= size then
sample_unique_helper acc rest_info
else
let x =
gen ()
in
if Option.is_some (List.find_opt ((=) x) acc) then
sample_unique_helper acc info
else
sample_unique_helper (x :: acc) info
let sample_unique : (int * (unit -> 'a)) list -> 'a list =
fun info ->
sample_unique_helper [] info
|> List.rev