682 lines
19 KiB
OCaml
682 lines
19 KiB
OCaml
open! Import
|
|
open Base_quickcheck
|
|
open Expect_test_helpers_base
|
|
open Array
|
|
|
|
let%test_module "Binary_searchable" =
|
|
(module Test_binary_searchable.Test1 (struct
|
|
include Array
|
|
|
|
module For_test = struct
|
|
let of_array = Fn.id
|
|
end
|
|
end))
|
|
;;
|
|
|
|
let%test_module "Blit" =
|
|
(module Test_blit.Test1
|
|
(struct
|
|
type 'a z = 'a
|
|
|
|
include Array
|
|
|
|
let create_bool ~len = create ~len false
|
|
end)
|
|
(Array))
|
|
;;
|
|
|
|
module List_helpers = struct
|
|
let rec sprinkle x xs =
|
|
(x :: xs)
|
|
::
|
|
(match xs with
|
|
| [] -> []
|
|
| x' :: xs' -> List.map (sprinkle x xs') ~f:(fun sprinkled -> x' :: sprinkled))
|
|
;;
|
|
|
|
let rec permutations = function
|
|
| [] -> [ [] ]
|
|
| x :: xs -> List.concat_map (permutations xs) ~f:(fun perms -> sprinkle x perms)
|
|
;;
|
|
end
|
|
|
|
let%test_module "Sort" =
|
|
(module struct
|
|
open Private.Sort
|
|
|
|
let%test_module "Intro_sort.five_element_sort" =
|
|
(module struct
|
|
(* run [five_element_sort] on all permutations of an array of five elements *)
|
|
|
|
let all_perms = List_helpers.permutations [ 1; 2; 3; 4; 5 ]
|
|
let%test _ = List.length all_perms = 120
|
|
let%test _ = not (List.contains_dup ~compare:[%compare: int list] all_perms)
|
|
|
|
let%test _ =
|
|
List.for_all all_perms ~f:(fun l ->
|
|
let arr = Array.of_list l in
|
|
Intro_sort.five_element_sort arr ~compare:[%compare: int] 0 1 2 3 4;
|
|
[%compare.equal: int t] arr [| 1; 2; 3; 4; 5 |])
|
|
;;
|
|
end)
|
|
;;
|
|
|
|
module Test (M : Private.Sort.Sort) = struct
|
|
let random_data ~length ~range =
|
|
let arr = Array.create ~len:length 0 in
|
|
for i = 0 to length - 1 do
|
|
arr.(i) <- Random.int range
|
|
done;
|
|
arr
|
|
;;
|
|
|
|
let assert_sorted arr =
|
|
M.sort arr ~left:0 ~right:(Array.length arr - 1) ~compare:[%compare: int];
|
|
let len = Array.length arr in
|
|
let rec loop i prev =
|
|
if i = len then true else if arr.(i) < prev then false else loop (i + 1) arr.(i)
|
|
in
|
|
loop 0 (-1)
|
|
;;
|
|
|
|
let%test _ = assert_sorted (random_data ~length:0 ~range:100)
|
|
let%test _ = assert_sorted (random_data ~length:1 ~range:100)
|
|
let%test _ = assert_sorted (random_data ~length:100 ~range:1_000)
|
|
let%test _ = assert_sorted (random_data ~length:1_000 ~range:1)
|
|
let%test _ = assert_sorted (random_data ~length:1_000 ~range:10)
|
|
let%test _ = assert_sorted (random_data ~length:1_000 ~range:1_000_000)
|
|
end
|
|
|
|
let%test_module _ = (module Test (Insertion_sort))
|
|
let%test_module _ = (module Test (Heap_sort))
|
|
let%test_module _ = (module Test (Intro_sort))
|
|
end)
|
|
;;
|
|
|
|
let%test _ = is_sorted [||] ~compare:[%compare: int]
|
|
let%test _ = is_sorted [| 0 |] ~compare:[%compare: int]
|
|
let%test _ = is_sorted [| 0; 1; 2; 2; 4 |] ~compare:[%compare: int]
|
|
let%test _ = not (is_sorted [| 0; 1; 2; 3; 2 |] ~compare:[%compare: int])
|
|
|
|
let%test_unit _ =
|
|
List.iter
|
|
~f:(fun (t, expect) ->
|
|
assert (Bool.equal expect (is_sorted_strictly (of_list t) ~compare:[%compare: int])))
|
|
[ [], true
|
|
; [ 1 ], true
|
|
; [ 1; 2 ], true
|
|
; [ 1; 1 ], false
|
|
; [ 2; 1 ], false
|
|
; [ 1; 2; 3 ], true
|
|
; [ 1; 1; 3 ], false
|
|
; [ 1; 2; 2 ], false
|
|
]
|
|
;;
|
|
|
|
let%expect_test "merge" =
|
|
let test a1 a2 =
|
|
let res = merge a1 a2 ~compare:Int.compare in
|
|
print_s ([%sexp_of: int array] res);
|
|
require_equal
|
|
[%here]
|
|
(module struct
|
|
type t = int list [@@deriving equal, sexp_of]
|
|
end)
|
|
(to_list res)
|
|
(List.merge (to_list a1) (to_list a2) ~compare:Int.compare)
|
|
in
|
|
test [||] [||];
|
|
[%expect {| () |}];
|
|
test [| 1; 2; 3 |] [||];
|
|
[%expect {| (1 2 3) |}];
|
|
test [||] [| 1; 2; 3 |];
|
|
[%expect {| (1 2 3) |}];
|
|
test [| 1; 2; 3 |] [| 1; 2; 3 |];
|
|
[%expect {| (1 1 2 2 3 3) |}];
|
|
test [| 1; 2; 3 |] [| 4; 5; 6 |];
|
|
[%expect {| (1 2 3 4 5 6) |}];
|
|
test [| 4; 5; 6 |] [| 1; 2; 3 |];
|
|
[%expect {| (1 2 3 4 5 6) |}];
|
|
test [| 3; 5 |] [| 1; 2; 4; 6 |];
|
|
[%expect {| (1 2 3 4 5 6) |}];
|
|
test [| 1; 3; 7; 8; 9 |] [| 2; 4; 5; 6 |];
|
|
[%expect {| (1 2 3 4 5 6 7 8 9) |}];
|
|
test [| 1; 2; 2; 3 |] [| 2; 2; 3; 4 |];
|
|
[%expect {| (1 2 2 2 2 3 3 4) |}]
|
|
;;
|
|
|
|
let%expect_test "merge with duplicates" =
|
|
(* Testing that equal elements from a1 come before equal elements from a2 *)
|
|
let test a1 a2 =
|
|
let compare a b = Comparable.lift Int.compare ~f:fst a b in
|
|
let res = merge a1 a2 ~compare in
|
|
print_s ([%sexp_of: (int * string) array] res);
|
|
require_equal
|
|
[%here]
|
|
(module struct
|
|
type t = (int * string) list [@@deriving equal, sexp_of]
|
|
end)
|
|
(to_list res)
|
|
(List.merge (to_list a1) (to_list a2) ~compare)
|
|
in
|
|
test [| 1, "a1" |] [| 1, "a2" |];
|
|
[%expect {|
|
|
((1 a1)
|
|
(1 a2))
|
|
|}];
|
|
test [| 1, "a1"; 2, "a1"; 3, "a1" |] [| 3, "a2"; 4, "a2"; 5, "a2" |];
|
|
[%expect
|
|
{|
|
|
((1 a1)
|
|
(2 a1)
|
|
(3 a1)
|
|
(3 a2)
|
|
(4 a2)
|
|
(5 a2))
|
|
|}];
|
|
test [| 3, "a1"; 4, "a1"; 5, "a1" |] [| 1, "a2"; 2, "a2"; 3, "a2" |];
|
|
[%expect
|
|
{|
|
|
((1 a2)
|
|
(2 a2)
|
|
(3 a1)
|
|
(3 a2)
|
|
(4 a1)
|
|
(5 a1))
|
|
|}];
|
|
test [| 1, "a1"; 3, "a1"; 3, "a1"; 5, "a1" |] [| 2, "a2"; 3, "a2"; 3, "a2"; 4, "a2" |];
|
|
[%expect
|
|
{|
|
|
((1 a1)
|
|
(2 a2)
|
|
(3 a1)
|
|
(3 a1)
|
|
(3 a2)
|
|
(3 a2)
|
|
(4 a2)
|
|
(5 a1))
|
|
|}]
|
|
;;
|
|
|
|
let%test _ = foldi [||] ~init:13 ~f:(fun _ _ _ -> failwith "bad") = 13
|
|
let%test _ = foldi [| 13 |] ~init:17 ~f:(fun i ac x -> ac + i + x) = 30
|
|
let%test _ = foldi [| 13; 17 |] ~init:19 ~f:(fun i ac x -> ac + i + x) = 50
|
|
|
|
let%test_module "count{,i}" =
|
|
(module struct
|
|
let%expect_test "[Array.count{,i} = List.count{,i}]" =
|
|
quickcheck_m
|
|
[%here]
|
|
(module struct
|
|
type t = int list * (int -> bool) [@@deriving quickcheck, sexp_of]
|
|
end)
|
|
~f:(fun (list, f) ->
|
|
require_equal
|
|
[%here]
|
|
(module Int)
|
|
(list |> List.count ~f)
|
|
(list |> of_list |> count ~f));
|
|
quickcheck_m
|
|
[%here]
|
|
(module struct
|
|
type t = int list * (int -> int -> bool) [@@deriving quickcheck, sexp_of]
|
|
end)
|
|
~f:(fun (list, f) ->
|
|
require_equal
|
|
[%here]
|
|
(module Int)
|
|
(list |> List.counti ~f)
|
|
(list |> of_list |> counti ~f))
|
|
;;
|
|
|
|
let%test _ = counti [| 0; 1; 2; 3; 4 |] ~f:(fun idx x -> idx = x) = 5
|
|
let%test _ = counti [| 0; 1; 2; 3; 4 |] ~f:(fun idx x -> idx = 4 - x) = 1
|
|
end)
|
|
;;
|
|
|
|
let%test_module "{min,max}_elt" =
|
|
(module struct
|
|
let test_opt_selector arr_fun list_fun =
|
|
quickcheck_m
|
|
[%here]
|
|
(module struct
|
|
type t = int list [@@deriving sexp_of, quickcheck]
|
|
end)
|
|
~f:(fun list ->
|
|
let arr = of_list list in
|
|
require_equal
|
|
[%here]
|
|
(module struct
|
|
type t = int option [@@deriving sexp_of, equal]
|
|
end)
|
|
(arr_fun arr ~compare:(fun x y -> Int.compare x y))
|
|
(list_fun list ~compare:(fun x y -> Int.compare x y)))
|
|
;;
|
|
|
|
let%expect_test "min_elt" = test_opt_selector min_elt List.min_elt
|
|
let%expect_test "max_elt" = test_opt_selector max_elt List.max_elt
|
|
end)
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
for i = 0 to 5 do
|
|
let l1 = List.init i ~f:Fn.id in
|
|
let l2 = List.rev (to_list (of_list_rev l1)) in
|
|
assert ([%compare.equal: int list] l1 l2)
|
|
done
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: int array]
|
|
(filter_opt [| Some 1; None; Some 2; None; Some 3 |])
|
|
~expect:[| 1; 2; 3 |]
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: int array] (filter_opt [| Some 1; None; Some 2 |]) ~expect:[| 1; 2 |]
|
|
;;
|
|
|
|
let%test_unit _ = [%test_result: int array] (filter_opt [| Some 1 |]) ~expect:[| 1 |]
|
|
let%test_unit _ = [%test_result: int array] (filter_opt [| None |]) ~expect:[||]
|
|
let%test_unit _ = [%test_result: int array] (filter_opt [||]) ~expect:[||]
|
|
|
|
let%expect_test _ =
|
|
print_s ([%sexp_of: int array] (map2_exn [| 1; 2; 3 |] [| 2; 3; 4 |] ~f:( + )));
|
|
[%expect {| (3 5 7) |}]
|
|
;;
|
|
|
|
let%expect_test "map2_exn raise" =
|
|
require_does_raise [%here] (fun () -> map2_exn [| 1; 2; 3 |] [| 2; 3; 4; 5 |] ~f:( + ));
|
|
[%expect {| (Invalid_argument "length mismatch in Array.map2_exn: 3 <> 4") |}]
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: int]
|
|
(fold2_exn [||] [||] ~init:13 ~f:(fun _ -> failwith "fail"))
|
|
~expect:13
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: (int * string) list]
|
|
(fold2_exn [| 1 |] [| "1" |] ~init:[] ~f:(fun ac a b -> (a, b) :: ac))
|
|
~expect:[ 1, "1" ]
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: int array] (filter [| 0; 1 |] ~f:(fun n -> n < 2)) ~expect:[| 0; 1 |]
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: int array] (filter [| 0; 1 |] ~f:(fun n -> n < 1)) ~expect:[| 0 |]
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: int array] (filter [| 0; 1 |] ~f:(fun n -> n < 0)) ~expect:[||]
|
|
;;
|
|
|
|
let%test_unit _ = [%test_result: bool] (exists [||] ~f:(fun _ -> true)) ~expect:false
|
|
|
|
let%test_unit _ =
|
|
[%test_result: bool] (exists [| 0; 1; 2; 3 |] ~f:(fun x -> 4 = x)) ~expect:false
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: bool] (exists [| 0; 1; 2; 3 |] ~f:(fun x -> 2 = x)) ~expect:true
|
|
;;
|
|
|
|
let%test_unit _ = [%test_result: bool] (existsi [||] ~f:(fun _ _ -> true)) ~expect:false
|
|
|
|
let%test_unit _ =
|
|
[%test_result: bool] (existsi [| 0; 1; 2; 3 |] ~f:(fun i x -> i <> x)) ~expect:false
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: bool] (existsi [| 0; 1; 3; 3 |] ~f:(fun i x -> i <> x)) ~expect:true
|
|
;;
|
|
|
|
let%test_unit _ = [%test_result: bool] (for_all [||] ~f:(fun _ -> false)) ~expect:true
|
|
|
|
let%test_unit _ =
|
|
[%test_result: bool] (for_all [| 1; 2; 3 |] ~f:Int.is_positive) ~expect:true
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: bool] (for_all [| 0; 1; 3; 3 |] ~f:Int.is_positive) ~expect:false
|
|
;;
|
|
|
|
let%test_unit _ = [%test_result: bool] (for_alli [||] ~f:(fun _ _ -> false)) ~expect:true
|
|
|
|
let%test_unit _ =
|
|
[%test_result: bool] (for_alli [| 0; 1; 2; 3 |] ~f:(fun i x -> i = x)) ~expect:true
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: bool] (for_alli [| 0; 1; 3; 3 |] ~f:(fun i x -> i = x)) ~expect:false
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: bool] (exists2_exn [||] [||] ~f:(fun _ _ -> true)) ~expect:false
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: bool]
|
|
(exists2_exn [| 0; 2; 4; 6 |] [| 0; 2; 4; 6 |] ~f:(fun x y -> x <> y))
|
|
~expect:false
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: bool]
|
|
(exists2_exn [| 0; 2; 4; 8 |] [| 0; 2; 4; 6 |] ~f:(fun x y -> x <> y))
|
|
~expect:true
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: bool]
|
|
(exists2_exn [| 2; 2; 4; 6 |] [| 0; 2; 4; 6 |] ~f:(fun x y -> x <> y))
|
|
~expect:true
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: bool] (for_all2_exn [||] [||] ~f:(fun _ _ -> false)) ~expect:true
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: bool]
|
|
(for_all2_exn [| 0; 2; 4; 6 |] [| 0; 2; 4; 6 |] ~f:(fun x y -> x = y))
|
|
~expect:true
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: bool]
|
|
(for_all2_exn [| 0; 2; 4; 8 |] [| 0; 2; 4; 6 |] ~f:(fun x y -> x = y))
|
|
~expect:false
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: bool]
|
|
(for_all2_exn [| 2; 2; 4; 6 |] [| 0; 2; 4; 6 |] ~f:(fun x y -> x = y))
|
|
~expect:false
|
|
;;
|
|
|
|
let%test_unit _ = [%test_result: bool] (equal ( = ) [||] [||]) ~expect:true
|
|
let%test_unit _ = [%test_result: bool] (equal ( = ) [| 1 |] [| 1 |]) ~expect:true
|
|
let%test_unit _ = [%test_result: bool] (equal ( = ) [| 1; 2 |] [| 1; 2 |]) ~expect:true
|
|
let%test_unit _ = [%test_result: bool] (equal ( = ) [||] [| 1 |]) ~expect:false
|
|
let%test_unit _ = [%test_result: bool] (equal ( = ) [| 1 |] [||]) ~expect:false
|
|
let%test_unit _ = [%test_result: bool] (equal ( = ) [| 1 |] [| 1; 2 |]) ~expect:false
|
|
let%test_unit _ = [%test_result: bool] (equal ( = ) [| 1; 2 |] [| 1; 3 |]) ~expect:false
|
|
|
|
let%test_unit _ =
|
|
[%test_result: (int * int) option]
|
|
(findi [| 1; 2; 3; 4 |] ~f:(fun i x -> i = 2 * x))
|
|
~expect:None
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: (int * int) option]
|
|
(findi [| 1; 2; 1; 4 |] ~f:(fun i x -> i = 2 * x))
|
|
~expect:(Some (2, 1))
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: int option]
|
|
(find_mapi [| 0; 5; 2; 1; 4 |] ~f:(fun i x -> if i = x then Some (i + x) else None))
|
|
~expect:(Some 0)
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: int option]
|
|
(find_mapi [| 3; 5; 2; 1; 4 |] ~f:(fun i x -> if i = x then Some (i + x) else None))
|
|
~expect:(Some 4)
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: int option]
|
|
(find_mapi [| 3; 5; 1; 1; 4 |] ~f:(fun i x -> if i = x then Some (i + x) else None))
|
|
~expect:(Some 8)
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
[%test_result: int option]
|
|
(find_mapi [| 3; 5; 1; 1; 2 |] ~f:(fun i x -> if i = x then Some (i + x) else None))
|
|
~expect:None
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
List.iter
|
|
~f:(fun (l, expect) ->
|
|
let t = of_list l in
|
|
assert (Poly.equal expect (find_consecutive_duplicate t ~equal:Poly.equal)))
|
|
[ [], None
|
|
; [ 1 ], None
|
|
; [ 1; 1 ], Some (1, 1)
|
|
; [ 1; 2 ], None
|
|
; [ 1; 2; 1 ], None
|
|
; [ 1; 2; 2 ], Some (2, 2)
|
|
; [ 1; 1; 2; 2 ], Some (1, 1)
|
|
]
|
|
;;
|
|
|
|
let%test_unit _ = [%test_result: int option] (random_element [||]) ~expect:None
|
|
let%test_unit _ = [%test_result: int option] (random_element [| 0 |]) ~expect:(Some 0)
|
|
|
|
let%test_unit _ =
|
|
List.iter
|
|
[ [||]; [| 1 |]; [| 1; 2; 3; 4; 5 |] ]
|
|
~f:(fun t -> [%test_result: int array] (Sequence.to_array (to_sequence t)) ~expect:t)
|
|
;;
|
|
|
|
let test_fold_map array ~init ~f ~expect =
|
|
[%test_result: int array] (folding_map array ~init ~f) ~expect:(snd expect);
|
|
[%test_result: int * int array] (fold_map array ~init ~f) ~expect
|
|
;;
|
|
|
|
let test_fold_mapi array ~init ~f ~expect =
|
|
[%test_result: int array] (folding_mapi array ~init ~f) ~expect:(snd expect);
|
|
[%test_result: int * int array] (fold_mapi array ~init ~f) ~expect
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
test_fold_map
|
|
[| 1; 2; 3; 4 |]
|
|
~init:0
|
|
~f:(fun acc x ->
|
|
let y = acc + x in
|
|
y, y)
|
|
~expect:(10, [| 1; 3; 6; 10 |])
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
test_fold_map
|
|
[||]
|
|
~init:0
|
|
~f:(fun acc x ->
|
|
let y = acc + x in
|
|
y, y)
|
|
~expect:(0, [||])
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
test_fold_mapi
|
|
[| 1; 2; 3; 4 |]
|
|
~init:0
|
|
~f:(fun i acc x ->
|
|
let y = acc + (i * x) in
|
|
y, y)
|
|
~expect:(20, [| 0; 2; 8; 20 |])
|
|
;;
|
|
|
|
let%test_unit _ =
|
|
test_fold_mapi
|
|
[||]
|
|
~init:0
|
|
~f:(fun i acc x ->
|
|
let y = acc + (i * x) in
|
|
y, y)
|
|
~expect:(0, [||])
|
|
;;
|
|
|
|
let%test_module "permute" =
|
|
(module struct
|
|
module Int_list = struct
|
|
type t = int list [@@deriving compare, sexp_of]
|
|
|
|
include (val Comparator.make ~compare ~sexp_of_t)
|
|
end
|
|
|
|
let test_permute initial_contents ~pos ~len =
|
|
let all_permutations =
|
|
let pos, len =
|
|
Ordered_collection_common.get_pos_len_exn
|
|
?pos
|
|
?len
|
|
~total_length:(List.length initial_contents)
|
|
()
|
|
in
|
|
let left = List.take initial_contents pos in
|
|
let middle = List.sub initial_contents ~pos ~len in
|
|
let right = List.drop initial_contents (pos + len) in
|
|
Set.of_list
|
|
(module Int_list)
|
|
(List_helpers.permutations middle
|
|
|> List.map ~f:(fun middle -> left @ middle @ right))
|
|
in
|
|
let not_yet_seen = ref all_permutations in
|
|
while not (Set.is_empty !not_yet_seen) do
|
|
let array = of_list initial_contents in
|
|
permute ?pos ?len array;
|
|
let permutation = to_list array in
|
|
if not (Set.mem all_permutations permutation)
|
|
then
|
|
raise_s
|
|
[%sexp
|
|
"invalid permutation"
|
|
, { array_length = (List.length initial_contents : int)
|
|
; permutation : int list
|
|
; pos : int option
|
|
; len : int option
|
|
}];
|
|
not_yet_seen := Set.remove !not_yet_seen permutation
|
|
done
|
|
;;
|
|
|
|
let%expect_test "permute different array lengths and subranges" =
|
|
let indices = None :: List.map [ 0; 1; 2; 3; 4 ] ~f:Option.some in
|
|
for array_length = 0 to 4 do
|
|
let initial_contents = List.init array_length ~f:Int.succ in
|
|
List.iter indices ~f:(fun pos ->
|
|
List.iter indices ~f:(fun len ->
|
|
match
|
|
Ordered_collection_common.get_pos_len
|
|
?pos
|
|
?len
|
|
~total_length:array_length
|
|
()
|
|
with
|
|
| Ok _ -> test_permute initial_contents ~pos ~len
|
|
| Error _ ->
|
|
require
|
|
[%here]
|
|
(Exn.does_raise (fun () ->
|
|
permute ?pos ?len (Array.of_list initial_contents)))))
|
|
done;
|
|
[%expect {| |}]
|
|
;;
|
|
end)
|
|
;;
|
|
|
|
let%expect_test "create_float_uninitialized" =
|
|
let array = create_float_uninitialized ~len:10 in
|
|
(* make sure reading/writing the array is safe *)
|
|
Array.permute array;
|
|
(* sanity check without depending on specific contents *)
|
|
print_s [%sexp (Array.length array : int)];
|
|
[%expect {| 10 |}]
|
|
;;
|
|
|
|
module Int_array = struct
|
|
type t = int array [@@deriving equal, sexp_of]
|
|
end
|
|
|
|
module Int_list = struct
|
|
type t = int list [@@deriving equal, sexp_of]
|
|
end
|
|
|
|
let%expect_test "swap" =
|
|
let array = [| 0; 1; 2; 3 |] in
|
|
print_s [%sexp (array : int array)];
|
|
[%expect {| (0 1 2 3) |}];
|
|
swap array 0 0;
|
|
print_s [%sexp (array : int array)];
|
|
[%expect {| (0 1 2 3) |}];
|
|
swap array 0 3;
|
|
print_s [%sexp (array : int array)];
|
|
[%expect {| (3 1 2 0) |}]
|
|
;;
|
|
|
|
let%expect_test "rev and rev_inplace" =
|
|
let test ordered_list =
|
|
let ordered_array = of_list ordered_list in
|
|
let reversed_array =
|
|
let array = copy ordered_array in
|
|
rev_inplace array;
|
|
array
|
|
in
|
|
require_equal
|
|
[%here]
|
|
(module Int_list)
|
|
(to_list reversed_array)
|
|
(List.rev ordered_list);
|
|
require_equal [%here] (module Int_array) reversed_array (rev ordered_array);
|
|
print_s [%sexp (reversed_array : int array)]
|
|
in
|
|
test [];
|
|
[%expect {| () |}];
|
|
test [ 0 ];
|
|
[%expect {| (0) |}];
|
|
test (List.init 10 ~f:Fn.id);
|
|
[%expect {| (9 8 7 6 5 4 3 2 1 0) |}]
|
|
;;
|
|
|
|
let%expect_test "map_inplace" =
|
|
let test list =
|
|
let f x = x * x in
|
|
let array = of_list list in
|
|
map_inplace array ~f;
|
|
require_equal [%here] (module Int_list) (to_list array) (List.map list ~f);
|
|
print_s [%sexp (array : int array)]
|
|
in
|
|
test [];
|
|
[%expect {| () |}];
|
|
test [ 0 ];
|
|
[%expect {| (0) |}];
|
|
test (List.init 10 ~f:Fn.id);
|
|
[%expect {| (0 1 4 9 16 25 36 49 64 81) |}]
|
|
;;
|
|
|
|
let%expect_test "cartesian_product" =
|
|
require [%here] (is_empty (cartesian_product [||] [||]));
|
|
require [%here] (is_empty (cartesian_product [||] [| 13 |]));
|
|
require [%here] (is_empty (cartesian_product [| 13 |] [||]));
|
|
print_s [%sexp (cartesian_product [| 1; 2; 3 |] [| "a"; "b" |] : (int * string) array)];
|
|
[%expect {|
|
|
((1 a)
|
|
(1 b)
|
|
(2 a)
|
|
(2 b)
|
|
(3 a)
|
|
(3 b))
|
|
|}]
|
|
;;
|
|
|
|
let%expect_test "create_local" =
|
|
let len = 10 in
|
|
let array = create_local ~len (-1) in
|
|
for i = 0 to len - 1 do
|
|
assert (get array i = -1);
|
|
set array i i
|
|
done;
|
|
let array = init len ~f:(fun i -> get array i) in
|
|
print_s (sexp_of_t sexp_of_int array);
|
|
[%expect {| (0 1 2 3 4 5 6 7 8 9) |}]
|
|
;;
|