IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Caml Discussion :

Demander à l'utilisateur d'entrer une liste d'entiers. (marre des syntax error !)


Sujet :

Caml

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 17
    Points : 7
    Points
    7
    Par défaut Demander à l'utilisateur d'entrer une liste d'entiers. (marre des syntax error !)
    Bonjour,
    j'ai fait le code suivant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    let input = try read_int () with Failure "int_of_string" -> (-1)
    in
    if input = (-1) then print_endline "erreur!"
    else print_endline ("Vous avez entré " ^ (string_of_int input) ^ ".");;
    qui récupère un entier entré par l'utilisateur.

    Ce que j'aimerais faire, c'est demander l'entrée d'une liste d'entiers.
    Par exemple, l'utilisateur entrerait 0 1 5 7 2 et le programme récupèrerait ça dans une liste.
    C'est sûrement possible en récupérant ça dans une string, mais je me dis que vérifier qu'il y a des espaces et que chaque valeur est un entier serait un peu trop fastidieux. Du coup, j'aimerais savoir si il existe des fonctions toutes prêtes qui récupèrent une liste d'entiers, du genre read_list (j'invente).
    Merci d'avance.

  2. #2
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Points : 1 104
    Points
    1 104
    Par défaut
    Non, il n'existe pas de fonction toute faite.

    Voici une fonction qui récupère un entier en ignorant les espaces devant, et sans demander obligatoirement de fin de ligne derrière (donc tu peux lire plusieurs entiers par ligne) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    let my_read_int () = Scanf.scanf " %d" (fun n -> n)
    Tu peux utiliser cette fonction, ou des variantes, pour tes besoins. Si tu connais le nombre d'entiers à lire sur la ligne, il suffit d'appeler la fonction autant de fois que nécessaire. Si tu veux lire tous les entiers sur la ligne, c'est un peu plus compliqué :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    (* prend une chaîne de nombres séparés par des blancs, et renvoie la
       liste d'entiers correspondante *)
    let int_list_of_string line =
      (* construire une entrée Scanf à partir de la chaîne *)
      let input = Scanf.Scanning.from_string line in
      (* fonction récursive de lecture de la chaîne *)
      let rec read () =
        if Scanf.Scanning.end_of_input input
        then [] (* s'il n'y a plus rien à lire *)
        else (* sinon on lit le début, et on y ajoute la suite *)
          (* comme il y a des espaces autour du %d, on ignore les blancs
             avant et après : "1 2 3", "1 2 3 " et " 1 2 3" vont marcher *)
          Scanf.bscanf input " %d " (fun n -> n :: read ()) in
      read ()
     
    (* renvoie la liste de nombres de l'entrée standard *)
    let read_int_list () =
      int_list_of_string (read_line ())
    Le code est commenté à mort et tente de privilégier la lisibilité. La fonction "read()" n'est pas tail-rec, ce qui pourrait poser problème pour des chaînes énormes, mais n'est pas un soucis en pratique et permet d'éviter de réfléchir aux accumulateurs et compagnie. La rendre tail-rec est un exercice facile (quand on connait List.rev).

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    Merci, ça va bien m'aider.

    Edit : le code fonctionne bien, mais j'ai essayé de l'adapter pour que le Scanf.bscanf input " %d ", s'il rencontre une erreur, ne mette pas fin au programme mais demande une nouvelle saisie, sans succès. Même avec des try....with Failure _ ->... le programme s'arrête avec "Fatal error: exception Scanf.Scan_failure("scanf: bad input at char number 0: a")"

    du coup je creuse dans une autre voie pour récupérer une liste d'entiers

  4. #4
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Points : 1 104
    Points
    1 104
    Par défaut
    Le code utilisant bscanf est compliqué spécifiquement parce qu'il lit une ligne terminée par un \n et ensuite la reparse pour récupérer les entiers. La ligne est lue une fois pour toute et terminée, tu ne peux pas l'étendre avec une entrée dynamique.

    Est-ce que tu pourrais spécifier plus précisément le comportement que tu cherches ? Par exemple si tu sais que tu veux lire N entiers (pour N connu au moment où tu veux lire les entiers), c'est facile. Comment est-ce que tu sais si tu dois encore attendre des entiers de l'utilisateur, ou si tu as terminé de lire et dois renvoyer la liste des entiers lus jusque là ?

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    En fait, l"utilisateur doit envoyer cinq entiers, pas plus ni moins.

    Mais c'est bon, j'ai trouvé comment me débrouiller avec ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    let string = read_line ();;
     
    let check_length string =
    	if String.length string > 5 then false else true;;
     
    let check_integer string index =
    	try int_of_string (String.sub string index 1) with Failure _ -> -1;;
     
    let rec check_each string index =
    	match (check_integer string index) with
    		-1 -> false
    		| _ -> if index < 4 then (check_each string (index+1)) else true;;
     
    if (check_each string 0) then print_endline "bon" else print_endline "mauvais";;
    C'est juste un début de code mais je pense que la suite ne devrait pas me poser problème.
    Merci de m'avoir aidé.

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Avril 2007
    Messages
    832
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2007
    Messages : 832
    Points : 1 104
    Points
    1 104
    Par défaut
    C'est trop compliqué et ça a toutes les chances de ne pas marcher si tes entiers ont plusieurs chiffres.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    let inline_read_int () = Scanf.scanf " %d" (fun n -> n)
     
    let rec read_n_ints = function
      | 0 -> []
      | n ->
        (* on fait attention à lire l'entier avant de lire la suite
            avec un séquençage explicite des effets par 'let' *)
        let i = inline_read_int () in
        i :: read_n_ints (n - 1)
     
    let () = List.iter (Printf.printf "%d\n") (read_n_ints 5)

  7. #7
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    J'ai oublié de préciser que l'utilisateur ne peut rentrer que des chiffres entre 0 et 9.

    Ça marche bien sauf que j'ai voulu mettre tout ça dans une fonction récursive avec plusieurs if...else et, comme à chaque fois que je veux faire ça en ocaml, j'ai des syntax error avec des ";;". Je ne comprends pas, ça me donne l'impression qu'on ne peut pas faire de traitement un minimum complexe dans ce langage, ou alors c'est moi qui n'ai rien compris aux ;/;;.
    Le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
    let check_length string =
    	if String.length string > 5 then false else true
     
    let check_integer string index =
    	try int_of_string (String.sub string index 1) with Failure _ -> -1
     
    let rec check_each string index =
    	match (check_integer string index) with
    		-1 -> false
    		| _ -> if index < 4 then (check_each string (index+1)) else true;;
     
    let rec input () =
    	print_string "Tapez une proposition : ";
    	let string = read_line ();
    	if not (check_length string) then input ();
    	if not (check_each string 0) then input () else string;;
     
    let string = input ();;
    print_endline (string ^ " correct.");;
    L'erreur :

    File "main.ml", line 34, characters 55-57:
    Error: Syntax error

    elle pointe exactement le ";;" qui termine la fonction récursive input (). J'aimerais bien comprendre ce qui cloche avec ça.

    Si j'enlève ces mêmes ";;" alors il me met syntax error sur le début de la ligne suivante ( let string = input ();; )
    Ça m'énerve, à chaque fois que j'essaie de faire un programme de plus de 5-10 lignes, il me met des syntax error de ce genre, j'ai vraiment dû rater quelque chose quand j'ai lu la documentation, mais quoi ??

  8. #8
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Bonsoir,

    Deux règles simples :


    1. Le code let string = read_line (); est erroné car il manque in.
    2. Dans un code destiné à la compilation, le double ;; est inutile.

    On se sert de ;; pour lancer l'analyse d'une séquence de code dans le toplevel caml, exactement comme le saut de ligne dans Python. J'ajoute qu'en OCaml comme dans tous les langages, les compilateurs indiquent parfois des erreurs un peu plus loin que leur position véritable... je crois que c'est le cas ici.

    Cordialement
    Cacophrène

  9. #9
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    Merci, je pensais que les ;; étaient absolument obligatoires.
    j'ai fait ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
     
     
    let check_length string =
    	if (String.length string) != 5 then false else true
     
    let check_integer string index =
    	try int_of_string (String.sub string index 1) with Failure _ -> -1
     
    let rec check_each string index =
    	match (check_integer string index) with
    		-1 -> false
    		| _ -> if index < (String.length string - 1) then (check_each string (index+1)) else true;;
     
    print_string "Tapez une proposition : "
     
    let string = ref (read_line ());;
     
    while not (check_length !string) || not ( check_each !string 0 ) do
    	print_string "Incorrect. Retapez une proposition : ";
    	string := read_line ()
    	done;;
     
    print_endline (!string ^ " correct.")
    ça marche !
    mais je ne sais pas pourquoi, je trouve ça un peu "sale" d'utiliser une référence ici, mais j'ai l'impression que ça aurait été impossible à faire sans.
    j'ai aussi du mal à comprendre la ponctuation, si j'enlève un ; par ci par là ça ne compile plus, faut que je relise la documentation là-dessus.
    Je vais essayer d'éclaircir le code, je le trouve assez illisible ici.

  10. #10
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Bonjour,

    Tu peux effectivement améliorer ce code et te passer de référence... je te laisse chercher un peu.

    Cordialement,
    Cacophrène

  11. #11
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    J'en suis là :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
     
     
    let list_of_rand max =
    	Random.self_init ();
    	let rec create max list = if List.length list < max then create max ((Random.int 10)::list) else list in
    	create max []
     
    let rec clch string index =
    	let cint string index = try int_of_string (String.sub string index 1) with Failure _ -> -1 in
    	match (cint string index) with -1 -> false | _ -> (if index < (String.length string - 1) then (clch string (index+1)) else true)
     
    let rec list_of_string string index list =
    	if index < (String.length string) then list_of_string string (index+1) ((int_of_string (String.sub string index 1))::list) else (List.rev list)
     
    let rec loop inputs =
    	if (clch inputs 0) && (String.length inputs) = 5 then (list_of_string inputs 0 []) else loop (read_line ());;
     
    loop (read_line ());;
     
    print_endline "ok"
    Ça fonctionne bien, c'est juste assez brouillon, je vais essayer d'éclaircir encore.
    Par contre, le ";;" sert bien à quelque chose sur loop (read_line ());;
    si je l'enlève, j'ai :
    Error: This function is applied to too many arguments;
    maybe you forgot a `;'
    et si je ne mets qu'un ";", j'ai :
    Warning S: this expression should have type unit.

    (ces messages d'erreur pointant sur la ligne "loop (read_line ());;" évidemment)

    du coup je comprends encore moins quand il faut mettre ";", quand il faut mettre ";;" et quand il ne faut rien mettre.

  12. #12
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Bonsoir,

    Il faut encapsuler le code plutôt que de le laisser tout seul :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    let _ =
      let line = read_line () in
      ignore (loop line);
      print_endline "ok"
    Autre remarque : attention aux effets de bord (read_line) dans les arguments des fonctions ! L'ordre d'évaluation n'est pas spécifié (en pratique, il a lieu de droite à gauche).

    Cordialement,
    Cacophrène

  13. #13
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    Bonsoir, j'en suis là :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
     
     
    let rec check_list string index =
    	let check_integer string index = try int_of_string (String.sub string index 1) with Failure _ -> -1 in
    	match (check_integer string index) with -1 -> false | _ -> (if index < (String.length string - 1) then (check_list string (index+1)) else true)
     
    let rec list_of_string string index list =
    	if index < (String.length string) then list_of_string string (index+1) ((int_of_string (String.sub string index 1))::list) else (List.rev list)
     
    let rec loop inputs =
    	if (check_list inputs 0) && (String.length inputs) = 5 then (list_of_string inputs 0 []) else loop (read_line ());;
     
    let rec ite vie = if vie > 0 then begin loop (read_line ()); ite (vie-1); end in
    ite 5;;
     
    print_endline "";;
    le code compile avec le warning

    File "main.ml", line 34, characters 40-59:
    Warning S: this expression should have type unit.

    la ligne 34, c'est

    let rec ite vie = if vie > 0 then begin loop (read_line ()); ite (vie-1); end in
    ite 5;;

    au caractère 40 il y a (read_line ())

    comment se fait-il que j'obtienne ce message alors que le binaire compilé fonctionne bien ?

    Cacophrene -> qu'entends-tu par encapsuler ? je débute en ocaml.
    Merci pour ton aide.

  14. #14
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Bonjour,

    En fait « encapsuler » n'est pas le bon mot. Je veux juste dire que l'on évite en général d'écrire du code hors d'un let foo = bar dans un module, même si c'est autorisé. On utilise let _ = bar (ou let () = bar) quand on ne souhaite pas stocker le résultat. La règle des points-virgules est alors très simple :

    • Un point-virgule entre chaque instruction
    • Pas de point-virgule à la fin d'un bloc (définition de fonction, de variable, etc.)

    C'est tout.

    Cordialement,
    Cacophrène

  15. #15
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    Merci pour les renseignements.

    Voici le code que j'ai pour l'instant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    (* on crée une liste de cinq entiers à partir d'une liste vide [] *)
     
    let rec list_of_rand list =
    	if List.length list < 5 then list_of_rand ((Random.int 10)::list) else list
     
    (* on vérifie que la chaîne de caractères envoyée contient bien cinq caractères *)
     
    let check_void string =
    	match string with "" -> false | _ when String.length string = 5-> true | _ -> false
     
    (* si oui, on vérifie que chaque caractère est bien un entier *)
     
    let rec check_list string index =
    	let check_integer string index = try int_of_string (String.sub string index 1) with Failure _ -> -1 in
    	match (check_integer string index) with -1 -> false | _ -> (if index < (String.length string - 1) then (check_list string (index+1)) else true)
     
    (* si oui, on construit la liste d'entiers *)
     
    let rec list_of_string string index list =
    	if index < (String.length string) then list_of_string string (index+1) ((int_of_string (String.sub string index 1))::list) else (List.rev list)
     
    (* on fait toutes les vérifications précédemment énoncées et on renvoie la liste obtenue *)
     
    let rec loop input =
    	if (check_void input) && (check_list input 0) then (list_of_string input 0 []) else loop (read_line ())
     
    let _ =
    	print_endline "Devinez la combinaison secrète en dix coups.";
    	Random.self_init ()
    	let random_list = list_of_rand [];
    Je compile, j'exécute, ça fonctionne.
    Mais (!) si j'ajoute une ligne

    List.iter (function v -> print_int v) random_list

    juste après le let random_list = list_of_rand []; , j'ai ce message à la compilation :

    File "main.ml", line 34, characters 39-50:
    Error: Unbound value random_list

    Qu'est-ce que ça veut dire ?

    Edit : oups désolé cacophrene j'ai édité trop tard on dirait.

    Re-edit : si je mets let random_list = list_of_rand [] in
    List.iter (function v -> print_int v) random_list

    la compilation fonctionne et l'exécution aussi, mais alors j'ai une question : je suis obligé de mettre in à chaque fois que je veux définir une valeur ?

  16. #16
    Membre éprouvé
    Avatar de Cacophrene
    Homme Profil pro
    Biologiste
    Inscrit en
    Janvier 2009
    Messages
    535
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Biologiste

    Informations forums :
    Inscription : Janvier 2009
    Messages : 535
    Points : 1 125
    Points
    1 125
    Par défaut
    Bonsoir,

    Citation Envoyé par Lyaskator
    J'ai une syntax error sur la toute dernière ligne ( qui est vide ).
    Où est le problème ?
    Il est ici : let input = loop list;. Il manque le in !

    Cordialement,
    Cacophrène

  17. #17
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2010
    Messages
    17
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2010
    Messages : 17
    Points : 7
    Points
    7
    Par défaut
    Edit : voilà, le code est bon, compile et fonctionne parfaitement !

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
     
     
    (* on définit le nombre maximum d'essais et la taille des combinaisons d'entiers *)
     
    let (trials_number, lists_range) = (-30, 4)
     
    (* on crée une liste de trois entiers à partir d'une liste vide [] *)
     
    let rec list_of_rand list =
    	if List.length list < lists_range then list_of_rand ((Random.int 10)::list) else list
     
    let random_list = Random.self_init (); list_of_rand []
     
    (* on vérifie que la chaîne de caractères envoyée contient bien trois caractères *)
     
    let check_void string =
    	(String.length string = lists_range)
     
    (* si oui, on vérifie que chaque caractère est bien un entier *)
     
    let rec check_list string index =
    	let check_integer string index = try int_of_string (String.sub string index 1) with Failure _ -> -1 in
    	match (check_integer string index) with -1 -> false | _ -> (if index < (String.length string - 1) then (check_list string (index+1)) else true)
     
    (* si oui, on construit la liste d'entiers *)
     
    let rec list_of_string string index list =
    	if index < (String.length string) then list_of_string string (index+1) ((int_of_string (String.sub string index 1))::list) else (List.rev list)
     
    (* on fait toutes les vérifications précédemment énoncées et on renvoie la liste obtenue *)
     
    let rec get_list input =
    	if (check_void input) && (check_list input 0) then (list_of_string input 0 []) else begin print_string "Retapez une proposition correcte : "; get_list (read_line ()); end
     
    (* on compare les deux listes si elles ne sont pas identiques *)
     
    let rec compare_lists1 input_list random_list =
    	if List.hd input_list = List.hd random_list then true
    	else if List.length input_list = 1 then false
    	else compare_lists1 (List.tl input_list) (List.tl random_list)
     
    let rec compare_lists2 input_list random_list =
    	if List.mem (List.hd input_list) random_list then true
    	else if List.length input_list = 1 then false
    	else compare_lists2 (List.tl input_list) random_list
     
    (* on affiche le résultat de la comparaison *)
     
    let int_of_list list = int_of_string (String.concat "" (List.map (function elem -> string_of_int elem) list))
     
    let rec print_result input_list random_list =
    	if compare_lists1 input_list random_list then print_endline "Au moins un entier correspond."
    	else if compare_lists2 input_list random_list then print_endline "Au moins un entier n'est pas à la bonne place."
    	else begin print_string "Aucun entier ne correspond, "; if (int_of_list input_list) < (int_of_list random_list) then print_endline "cherchez plus haut." else print_endline "cherchez plus bas."; end
     
    (* on définit la boucle principale *)
     
    let rec main trials =
    	print_string ((string_of_int (trials+1)) ^ " Tapez une proposition : ");
    	let input_list = get_list (read_line ()) in
    	if not (input_list = random_list) then if trials <= 0 then begin print_string "Vous avez perdu ! La combinaison était : "; List.iter (function elem -> print_int elem) random_list; print_endline ""; end else begin print_result input_list random_list; main (trials-1); end else print_endline "Vous avez gagné !"
     
    (* on lance tout *)
     
    let _ =
    	print_endline ("Devinez la combinaison secrète en " ^ (string_of_int trials_number) ^ " coups maximum.");
    	main (trials_number-1)
    On peut changer la difficulté en modifiant la première ligne maintenant.

    Merci pour votre aide, Bluestorm et Cacophrene ( si j'ai encore un problème en modifiant ce code je reviens vous embêter, promis ).
    Je pense que je commence à capter ce qu'il (ne) faut faire pour ramasser des syntax error à la pelle en ocaml.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [MySQL] Entrer une liste de pays dans une base de données
    Par Marc22 dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 13/07/2009, 15h04
  2. Réponses: 1
    Dernier message: 11/08/2008, 20h37
  3. Réponses: 2
    Dernier message: 05/06/2008, 17h19
  4. Demander à l'utilisateur de saisir une phrase
    Par domidut dans le forum Prolog
    Réponses: 1
    Dernier message: 25/04/2007, 19h27
  5. [VBA-Excel] - Demander à l'utilisateur de choisir une cellule
    Par MrYoYo dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 14/02/2007, 11h54

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo