Skip to content

Commit

Permalink
Add Ex 01-27
Browse files Browse the repository at this point in the history
  • Loading branch information
trolleyman committed Nov 19, 2015
1 parent 0ba7b68 commit d9cb8e9
Show file tree
Hide file tree
Showing 27 changed files with 526 additions and 0 deletions.
7 changes: 7 additions & 0 deletions 01.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
let rec last xs = match xs with
| [] -> None
| x :: [] -> Some (x)
| _ :: xs -> last xs;;

last ['a'; 'b'; 'c'];;
last [];;
9 changes: 9 additions & 0 deletions 02.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let rec last_two xs = match xs with
| [] -> None
| [_] -> None
| [x; y] -> Some (x, y)
| _ :: xs -> last_two xs;;

last_two ['a'];;
last_two ['a';'b'];;
last_two ['a';'b';'c'];;
16 changes: 16 additions & 0 deletions 03.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
let rec at n xs = match xs with
| [] -> None
| x :: xs -> if n < 0 then None else if n == 0 then Some x else at (n-1) xs;;
val at : int -> 'a list -> 'a option = <fun>
at 2 ['a'];;
at 1 ['a'];;
at 0 ['a'];;
at (-1) ['a'];;
at 2 ['a', 'b', 'c'];;

# Tail-recursive version
let length list =
let rec aux n = function
| [] -> n
| _::t -> a
in aux 0 list;;
7 changes: 7 additions & 0 deletions 04.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
let rec len xs = match xs with
| [] -> 0
| _ :: xs -> 1 + len xs;;

len [0;1;2];;
len [];;
len [0;1;2;3;4;5;6;7;8;9];;
9 changes: 9 additions & 0 deletions 05.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(* Reverse a list. *)

let rec rev ls = match ls with
| [] -> []
| x :: xs -> (rev xs) @ [x];;

rev [0;1;2];;
rev [0;1;2;3;4;5];;
rev [];;
11 changes: 11 additions & 0 deletions 06.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
(* Find out whether a list is a palindrome. *)

let is_palindrome xs =
List.rev xs = xs;;

is_palindrome [0;1;0];;
is_palindrome [0;1;1;0];;
is_palindrome [0];;
is_palindrome [];;
is_palindrome [0;1];;
is_palindrome [0;4;1;4];;
14 changes: 14 additions & 0 deletions 07.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
type 'a node =
| One of 'a
| Many of 'a node list;;

let rec flatten_node nd = match nd with
| One x -> [x]
| Many xs -> flatten_nodes xs
and flatten_nodes xs = match xs with
| [] -> []
| x :: xs -> (flatten_node x) @ (flatten_nodes xs);;

let flatten = flatten_nodes;

flatten [ One "a" ; Many [ One "b" ; Many [ One "c" ; One "d" ] ; One "e" ] ];;
9 changes: 9 additions & 0 deletions 08.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
(* # compress ["a";"a";"a";"a";"b";"c";"c";"a";"a";"d";"e";"e";"e";"e"];;
: string list = ["a"; "b"; "c"; "a"; "d"; "e"] *)

let rec compress xs = match xs with
| [] -> []
| x :: y :: xs -> if x = y then compress (x :: xs) else x :: (compress (y :: xs))
| x :: [] -> x :: [];;

compress ["a";"a";"a";"a";"b";"c";"c";"a";"a";"d";"e";"e";"e";"e"];;
18 changes: 18 additions & 0 deletions 09.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
(* # pack ["a";"a";"a";"a";"b";"c";"c";"a";"a";"d";"d";"e";"e";"e";"e"];;
- : string list list =
[["a"; "a"; "a"; "a"]; ["b"]; ["c"; "c"]; ["a"; "a"]; ["d"; "d"];
["e"; "e"; "e"; "e"]] *)

let rec pack ls =
let rec aux packed acc ls = match ls with
| [] -> packed
| x :: [] -> packed @ [x::acc]
| x :: y :: xs ->
if x = y then aux packed (x::acc) (y::xs)
else aux (packed @ [x::acc]) [] (y::xs)
in aux [] [] ls;;

pack ["a";"a";"a";"a";"b";"c";"c";"a";"a";"d";"d";"e";"e";"e";"e"];;
pack [];;
pack ['a';'a';'b';'b';'b';'a';'c';'c'];;
pack ['a'];;
20 changes: 20 additions & 0 deletions 10.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
(* Run-length encoding of a list. (easy) *)
(*
# encode ["a";"a";"a";"a";"b";"c";"c";"a";"a";"d";"e";"e";"e";"e"];;
- : (int * string) list =
[(4, "a"); (1, "b"); (2, "c"); (2, "a"); (1, "d"); (4, "e")]
*)


let rec encode xs = match xs with
| [] -> []
| x :: xs ->
let rec aux acc n c xs = match xs with
| [] -> acc @ [(n, c)]
| x :: xs ->
if x = c then aux acc (n+1) c xs
else aux (acc @ [(n, c)]) 1 x xs
in aux [] 1 x xs;;

