Paradigmas de Programación Práctica 4 La "pseudo-función" rlist definida a continuación permite crear listas "aleatorias" de enteros de la longitud deseada: let rec rlist r l = if l <= 0 then [] else Random.int r :: rlist r (l-1);; ¿Es recursiva terminal? Si no lo fuera, ¿qué inconveniente podría tener? Si no lo es, haga una versión recursiva terminal de la "misma función". Las siguientes definiciones implementan en ocaml algoritmos de ordenación siguiendo los métodos de selección y de inserción: let rec remove x = function [] -> [] | h::t -> if x = h then t else h::remove x t;; let lmin (h::t) = fold_left min h t;; let rec s_sort = function [] -> [] | l -> let m = lmin l in let resto = remove m l in m::s_sort resto;; let rec insert x = function [] -> [x] | h::t -> if x <= h then x::h::t else h::insert x t;; let rec i_sort = function [] -> [] | h::t -> insert h (i_sort t);; ¿Son ambas implementaciones recursivas terminales? Si no lo son, ¿supone eso en la práctica algún tipo de limitación? Compare empíricamente la rapidez en la aplicación de ambos métodos. Puede utilizar para ello la "pseudo-función" rlist definida anteriormente y la "pseudo-función" crono definida a continuación: let crono f x = let t = Sys.time () in let _ = f x in Sys.time () -. t;; ¿Cuál es más rápida? ¿Cómo crece el tiempo de ejecución con la longitud de la listas? ¿Existen casos especialmente "fáciles" o "difíciles"? Si determinó que las implementaciones anteriores no eran recursivas terminales, realice implementaciones alternativas (t_s_sort y t_i_sort) que sí lo sean. ¿Presentan en la práctica alguna ventaja? ¿Y algún inconveniente? ¿Cuáles son más rápidas? Si la implementación terminal realizada para el método de inserción resultase más lenta que la original, intente mejorarla de modo que no lo sea. Debe tratarse, en todo caso, de una implementación recursiva terminal basada en el método de inserción.