let lecture_instance ~file =
(*(** file : correspond à l'adresse (relative ou absolue) du fichier que l'on veut lire. *)
(** /!\ CONVENTION : on utilise toujours la réprésentation fichier de Unix : /home/superman/Bureau/puzzle_de_la_mort_qui_tue.instance *)
*)
(** On ouvre le canal. *) |
let canal_entree = open_in file; in
let finlecture = ref false; in
let nb_ligne = ref 0; in
(** On commence à lire, *) |
let m = ref 0 and n = ref 0 and c = ref 0 in
let p = ref [] in
let rec auxi mon_ce =
let res_input = (try (((input_line mon_ce))) with End_of_file -> (finlecture := true; "")); in
(* print_string ("Numéro de ligne "^(string_of_int !nb_ligne)^": \tLigne importee :\n\t["^res_input^"]\n");*) (* DEBUG *)
(** Si on a pas finit de lire, on analyse : *) |
if (not !finlecture)
then
(
(** 1' cas : c'est la première ligne lue; *) |
if (!nb_ligne = 0) then (
(** On a importé une ligne qui correspond d'abord au header : m n c, *) |
let liste_header = List.map int_of_string (decoupe res_input); in (* une liste de strings transformées en entiers donc *)
if (List.length liste_header) <> 3 then raise Error_Parse_instance;
(** En cas de non cohérence, l'exception est lancée 'Error_Parse_instance'. *) |
m := List.nth liste_header 0;
n := List.nth liste_header 1;
c := List.nth liste_header 2;
(** On a réussi a lire et convertir la ligne. *) |
);
(** 2' cas : ce n'est pas la première ligne lue; *) |
if (!nb_ligne <> 0) then (
(** On a importé une ligne qui correspond à une piece, *) |
let liste_couleur_piece = List.map int_of_string (decoupe res_input); in (* une liste de strings transformées en entiers donc *)
if (List.length liste_couleur_piece) <> 4 then raise Error_Parse_instance;
(** En cas de non cohérence, l'exception est lancée 'Error_Parse_instance'. *) |
p := !p @ [piece_of_listcouleur liste_couleur_piece];
(** On a réussi a lire et convertir la ligne. *) |
);
incr nb_ligne;
(auxi mon_ce);
)
else close_in canal_entree;
(** Sinon, on clos le canal d'entrée, et on passe a la suite. *) |
in
auxi canal_entree;
(** On vérifie le bon nombre de lignes, les autres spécificités des fichiers .instance ont déja été vérifiée. *) |
if (!nb_ligne <> ((!n * !m) + 1)) then raise Error_Parse_instance;
(** On conclut en fermant le canal d'entréé et en construisant l'instance lue. *) |
close_in canal_entree;
{ ci = !c; ni = !n; mi = !m; pi = !p }