(* Cette fonction permet de construire des matrices à partir du constructeur d'un type et non pas d'un objet de ce type *) let make_matrix_bis a b t= let m = make_vect a (make_vect b (t ())) in for i = 0 to a-1 do m.(i) <- make_vect b (t ()); for j = 0 to b-1 do m.(i).(j) <- t () done done; m;; let n = 3;; let nn = n*n;; type possib_c = {mutable nb_possib : int; possib : int vect};; type case_c = {mutable valeur : int; pos : possib_c};; type sudok_c = {jeu : case_c vect vect;mutable nb_void : int ; ligne : case_c vect vect ; colonne : case_c vect vect ; carre : case_c vect vect};; let r_MODIF=2 and r_NO_MODIF=1 and r_ERROR=0;; let make_possib () = {nb_possib=nn;possib=make_vect nn 1};; let make_case () = {valeur=(-1);pos=make_possib ()};; let make_sudok () = {jeu=make_matrix_bis nn nn make_case;nb_void=nn*nn;ligne=make_matrix_bis nn nn make_case;colonne=make_matrix_bis nn nn make_case;carre=make_matrix_bis nn nn make_case};; (* indique si la case (i,j) est libre *) let is_free c= c.valeur=(-1);; let is_free_cas s i j = is_free s.jeu.(i).(j);; let is_free_lig s i j = is_free s.ligne.(i).(j);; let is_free_col s i j = is_free s.colonne.(i).(j);; let is_free_car s i j = is_free s.carre.(i).(j);; (* renvoie une valeur que l'on peut mettre sur la case (i,j) *) let get_pos p = let rec g_p l = if l=nn then -1 else if p.(l)=1 then l else g_p (l+1) in g_p 0;; let get_pos_cas s i j = (get_pos s.jeu.(i).(j).pos.possib) + 1;; let get_pos_lig s i j = (get_pos s.ligne.(i).(j).pos.possib);; let get_pos_col s i j = (get_pos s.colonne.(i).(j).pos.possib);; let get_pos_car s i j = (get_pos s.carre.(i).(j).pos.possib);; (* rend impossible l'utilisation de la valeur t sur la case (i,j) ainsi que sur les colonne, ligne et carré auxquelles elle appartient. *) let remove p t = let r = p.possib.(t) in begin if r=1 then p.nb_possib <- p.nb_possib-1; p.possib.(t) <- r-1 end;; let remove_cas s i j t = remove s.jeu.(i).(j).pos (t-1);; let remove_lig s i j t = remove s.ligne.(i).(t-1).pos j;; let remove_col s i j t = remove s.colonne.(j).(t-1).pos i;; let remove_car s i j t = remove s.carre.(i).(t-1).pos j;; let remove_all s i j t = remove_cas s i j t; remove_lig s i j t; remove_col s i j t; remove_car s ((i/n)*n+(j/n)) ((i mod n)*n+(j mod n)) t;; (* assigne la valeur t à la case (i,j) *) let assign s i j t= for m = 0 to nn-1 do remove_all s i m t; remove_all s m j t; remove_all s i j (m+1); remove_all s ((i/n)*n+(m mod n)) ((j/n)*n+(m/n)) t done; s.jeu.(i).(j).valeur <- t; s.ligne.(i).(t-1).valeur <- j; s.colonne.(j).(t-1).valeur <- i; s.carre.((i/n)*n+(j/n)).(t-1).valeur <- ((i mod n)*n+(j mod n)); s.nb_void <- s.nb_void-1;; let print v = if v=2 then print_string "r_MODIF " else if v=1 then print_string "r_NO_MODIF " else print_string "r_ERROR ";; let get_sup s = let rec boucle_i_j i j = if i=nn then (nn+1,0,0) else if j=nn then boucle_i_j (i+1) 0 else let m=s.jeu.(i).(j).pos.nb_possib in if m = 2 then (2,i,j) else if m<2 then boucle_i_j i (j+1) else let (mm,ii,jj)=boucle_i_j i (j+1) in if mm<2 then (m,i,j) else if mm