(* CS 2SC3 / SE 2S03 solutions, episode 2: Pouya is slowly going crazy *) type vector = float * float (* Combinators: >> is pipe, >< is zip, !! is double app, ^^ is min *) let (>>) f g x = g (f x) and (><) f g (x,y :vector) :vector = f x,g y and (!!) f v = f v v and (^^) a b f = if f a < f b then a else b let vec_zero:vector = 0.,0. let vec_neg = (~-.) >< (~-.) and vec_add (x,y:vector) = (+.)x >< (+.)y let vec_mag = !! (><) !! ( *.) >> (fun (a,b) -> a+.b) >> sqrt let vec_dist v = vec_neg >> vec_add v >> vec_mag let remus_iter f n s = if n < 0 then vec_zero else let m = ref (f 0) in for x = 1 to n do m := ((f x) ^^ !m) (vec_dist s) done; !m let rec remus_rec f n s = match n with x when x < 0 -> vec_zero | 0 -> f 0 | x -> ((f n) ^^ (remus_rec f (x-1) s)) (vec_dist s) let romulus_iter l = remus_iter (List.nth l) ((List.length l)-1) let romulus_rec l = remus_rec (List.nth l) ((List.length l)-1) (* Testing the code. From here on it should be more understandable. I think. *) let vtos (a,b) = "("^string_of_float(a)^","^string_of_float(b)^")" let pvl l = print_endline (String.concat ",\t" (List.map vtos l)) let cases = [(0.,0.);(1.,1.);(-2.,-1.);(1.,-2.);(5.5,-5.5);(-100.,-100.)] let points = [(0.,1.);(1.,0.);(0.,-1.);(-1.,0.);(-10.,1.);(1.,-10.);(10.,-1.);(10.,1.);(55.,55.)];; print_string "\nvec_zero = "; pvl [vec_zero];; print_endline "\nTest cases are:"; pvl cases;; print_endline "\nApplying vec_neg:"; pvl (List.map vec_neg cases);; print_endline "\nApplying vec_mag:"; print_endline (String.concat ",\t" (List.map (vec_mag >> string_of_float) cases));; print_endline "\nTable of vec_add:"; List.iter (fun a -> pvl (List.map (vec_add a) cases)) cases;; print_endline "\nLooking for closest point to each case in the following list of points:"; pvl points;; print_endline "\nUsing romulus_iter"; pvl (List.map (romulus_iter points) cases);; print_endline "\nUsing romulus_rec"; pvl (List.map (romulus_rec points) cases);; print_endline "\nUsing remus_iter"; pvl (List.map (remus_iter (List.nth points) 8) cases);; print_endline "\nUsing remus_rec"; pvl (List.map (remus_rec (List.nth points) 8) cases);;