encode ["a";"a";"a";"a";"b";"c";"c";"a";"a";"d";"e";"e";"e";"e"];;
encode [];;
23 changes: 23 additions & 0 deletions 11.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
(* Modified run-length encoding. (easy) *)

(* Modify the result of the previous problem in such a way that if an element has no duplicates it is simply copied into the result list. Only elements with duplicates are transferred as (N E) lists.
Since OCaml lists are homogeneous, one needs to define a type to hold both single elements and sub-lists. *)

type 'a rle =
| One of 'a
| Many of int * 'a

let rec encode xs = match xs with
| [] -> []
| x :: xs ->
let rec aux acc n c xs = match xs with
| [] -> acc @ [Many (n, c)]
| x :: xs ->
if x = c then aux acc (n+1) c xs
else if n = 1 then aux (acc @ [One c]) 1 x xs
else aux (acc @ [Many (n, c)]) 1 x xs
in aux [] 1 x xs;;

encode ["a";"a";"a";"a";"b";"c";"c";"a";"a";"d";"e";"e";"e";"e"];;
encode [];;
24 changes: 24 additions & 0 deletions 12.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
(* Decode a run-length encoded list. (medium)
Given a run-length code list generated as specified in the previous problem, construct its uncompressed version.*)

type 'a rle =
| One of 'a
| Many of int * 'a

let decode xs =
let rec rep n x = match n with
| 0 -> []
| 1 -> [x]
| _ -> x :: rep (n-1) x
in let rec aux acc = match acc with
| [] -> []
| x :: xs -> match x with
| One c -> c :: (aux xs)
| Many (n, c) -> (rep n c) @ (aux xs)
in aux xs;;

decode [Many (4, 'a'); One 'b'; Many (12, 'e'); One 'f'];;
decode [One '2'];;
decode [Many (3, '3')];;
decode [];;
3 changes: 3 additions & 0 deletions 13.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
(* Run-length encoding of a list (direct solution). (medium) *)

(* Seems to be the same as 11.ml ... *)
14 changes: 14 additions & 0 deletions 14.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
(* Duplicate the elements of a list. (easy) *)

(*
# duplicate ["a";"b";"c";"c";"d"];;
- : string list = ["a"; "a"; "b"; "b"; "c"; "c"; "c"; "c"; "d"; "d"]
*)

let rec duplicate = function
| [] -> []
| x :: xs -> x :: x :: duplicate xs;;

duplicate ['a'];;
duplicate ['a'; 'b'; 'c'];;
duplicate ["a";"b";"c";"c";"d"];;
18 changes: 18 additions & 0 deletions 15.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
(* Replicate the elements of a list a given number of times. (medium) *)

(*
# replicate ["a";"b";"c"] 3;;
- : string list = ["a"; "a"; "a"; "b"; "b"; "b"; "c"; "c"; "c"]
*)

let rec replicate xs n =
let rec rep n x =
if n < 0 then failwith "rep"
else if n = 0 then []
else if n = 1 then x :: []
else x :: rep (n-1) x
in match xs with
| [] -> []
| x :: xs -> (rep n x) @ (replicate xs n);;

