Sys.command "ocaml -version";; let ligne p t i = Array.init p (fun j -> t.(i).(j)) ;; (* t.(i) marche aussi bien ! *) let colonne p t j = Array.init p (fun i -> t.(i).(j)) ;; let tousVrai tab = let res = ref true in for i = 0 to (Array.length tab) - 1 do res := !res && tab.(i) done; !res ;; let tousVrai = Array.fold_left (&&) true;; (* Array.for_all marche aussi bien ! *) let estNp p tab = if tousVrai (Array.map (fun x -> (1 <= x) && (x <= p)) tab) then begin let estLa = Array.make p false in for i = 0 to p - 1 do estLa.(tab.(i) - 1) <- true done; tousVrai estLa end else false ;; let contraintes_lignes p t = tousVrai (Array.init p (fun i -> estNp p (ligne p t i) )) ;; let contraintes_colonnes p t = tousVrai (Array.init p (fun j -> estNp p (colonne p t j) )) ;; let carre_latin p t = (contraintes_lignes p t) && (contraintes_colonnes p t) ;; let transpose_for p tab = let tab2 = Array.make_matrix p p 0 in for i = 0 to p - 1 do for j = 0 to p - 1 do tab2.(i).(j) <- tab.(j).(i); done; done; tab2 ;; transpose_for 2 [| [|1; 2|]; [|3; 4|] |];; let transpose p tab = Array.init p (fun i -> (Array.init p (fun j -> tab.(j).(i))));; transpose 2 [| [|1; 2|]; [|3; 4|] |];; let carre_latin2 p t = (contraintes_lignes p t) && (contraintes_lignes p (transpose p t)) ;; let p1 = 3;; let t1 = [| [| 1; 2; 7; |]; [| 3; 4; 9; |]; [| 5; 8; 6; |]; |];; carre_latin p1 t1;; let p2 = 3;; let t2 = [| [| 1; 2; 3 |]; [| 2; 3; 1 |]; [| 3; 1; 2 |]; |];; carre_latin p2 t2;; carre_latin2 p2 t2;; let p3 = 9 ;; let t3 = [| [| 1; 2; 7; 4; 6; 3; 9; 8; 5 |]; [| 3; 4; 9; 8; 7; 5; 2; 6; 1 |]; [| 5; 8; 6; 2; 9; 1; 4; 3; 7 |]; [| 7; 6; 5; 9; 4; 2; 3; 1; 8 |]; [| 8; 3; 4; 7; 1; 6; 5; 2; 9 |]; [| 9; 1; 2; 5; 3; 8; 7; 4; 6 |]; [| 2; 7; 8; 6; 5; 4; 1; 9; 3 |]; [| 4; 5; 3; 1; 8; 9; 6; 7; 2 |]; [| 6; 9; 1; 3; 2; 7; 8; 5; 4 |]; |]; carre_latin p3 t3;; carre_latin2 p3 t3;; let p4 = 9 ;; let t4 = [| [| 1; 2; 7; 4; 6; 3; 9; 8; 5 |]; [| 3; 4; 9; 8; 7; 5; 2; 6; 1 |]; [| 5; 8; 6; 2; 9; 1; 4; 3; 7 |]; [| 7; 6; 5; 9; 4; 2; 3; 1; 8 |]; [| 8; 2; 4; 7; 1; 6; 5; 2; 9 |]; (* Ligne non valable, 2 est là deux fois !*) [| 9; 1; 2; 5; 3; 8; 7; 4; 6 |]; [| 2; 7; 8; 6; 5; 4; 1; 9; 3 |]; [| 4; 5; 3; 1; 8; 9; 6; 7; 2 |]; [| 6; 9; 1; 3; 2; 7; 8; 5; 4 |]; |]; carre_latin p4 t4;; carre_latin2 p4 t4;; let racine_carree i = int_of_float (sqrt (float_of_int i));; let petit_carre p n t i j = Array.init p (fun k -> t.(n*i + (k / n)).(n*j + (k mod n)) ) ;; let n3 = racine_carree p3;; petit_carre p3 n3 t3 0 0;; petit_carre p3 n3 t3 0 1;; petit_carre p3 n3 t3 0 2;; petit_carre p3 n3 t3 1 0;; petit_carre p3 n3 t3 1 1;; petit_carre p3 n3 t3 1 2;; petit_carre p3 n3 t3 2 0;; petit_carre p3 n3 t3 2 1;; petit_carre p3 n3 t3 2 2;; let petits_carres_sont_latins p t = let n = racine_carree p in (* Par flemme, on créé le tableau entier, qu'on vérifie après *) let contraintes_petits_carres = Array.init p (fun i -> estNp p (petit_carre p n t (i / n) (i mod n) ) ) in (* Mais on peut mieux faire, avec une boucle while par exemple, on sort dès qu'une contrainte est fausse *) tousVrai contraintes_petits_carres ;; petits_carres_sont_latins p3 t3;; petits_carres_sont_latins p4 t4;;