(**************************************************************************)
(*                                                                        *)
(*  Ocamlviz --- real-time profiling tools for Objective Caml             *)
(*  Copyright (C) by INRIA - CNRS - Universite Paris Sud                  *)
(*  Authors: Julien Robert                                                *)
(*           Guillaume Von Tokarski                                       *)
(*           Sylvain Conchon                                              *)
(*           Jean-Christophe Filliatre                                    *)
(*           Fabrice Le Fessant                                           *)
(*  GNU Library General Public License version 2                          *)
(*  See file LICENSE for details                                          *)
(*                                                                        *)
(**************************************************************************)

(* quicksort on lists *)
open Ocamlviz

let p1 = Point.create "qsort"
let p2 = Point.create "part"
let t1 = Time.create "time1"

let quicksort s =
  (* [qsort s acc] sorts [s] and appends it in front of [acc] *)
  let rec qsort s acc = 
    Point.observe p1;
    match s with
      | [] -> acc
      | [x] -> x :: acc
      | x :: xs ->
	  let rec part l r s =
	    Point.observe p2;
	    match s with
	      | [] -> qsort l (x :: qsort r acc)
	      | y :: ys when y <= x -> part (y :: l) r ys
	      | y :: ys -> part l (y :: r) ys
	  in
	  part [] [] xs
  in
  Time.start t1;
  let res = qsort s [] in
  Time.stop t1;
  res


(* test function *)

let rec sorted = function 
  | [] | [_] -> true
  | x :: (y :: _ as s) -> x <= y && sorted s

let random_list n = 
  let rec make acc = function
    | 0 -> acc
    | n -> make (Random.int n :: acc) (n-1)
  in
  make [] n

let () =
  Ocamlviz.init ();
  let l = random_list 10_000_000 in
  assert (sorted (quicksort l))



(*
Local Variables: 
compile-command: "unset LANG; make -C .. test-quicksortl"
End: 
*)