replicate ["a";"b";"c"] 3;;
12 changes: 12 additions & 0 deletions 16.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
(* Drop every N'th element from a list. (medium) *)

let rec drop xs n =
let rec aux acc i = match acc with
| [] -> []
| x :: xs ->
if i = 1 then aux xs n
else x :: aux xs (i-1)
in aux xs n;;

drop ["a";"b";"c";"d";"e";"f";"g";"h";"i";"j"] 3;;
drop [0;1;2;3;4;5;6;7;8;9] 2;;
25 changes: 25 additions & 0 deletions 17.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
(* Split a list into two parts; the length of the first part is given. (easy) *)
(*
# split ["a";"b";"c";"d";"e";"f";"g";"h";"i";"j"] 3;;
- : string list * string list =
(["a"; "b"; "c"], ["d"; "e"; "f"; "g"; "h"; "i"; "j"])
# split ["a";"b";"c";"d"] 5;;
- : string list * string list = (["a"; "b"; "c"; "d"], [])
*)

let split xs n =
let rec aux acc proc n = match proc with
| [] -> (acc, [])
| x :: xs ->
if n = 1 then (x :: acc, xs)
else aux (x :: acc) xs (n-1)
in let (l1, l2) = aux [] xs n
in (List.rev l1, l2);;

split [0;1;2;3;4;5] 3;;
split [0;1;2;3;4;5] 5;;
split [0;1;2;3;4;5] 6;;
split [0;1;2;3;4;5] 7;;

split ["a";"b";"c";"d";"e";"f";"g";"h";"i";"j"] 3;;
split ["a";"b";"c";"d"] 5;;
22 changes: 22 additions & 0 deletions 18.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
(* Extract a slice from a list. (medium) *)
(* Given two indices, i and k, the slice is the list containing the elements between the i'th and k'th element of the original list (both limits included). Start counting the elements with 0 (this is the way the List module numbers elements). *)

(*
# slice ["a";"b";"c";"d";"e";"f";"g";"h";"i";"j"] 2 6;;
- : string list = ["c"; "d"; "e"; "f"; "g"]
*)

let slice xs i k =
let rec aux acc proc i k = match proc with
| [] -> if not (i = 0) && not (k = 0) then failwith "slice" else acc
| x :: xs ->
if i <= 0 && k > 0 then aux (x::acc) xs (i-1) (k-1)
else if k = 0 then (x::acc)
else (*if i > 0 then*) aux acc xs (i-1) (k-1)
in List.rev (aux [] xs i k);;

slice [0;1;2] 0 1;;
slice [0;1;2] 0 2;;
slice [0;1;2;3;4;5;6;7;8;9] 2 6;;
slice ["a";"b";"c";"d";"e";"f";"g";"h";"i";"j"] 2 6;;
slice ["a";"b";"c";"d";"e";"f";"g";"h";"i";"j"] 1 1;;
28 changes: 28 additions & 0 deletions 19.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
(* Rotate a list N places to the left. (medium) *)
(*
# rotate ["a"; "b"; "c"; "d"; "e"; "f"; "g"; "h"] 3;;
- : string list = ["d"; "e"; "f"; "g"; "h"; "a"; "b"; "c"]
# rotate ["a"; "b"; "c"; "d"; "e"; "f"; "g"; "h"] (-2);;
- : string list = ["g"; "h"; "a"; "b"; "c"; "d"; "e"; "f"]
*)

let rotate xs n =
let split xs n =
let rec aux acc proc n = match proc with
| [] -> (acc, [])
| x :: xs ->
if n = 1 then (x :: acc, xs)
else aux (x :: acc) xs (n-1) in
let (l1, l2) = aux [] xs n in
(List.rev l1, l2) in
if n = 0 then xs
else if n < 0 then let (l1, l2) = split xs ((List.length xs) + n) in l2 @ l1
else (*n > 0*) let (l1, l2) = split xs n in l2 @ l1;;


rotate ["a"; "b"; "c"; "d"; "e"; "f"; "g"; "h"] (-2);;
rotate ["a"; "b"; "c"; "d"; "e"; "f"; "g"; "h"] 3;;
rotate [] 0;;
rotate [0;1;2] 0;;
rotate [0;1;2] 1;;
rotate [0;1;2] 2;;
17 changes: 17 additions & 0 deletions 20.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
(* Remove the K'th element from a list. (easy) *)
(*
# remove_at 1 ["a";"b";"c";"d"];;
- : string list = ["a"; "c"; "d"]
*)

let remove_at n xs =
let rec aux acc n = function
| [] -> failwith "remove_at"
| x :: xs ->
if n = 0 then (List.rev acc) @ xs
else aux (x :: acc) (n-1) xs
in aux [] n xs;;

remove_at 1 ["a";"b";"c";"d"];;
remove_at 4 ["a";"b";"c";"d"];;
remove_at (-1) ["a";"b";"c";"d"];;
24 changes: 24 additions & 0 deletions 21.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
(* Insert an element at a given position into a list. (easy) *)
(* Start counting list elements with 0. If the position is larger or equal to the length of the list, insert the element at the end.
(The behavior is unspecified if the position is negative.) *)

(*
# insert_at "alfa" 1 ["a";"b";"c";"d"];;
- : string list = ["a"; "alfa"; "b"; "c"; "d"]
# insert_at "alfa" 3 ["a";"b";"c";"d"];;
- : string list = ["a"; "b"; "c"; "alfa"; "d"]
# insert_at "alfa" 4 ["a";"b";"c";"d"];;
- : string list = ["a"; "b"; "c"; "d"; "alfa"]
*)

let insert_at x i xs =
let rec aux acc x i = function
| [] -> (List.rev (x :: acc))
| h :: t ->
if i = 0 then (List.rev (h :: x :: acc)) @ t
else aux (h :: acc) x (i-1) t
in aux [] x i xs;;

insert_at "alfa" 1 ["a";"b";"c";"d"];;
insert_at "alfa" 3 ["a";"b";"c";"d"];;
insert_at "alfa" 4 ["a";"b";"c";"d"];;
19 changes: 19 additions & 0 deletions 22.ml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
(* Create a list containing all integers within a given range. (easy)
If first argument is smaller than second, produce a list in decreasing order. *)

(*
# range 4 9;;
- : int list = [4; 5; 6; 7; 8; 9]
# range 9 4;;
- : int list = [9; 8; 7; 6; 5; 4]
*)

let range a b =
let rec aux a b step =
if a = b then [a]
else a :: aux (a+step) b step
in if a < b then aux a b 1 else aux a b (-1);;

range 9 4;;
range 4 9;;
Loading

0 comments on commit d9cb8e9

Please sign in to comment.