2024-10-05 18:40:45 +02:00
|
|
|
let rec pow a = function
|
|
|
|
|
| 0 -> 1
|
|
|
|
|
| 1 -> a
|
|
|
|
|
| n ->
|
|
|
|
|
let b = pow a (n / 2) in
|
|
|
|
|
b * b * (if n mod 2 = 0 then 1 else a)
|
2024-10-07 14:13:28 +02:00
|
|
|
|
|
|
|
|
let rec powmod a d = function
|
|
|
|
|
| 0 -> 1
|
|
|
|
|
| 1 -> a mod d
|
|
|
|
|
| n ->
|
|
|
|
|
let b = (powmod a d (n / 2)) mod d in
|
|
|
|
|
(((b * b) mod d) * (if n mod 2 = 0 then 1 else a)) mod d
|
2024-12-01 12:55:20 +01:00
|
|
|
|
2024-12-03 17:18:42 +01:00
|
|
|
let int_and a b =
|
|
|
|
|
match (a>0, b>0) with
|
|
|
|
|
true, true -> 1
|
|
|
|
|
| _, _ -> 0
|
|
|
|
|
|
|
|
|
|
let int_or a b =
|
|
|
|
|
match (a>0, b>0) with
|
|
|
|
|
false, false -> 0
|
|
|
|
|
| _, _ -> 1
|
|
|
|
|
|
|
|
|
|
let int_eq a b =
|
|
|
|
|
if a = b then 1 else 0
|
|
|
|
|
|
|
|
|
|
let int_less a b =
|
|
|
|
|
if a < b then 1 else 0
|
|
|
|
|
|
|
|
|
|
let int_less_eq a b =
|
|
|
|
|
if a <= b then 1 else 0
|
|
|
|
|
|
|
|
|
|
let int_more a b =
|
|
|
|
|
if a > b then 1 else 0
|
|
|
|
|
|
|
|
|
|
let int_more_eq a b =
|
|
|
|
|
if a >= b then 1 else 0
|
|
|
|
|
|
|
|
|
|
let int_not a =
|
|
|
|
|
if a > 0 then 0 else 1
|
|
|
|
|
|
2024-12-16 05:15:33 +01:00
|
|
|
(* converts an integer to a list of chars such that it is pretty and linear *)
|
2024-12-01 12:55:20 +01:00
|
|
|
let rec fromIntToString (alphabet: string) (x: int) : string =
|
|
|
|
|
let base = String.length alphabet in
|
|
|
|
|
if x < 0 then
|
|
|
|
|
""
|
|
|
|
|
else if x < base then
|
|
|
|
|
String.get alphabet x |> String.make 1
|
|
|
|
|
else
|
2024-12-16 05:15:33 +01:00
|
|
|
(fromIntToString (alphabet) (x/base - 1)) ^ (String.get alphabet (x mod base)
|
|
|
|
|
|> String.make 1)
|
|
|
|
|
|
|
|
|
|
|
2024-12-27 21:11:38 +01:00
|
|
|
(* true if every element of la is in lb *)
|
2024-12-16 05:15:33 +01:00
|
|
|
let inclusion la lb =
|
|
|
|
|
let rec aux la =
|
|
|
|
|
function
|
|
|
|
|
[] -> true
|
|
|
|
|
| b::lb ->
|
|
|
|
|
if List.mem b la
|
|
|
|
|
then aux la lb
|
|
|
|
|
else false
|
|
|
|
|
in
|
|
|
|
|
aux lb la
|
|
|
|
|
|
2024-12-27 21:11:38 +01:00
|
|
|
(* true if lb includes la and la includes lb *)
|
|
|
|
|
let equality la lb =
|
|
|
|
|
inclusion la lb && inclusion lb la
|
|
|
|
|
|
|
|
|
|
(* computes the result of la \setminus lb *)
|
2024-12-16 05:15:33 +01:00
|
|
|
let subtraction la lb =
|
|
|
|
|
let rec aux la =
|
|
|
|
|
function
|
|
|
|
|
[] -> la
|
|
|
|
|
| b::lb ->
|
|
|
|
|
aux (List.filter ((<>) b) la) lb
|
|
|
|
|
in
|
|
|
|
|
aux la lb
|
|
|
|
|
|
|
|
|
|
(* returns only the unique elements of l *)
|
|
|
|
|
let unique l =
|
|
|
|
|
let rec aux l acc =
|
|
|
|
|
match l with
|
|
|
|
|
| [] ->
|
|
|
|
|
List.rev acc
|
|
|
|
|
| h :: t ->
|
|
|
|
|
if List.mem h acc
|
|
|
|
|
then aux t acc
|
|
|
|
|
else aux t (h :: acc)
|
|
|
|
|
in
|
|
|
|
|
aux l []
|
|
|
|
|
|
|
|
|
|
(* returns the unique elements of the concat of the lists *)
|
|
|
|
|
let unique_union la lb =
|
|
|
|
|
unique (la @ lb)
|
|
|
|
|
|
2024-12-27 21:11:38 +01:00
|
|
|
(* returns all elements both in la and in lb *)
|
2024-12-16 05:15:33 +01:00
|
|
|
let unique_intersection la lb =
|
2024-12-27 21:11:38 +01:00
|
|
|
let rec aux la acc =
|
2024-12-16 05:15:33 +01:00
|
|
|
match la with
|
|
|
|
|
[] -> acc
|
|
|
|
|
| a::la ->
|
|
|
|
|
if List.mem a lb
|
2024-12-27 21:11:38 +01:00
|
|
|
then aux la (a::acc)
|
|
|
|
|
else aux la acc
|
2024-12-16 05:15:33 +01:00
|
|
|
in
|
2024-12-27 21:11:38 +01:00
|
|
|
aux la [] |> unique
|
2024-12-16 05:15:33 +01:00
|
|
|
|
2024-12-27 21:11:38 +01:00
|
|
|
(* returns a list with at most n items and the rest in the second *)
|
|
|
|
|
let rec take (n: int) (l: 'a list) : ('a list * 'a list) =
|
|
|
|
|
match n with
|
|
|
|
|
| 0 -> ([], l)
|
|
|
|
|
| n ->
|
|
|
|
|
match l with
|
|
|
|
|
| [] -> ([], [])
|
|
|
|
|
| i::ls ->
|
|
|
|
|
let (t1, t2) = (take (n - 1) ls) in
|
|
|
|
|
((i :: t1), (t2))
|
2024-12-16 05:15:33 +01:00
|
|
|
|
2024-12-27 21:11:38 +01:00
|
|
|
(* returns the list without the last element *)
|
2024-12-21 02:16:04 +01:00
|
|
|
let drop_last_element_list =
|
|
|
|
|
function
|
|
|
|
|
| [] -> []
|
|
|
|
|
| l -> l |> List.rev |> List.tl |> List.rev
|
|
|
|
|
|
2024-12-27 21:11:38 +01:00
|
|
|
let drop_first_element_list =
|
|
|
|
|
function
|
|
|
|
|
| [] -> []
|
|
|
|
|
| _::l -> l
|
|
|
|
|
|
2024-12-16 05:15:33 +01:00
|
|
|
(* Complicated way to drop the last element and add a new option element to the
|
|
|
|
|
beginning *)
|
|
|
|
|
let prev l a =
|
|
|
|
|
match l with
|
|
|
|
|
| [] ->
|
|
|
|
|
[a]
|
|
|
|
|
| _ ->
|
2024-12-21 02:16:04 +01:00
|
|
|
a :: (List.map (fun x -> Some x) (drop_last_element_list l))
|
2024-12-16 05:15:33 +01:00
|
|
|
|
|
|
|
|
let pad l a n =
|
|
|
|
|
let l = List.map (fun i -> Some i) l in
|
|
|
|
|
if List.length l < n
|
|
|
|
|
then
|
|
|
|
|
l @ (List.init (n - List.length l) (fun _ -> a))
|
|
|
|
|
else
|
|
|
|
|
l
|
|
|
|
|
|
|
|
|
|
let pad_opt l a n =
|
|
|
|
|
if List.length l < n
|
|
|
|
|
then
|
|
|
|
|
l @ (List.init (n - List.length l) (fun _ -> a))
|
|
|
|
|
else
|
|
|
|
|
l
|
|
|
|
|
|
|
|
|
|
let combine la lb =
|
|
|
|
|
List.map2 (fun a b ->
|
|
|
|
|
match b with
|
|
|
|
|
None -> None
|
|
|
|
|
| Some b -> Some (a, b)
|
|
|
|
|
) la lb
|
|
|
|
|
|
|
|
|
|
let rec last_list l =
|
|
|
|
|
match l with
|
|
|
|
|
[] -> failwith "Utility.last_list, not enough items"
|
|
|
|
|
| [a] -> a
|
|
|
|
|
| _::ll -> last_list ll
|
|
|
|
|
|
|
|
|
|
let add_to_last_list (la: 'a list list) (a: 'a) : 'a list list =
|
|
|
|
|
let rec aux la a =
|
|
|
|
|
match la with
|
|
|
|
|
[] -> [[a]]
|
|
|
|
|
| [l] -> [a :: l]
|
|
|
|
|
| l::la -> l :: (aux la a)
|
|
|
|
|
in
|
|
|
|
|
aux la a
|
|
|
|
|
|
2024-12-27 21:11:38 +01:00
|
|
|
let rec combine_twice la lb =
|
|
|
|
|
match (la, lb) with
|
|
|
|
|
| [], [] -> []
|
|
|
|
|
| [a], [b] -> [a, b]
|
|
|
|
|
| a::la, b::lb -> (a, b) :: (combine_twice la lb)
|
|
|
|
|
| _ -> []
|
|
|
|
|
|
2024-12-16 05:15:33 +01:00
|
|
|
let rec combine_thrice la lb lc =
|
|
|
|
|
match (la, lb, lc) with
|
|
|
|
|
| [], [], [] -> []
|
|
|
|
|
| [a], [b], [c] -> [a, b, c]
|
|
|
|
|
| a::la, b::lb, c::lc -> (a, b, c) :: (combine_thrice la lb lc)
|
|
|
|
|
| _ -> []
|