Sys.command "ocaml -version";;
The OCaml toplevel, version 4.04.2
- : int = 0
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)) ;;
val ligne : int -> 'a array array -> int -> 'a array = <fun>
val colonne : int -> 'a array array -> int -> 'a array = <fun>
let tousVrai = Array.for_all (fun x -> x);;
val tousVrai : bool array -> bool = <fun>
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
;;
val estNp : int -> int array -> bool = <fun>
let sum_array = Array.fold_left (+) 0;;
val sum_array : int array -> int = <fun>
let estNp_compte p tab =
if tousVrai (Array.map (fun x -> (1 <= x) && (x <= p)) tab) then begin
let estLa = Array.make p 0 in
for i = 0 to p - 1 do
estLa.(tab.(i) - 1) <- 1
done;
sum_array estLa
end
else
0
;;
val estNp_compte : int -> int array -> int = <fun>
let racine_carree i = int_of_float (sqrt (float_of_int i));;
val racine_carree : int -> int = <fun>
let contraintes_lignes p t =
tousVrai (Array.init p (fun i ->
estNp p (ligne p t i)
))
;;
val contraintes_lignes : int -> int array array -> bool = <fun>
let contraintes_lignes_compte p t =
sum_array (Array.init p (fun i ->
estNp_compte p (ligne p t i)
))
;;
val contraintes_lignes_compte : int -> int array array -> int = <fun>
let contraintes_colonnes p t =
tousVrai (Array.init p (fun j ->
estNp p (colonne p t j)
))
;;
val contraintes_colonnes : int -> int array array -> bool = <fun>
let contraintes_colonnes_compte p t =
sum_array (Array.init p (fun j ->
estNp_compte p (colonne p t j)
))
;;
val contraintes_colonnes_compte : int -> int array array -> int = <fun>
let carre_latin p t =
(contraintes_lignes p t) && (contraintes_colonnes p t)
;;
val carre_latin : int -> int array array -> bool = <fun>
let carre_latin_compte p t =
(contraintes_lignes_compte p t) + (contraintes_colonnes_compte p t)
;;
val carre_latin_compte : int -> int array array -> int = <fun>
let petit_carre p n t i j =
Array.init p (fun k ->
t.(n*i + (k / n)).(n*j + (k mod n))
)
;;
val petit_carre : int -> int -> 'a array array -> int -> int -> 'a array = <fun>
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
;;
val petits_carres_sont_latins : int -> int array array -> bool = <fun>
let petits_carres_sont_latins_compte p t =
let n = racine_carree p in
let contraintes_petits_carres =
Array.init p (fun i ->
estNp_compte p (petit_carre p n t (i / n) (i mod n) )
)
in
sum_array contraintes_petits_carres
;;
val petits_carres_sont_latins_compte : int -> int array array -> int = <fun>
let est_resolu p t =
(carre_latin p t) && (petits_carres_sont_latins p t)
;;
val est_resolu : int -> int array array -> bool = <fun>
let nb_contraintes_resolues p t =
(carre_latin_compte p t) + (petits_carres_sont_latins_compte p t)
;;
let score = nb_contraintes_resolues;;
val nb_contraintes_resolues : int -> int array array -> int = <fun>
val score : int -> int array array -> int = <fun>
Avec $p = n^2 = 9$, on reprend l'exemple du texte :
Ça va être long un peu à écrire, mais au moins on vérifiera notre fonction sur un vrai exemple.
let p = 9 ;;
let t = [|
[| 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 |];
|];
val p : int = 9
val t : int array array = [|[|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|]|]
let score_max = 3 * 9 * 9;;
val score_max : int = 243
score p t;;
- : int = 243
Avec $p = n^2 = 9$, en modifiant seulement une case du tableau $T$ précédent.
let p = 9 ;;
let t = [|
[| 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 |];
|];
val p : int = 9
val t : int array array = [|[|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|]; [|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|]|]
score p t;;
- : int = 240
On voit que 3 contraintes ne sont pas vérifiées.
Nan, je déconne. ... Bien-sûr, évitez les blagues pourries le jour de l'oral ! Mais une bonne blague peut être bien reçue...
let population = 100
and mutes = 45
and effaces = 10;;
let conserves = population - mutes - effaces;;
val population : int = 100 val mutes : int = 45 val effaces : int = 10
val conserves : int = 45
Random.self_init();;
- : unit = ()
Random.int;;
- : int -> int = <fun>
let choix_sans_remise tab k =
let n = Array.length tab in
assert 0 <= k <= n;
let reponse = Array.make k (-1) in
for i = 0 to k-1 do
done;
reponse
;;
File "[63]", line 1, characters 0-13: Error: Unbound value Random.choice 1: Random.choice;;
let copie n t =
Array.init n (fun i -> (Array.copy t.(i)))
;;
val copie : int -> 'a array array -> 'a array array = <fun>
let individu_initial n grille_initiale =
Array.init
;;
let mutation n grille_initiale individu =
XXX
;;
File "[61]", line 2, characters 4-7: Error: Unbound constructor XXX 1: let mutation n grille_initiale individu = 2: XXX 3: ;;
let algorithme_genetique nb1 nb2 nb3 ii m generation =
let n = nb1 + nb2 + nb3 in
let population = List.init (fun i -> ii ()) in
let resolution_genetique_sudoku n grille_initiale =
let ii = fun () -> individu_initial n grille_initiale in
let m = fun individu -> mutation n grille_initiale individu in
Voilà pour une proposition de bonus d'implémentation.
Bien-sûr, ce petit notebook ne se prétend pas être une solution optimale, ni exhaustive.