Commit c81e90da authored by Taddeus Kroes's avatar Taddeus Kroes

Merge branch 'master' of ssh://vo20.nl/git/uva

parents feedb9d1 cfc7871b
...@@ -4,10 +4,9 @@ open List ...@@ -4,10 +4,9 @@ open List
let rec nth l n = let rec nth l n =
(* Walk through the list recursively, subtracting 1 off n each time and (* Walk through the list recursively, subtracting 1 off n each time and
* matching it with 0 to check of the nth element has been reached yet *) * matching it with 0 to check of the nth element has been reached yet *)
match n with match l with
| 0 -> hd l | [] -> raise (Failure "list index out of bounds")
| i when i > 0 && i < (length l) -> nth (tl l) (i - 1) | h::t -> if n = 0 then h else nth t (n - 1)
| _ -> raise (Failure "list index out of bounds")
;; ;;
(* 2 *) (* 2 *)
...@@ -43,7 +42,7 @@ let rec reduce f z l = ...@@ -43,7 +42,7 @@ let rec reduce f z l =
(* 6 *) (* 6 *)
let rec isSublist l s = let rec isSublist l s =
(* Check if l starts with s, otherwise chech the tail recursively *) (* Check if l starts with s, otherwise check the tail recursively *)
let rec startsWith l s = let rec startsWith l s =
(length s) <= (length l) && match s with (length s) <= (length l) && match s with
| [] -> true | [] -> true
...@@ -56,7 +55,7 @@ let rec isSublist l s = ...@@ -56,7 +55,7 @@ let rec isSublist l s =
(* 7 *) (* 7 *)
let rec lookup l key = let rec lookup l key =
(* Math key to the first tuple and return the value-side of the tuple if (* Match key to the first tuple and return the value-side of the tuple if
* matched. Otherwise, lookup in the rest of the tuples *) * matched. Otherwise, lookup in the rest of the tuples *)
match l with match l with
| [] -> raise (Failure "lookup") | [] -> raise (Failure "lookup")
...@@ -67,7 +66,7 @@ let rec lookup l key = ...@@ -67,7 +66,7 @@ let rec lookup l key =
let rec coin_permutation l n = let rec coin_permutation l n =
(* Reduce the list using the fact that the the total number of coin (* Reduce the list using the fact that the the total number of coin
* permutations is equal to the number of permutations given a single coin, * permutations is equal to the number of permutations given a single coin,
* added to the number of permutations without that coin *) * combined with the number of permutations without that coin *)
match l with match l with
| [] -> 0 | [] -> 0
| h::t -> (if h > n then 0 else 1 + (coin_permutation t (n - h))) | h::t -> (if h > n then 0 else 1 + (coin_permutation t (n - h)))
......
(* Alias for Printf.printf, because it saves typing characters. *)
let print = Printf.printf;;
(* 1: nth yields the N-th element of the list L, counting from zero. *)
let rec nth l n = match l with
| [] -> raise (Failure "Index out of bounds")
| h::t -> if n == 0 then h else nth t (n - 1)
;;
print "7.1: %b\n" ((=) (nth [1;2;3] 2) 3 );;
open List
(* 2: Given a list of non-empty lists L, head yields the list of first elements
* of the sublists. *)
let heads l = map hd l;;
print "7.2: %b\n" ((=) (heads [[1;2;3];[4;5;6]]) [1;4]);;
(* 3: zip L M that given a pair of lists yields the list of pairs of elements
* from corresponding list positions. If the length of one argument list
* exceeds * the length of the other, surplus elements are to be ignored. *)
let rec zip ?(s=[]) l1 l2 = match (l1, l2) with
| [], _ -> s (* If the first list is empty, return list. *)
| _, [] -> s (* If the second list is empty, return list. *)
(* Take the head and tail of both lists. Then call zip with the list,
* and append a tuple of the two heads to it. The last two arguments
* of zip are the tails of both lists. *)
| h1::t1, h2::t2 -> zip ~s:(s @ [h1, h2]) t1 t2
;;
print "7.3: %b\n" ((=) (zip [1;2;3] [true;false]) [(1,true);(2,false)]);;
(* 4: map f l that given a function F applies it to every element of list L
* returning a list of the results. *)
let rec map f l = match l with
| [] -> []
| h::t -> f h::map f t
;;
let inc n = 1 + n in
print "7.4: %b\n" ((=) (map inc [1;2;3;4;5]) [2;3;4;5;6]);;
(* 5: reduce f z l that given a function f, a begin element z and a list l
* applies f to z and the first element of l, then applies f to the result of
* this application and the second element of l, etc. Which means that reduce f
* z [a;b;c] becomes f (f (f z a) b) c. *)
let rec reduce f z l = match l with
| [] -> z
| h::t -> reduce f (f z h) t
;;
print "7.5: %b\n" ((=) (reduce (+) 0 [1;2;3;4;5]) 15);;
(* 6: isSublist l s that checks whether or not the argument list s is a sublist
* of the argument list l. *)
let isSublist l s =
(* Store the full search term *)
let full = s in
let rec sublistMatches l s = match (l, s) with
| _, [] -> true
| [], _ -> false
| h1::t1, h2::t2 ->
(* if the head of s matches the head of l'. *)
h1 = h2
(* and the next head of s matches the next head of l. *)
&& ( t1 = [] && t2 = [] || hd t1 = hd t2 )
(* recursively match the tails of s and l. *)
&& sublistMatches t1 t2
(* otherwise, continue with the tail of l and reset s. *)
|| sublistMatches t1 full
in sublistMatches l s
;;
print "7.6.1: %b\n" (isSublist [1;2;3;4] [3;4]);;
print "7.6.2: %b (%s)\n" (isSublist [1;2;3;4] [2;4]) "expected failure";;
print "7.6.3: %b (%s)\n" (isSublist [1;2;3;3;4] [2;3;4]) "expected failure";;
print "7.6.4: %b\n" (isSublist [1;2;3;3;4] [3;3;4]);;
print "7.6.5: %b\n" (isSublist [] []);;
(* 7. lookup l key that given a list l of (key, value) tuples and a key returns
* the value associated with that key. *)
let rec lookup l key = match l with
| [] -> raise (Failure "Key not found")
| h::t -> let k,v = h in if key = k then v else lookup t key
;;
print "7.7: %b\n" ((=) (lookup [(1,"foo");(2,"bar");(3,"baz")] 2) "bar");;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment