let (<<) f g x = f (g x)
let tally xs =
let increment key
= match Hashtbl.find_opt h key
with | Some count
-> Hashtbl.replace h key
(count
+ 1) in
let () = List.iter increment xs
in h
let factrial =
let rec aux acc = function
0 -> acc
| n -> aux (acc * n) (n - 1)
in aux 1
let n_permutations xs =
factrial
(List.length xs
) / Hashtbl.fold
(fun k v acc
-> acc
* factrial v
) (tally xs
) 1let count f =
List.fold_left
(fun acc x
-> acc
+ if f x
then 1 else 0) 0 let f =
let rec aux acc = function
[] -> acc
| x
:: xs
as ys
-> aux
(acc
+ count
((>) x
) xs
* n_permutations ys
/ List.length ys
) xs
in aux 1
let () =
g [1;2;3;4;5;6;7;8;9];
g [1;2;3;4;5;6;7;9;8];
g [1;2;3;4;5;6;8;7;9];
g [4;1;6;5;8;9;7;3;2];
g [6;8;4;7;5;3;2;1;9];
g [9;8;7;6;5;4;3;2;1];
g [1;1;1;2;2;2;3;3;3;4;4;4];
g [1;1;1;2;2;2;3;3;4;3;4;4];
g [1;1;1;2;2;2;3;3;4;4;3;4];
g [2;2;2;3;3;1;4;3;4;1;1;4];
g [3;2;4;4;2;4;3;3;1;1;1;2];
g [4;4;4;3;3;3;2;2;2;1;1;1];
g [3;1;4;1;5;9];
bGV0ICg8PCkgZiBnIHggPSBmIChnIHgpCmxldCB0YWxseSB4cyA9CiAgbGV0IGggPSBIYXNodGJsLmNyZWF0ZSAzMiBpbgogIGxldCBpbmNyZW1lbnQga2V5ID0gbWF0Y2ggSGFzaHRibC5maW5kX29wdCBoIGtleSB3aXRoCiAgICAgIE5vbmUgLT4gSGFzaHRibC5hZGQgaCBrZXkgMQogICAgfCBTb21lIGNvdW50IC0+IEhhc2h0YmwucmVwbGFjZSBoIGtleSAoY291bnQgKyAxKQogIGluCiAgbGV0ICgpID0gTGlzdC5pdGVyIGluY3JlbWVudCB4cyBpbiBoCmxldCBmYWN0cmlhbCA9CiAgbGV0IHJlYyBhdXggYWNjID0gZnVuY3Rpb24KICAgICAgMCAtPiBhY2MKICAgIHwgbiAtPiBhdXggKGFjYyAqIG4pIChuIC0gMSkKICBpbiBhdXggMQpsZXQgbl9wZXJtdXRhdGlvbnMgeHMgPQogIGZhY3RyaWFsIChMaXN0Lmxlbmd0aCB4cykgLyBIYXNodGJsLmZvbGQgKGZ1biBrIHYgYWNjIC0+IGFjYyAqIGZhY3RyaWFsIHYpICh0YWxseSB4cykgMQpsZXQgY291bnQgZiA9CiAgTGlzdC5mb2xkX2xlZnQgKGZ1biBhY2MgeCAtPiBhY2MgKyBpZiBmIHggdGhlbiAxIGVsc2UgMCkgMApsZXQgZiA9CiAgbGV0IHJlYyBhdXggYWNjID0gZnVuY3Rpb24KICAgICAgW10gLT4gYWNjCiAgICB8IHggOjogeHMgYXMgeXMgLT4gYXV4IChhY2MgKyBjb3VudCAoKD4pIHgpIHhzICogbl9wZXJtdXRhdGlvbnMgeXMgLyBMaXN0Lmxlbmd0aCB5cykgeHMKICBpbiBhdXggMQpsZXQgZyA9IHByaW50X25ld2xpbmUgPDwgcHJpbnRfaW50IDw8IGYKbGV0ICgpID0KICBnIFsxOzI7Mzs0OzU7Njs3Ozg7OV07CiAgZyBbMTsyOzM7NDs1OzY7Nzs5OzhdOwogIGcgWzE7MjszOzQ7NTs2Ozg7Nzs5XTsKICBnIFs0OzE7Njs1Ozg7OTs3OzM7Ml07CiAgZyBbNjs4OzQ7Nzs1OzM7MjsxOzldOwogIGcgWzk7ODs3OzY7NTs0OzM7MjsxXTsKICBnIFsxOzE7MTsyOzI7MjszOzM7Mzs0OzQ7NF07CiAgZyBbMTsxOzE7MjsyOzI7MzszOzQ7Mzs0OzRdOwogIGcgWzE7MTsxOzI7MjsyOzM7Mzs0OzQ7Mzs0XTsKICBnIFsyOzI7MjszOzM7MTs0OzM7NDsxOzE7NF07CiAgZyBbMzsyOzQ7NDsyOzQ7MzszOzE7MTsxOzJdOwogIGcgWzQ7NDs0OzM7MzszOzI7MjsyOzE7MTsxXTsKICBnIFszOzE7NDsxOzU7OV07Cg==