(* Ouvrir la fenêtre graphique *) let () = Graphics.open_graph " 512x512" (**************************************) (* Déclarations des types de l'énoncé *) (**************************************) type couleur = Blanc Noir type arbre = Feuille of couleur Noeud of arbre * arbre * arbre * arbre type image = couleur array array (**************) (* Question 1 *) (**************) let rec compte_feuilles = function Feuille _ -> 1 Noeud (c1, c2, c3, c4) -> compte_feuilles c1 + compte_feuilles c2 + compte_feuilles c3 + compte_feuilles c4 let a = Noeud (Noeud (Feuille Blanc, Feuille Blanc, Feuille Noir, Feuille Blanc), Feuille Noir, Feuille Noir, Feuille Noir) let () = assert (compte_feuilles a = 7) (**************) (* Question 2 *) (**************) let rec do_dessine i j k = function Feuille Noir -> Graphics.fill_rect i j k k Feuille Blanc -> () Noeud (c1, c2, c3, c4) -> let k2 = k/2 in do_dessine i (j+k2) k2 c1; do_dessine (i+k2) (j+k2) k2 c2; do_dessine i j k2 c3; do_dessine (i+k2) j k2 c4 let dessine_arbre k a = do_dessine 0 0 k a let rec do_vers_arbre img i j k = if k <= 1 then Feuille img.(i).(j) else let k2 = k/2 in let c1 = do_vers_arbre img i (j+k2) k2 and c2 = do_vers_arbre img (i+k2) (j+k2) k2 and c3 = do_vers_arbre img i j k2 and c4 = do_vers_arbre img (i+k2) j k2 in match c1, c2, c3, c4 with Feuille n1, Feuille n2, Feuille n3, Feuille n4 when n1 = n2 && n2 = n3 && n3 = n4 -> c1 _ -> Noeud (c1, c2, c3, c4) let image_vers_arbre k img = do_vers_arbre img 0 0 k (* Test de dessine_arbre *) let rec q2 a = Graphics.clear_graph (); dessine_arbre 512 a; let rec do_rec () = let c = Graphics.read_key () in if c = 'q' then () else do_rec () in do_rec () let () = q2 a (* Test de image_vers_arbre *) let img = [| [| Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Blanc; Blanc; Blanc; Blanc; |]; [| Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Blanc; Blanc; Blanc; Blanc; |]; [| Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Blanc; Blanc; Blanc; Blanc; |]; [| Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir;Blanc; Blanc; Blanc; Blanc; |]; [| Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Blanc; Blanc; Blanc; Blanc; Blanc; Blanc; Blanc; Blanc; |]; [| Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Blanc; Blanc; Blanc; Blanc; Blanc; Blanc; Blanc; Blanc; |]; [| Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Blanc; Blanc; Blanc; Blanc; Blanc; Blanc; Blanc; Blanc; |]; [| Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Blanc; Blanc; Blanc; Blanc; Blanc; Blanc; Blanc; Blanc; |]; [| Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; |]; [| Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; |]; [| Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; |]; [| Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; |]; [| Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; |]; [| Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; |]; [| Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; |]; [| Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; Noir; |]; |] let () = assert (image_vers_arbre (Array.length img) img = a) (**************) (* Question 3 *) (**************) let rec inverse = function Feuille Blanc -> Feuille Noir Feuille Noir -> Feuille Blanc Noeud (c1, c2, c3, c4) -> Noeud (inverse c1, inverse c2, inverse c3, inverse c4) (* 3 -> 4 -> 2 -> 1 *) let rec rotate = function Feuille _ as a -> a Noeud (c1, c2, c3, c4) -> Noeud (rotate c2, rotate c4, rotate c1, rotate c3) (* 1 -> 2 -> 4 -> 3 *) let rec antirotate = function Feuille _ as a -> a Noeud (c1, c2, c3, c4) -> Noeud (antirotate c3, antirotate c1, antirotate c4, antirotate c2) (* Test des rotations *) let rec q3 a = Graphics.clear_graph (); dessine_arbre 512 a; let rec do_rec () = let c = Graphics.read_key () in if c = 'n' then q3 (rotate a) else if c = 'p' then q3 (antirotate a) else if c = 'i' then q3 (inverse a) else if c = 'q' then () else do_rec () in do_rec () let () = q3 a (**************) (* Question 4 *) (**************) let rec fractale n = if n <= 0 then Feuille Noir else let c = fractale (n-1) in let c1 = Noeud (c, c, c, Feuille Blanc) in let c3 = rotate c1 in let c4 = rotate c3 in let c2 = rotate c4 in Noeud (c1, c2, c3, c4) let rec q4 i = dessine_arbre 512 (fractale i); let rec do_rec () = let c = Graphics.read_key () in if c = 'n' && i < 5 then begin Graphics.clear_graph (); q4 (i+1) end else if c = 'p' && i > 0 then begin Graphics.clear_graph (); q4 (i-1) end else if c = 'q' then () else do_rec () in do_rec () let () = q4 0 (**************) (* Question 5 *) (**************) type bit = Zero Un let rec do_arbre_vers_liste a k = match a with Feuille Blanc -> Zero :: Zero :: k Feuille Noir -> Zero :: Un :: k Noeud (a1, a2, a3, a4) -> Un :: do_arbre_vers_liste a1 (do_arbre_vers_liste a2 (do_arbre_vers_liste a3 (do_arbre_vers_liste a4 k))) let arbre_vers_liste a = do_arbre_vers_liste a [] let rec do_parse = function Zero :: Zero :: rem -> Feuille Blanc, rem Zero :: Un :: rem -> Feuille Noir, rem Un :: rem -> let a1, rem = do_parse rem in let a2, rem = do_parse rem in let a3, rem = do_parse rem in let a4, rem = do_parse rem in Noeud (a1, a2, a3, a4), rem _ -> assert false let liste_vers_arbre l = let a,_ = do_parse l in a let a = fractale 4 let () = assert (a = liste_vers_arbre (arbre_vers_liste a)) (* sauvegarde et lecture, octet par octet des listes de bits *) let bit_to_int = function Zero -> 0 Un -> 1 let get_one_bit = function [] -> Zero,[] b :: rem -> b,rem let rec get_n_bits n l = if n <= 0 then 0, l else let b, rem = get_one_bit l in let r, rem = get_n_bits (n-1) rem in 2 * r + (bit_to_int b), rem let rec output_list f = function [] -> () l -> let byte,rem = get_n_bits 8 l in output_char f (Char.chr byte); output_list f rem let ecrire_arbre name a = let f = open_out_bin name in output_list f (arbre_vers_liste a); close_out f let read_byte f = try let c = input_char f in Some (Char.code c) with End_of_file -> None let rec get_n_bits digits n = if digits <= 0 then [] else let b = match n mod 2 with 0 -> Zero 1 -> Un _ -> assert false in b :: get_n_bits (digits-1) (n/2) let rec input_list f = match read_byte f with None -> [] Some n -> get_n_bits 8 n @ input_list f let lire_arbre name = let f = open_in_bin name in let a = liste_vers_arbre (input_list f) in close_in f; a let q5 a = ecrire_arbre "f4.quad" a; let aa = lire_arbre "f4.quad" in assert (a = aa) let () = q5 (fractale 4)
This document was generated using caml2html