Lecture de l'entrée en OCaml (QCM 2014, Exo 1)

Bonjour,

Étant donné l'extrême mocheté des codes de base fournis cette année (j'ai lu qu'ils étaient générés par automatiquement), je me suis dis que c'était une bonne occasion pour apprendre à lire sur l'entrée standard en OCaml pour me passer de ces codes (qui j'ai l'impression ralentissent l'exécution : je ne passe pas le dernier test de performance sur l'exo 1).

J'ai eu plutôt du mal à trouver de la doc sur internet mais j'ai réussi à priori à générer un tableau à partir d'une suite d'entier séparés par des espaces : "Array.init len (fun _ -> Scanf.scanf "%d " (fun n -> n)" (bien que je n'ai pas testé) en regardant les codes des années précédentes.

Mais maintenant, j'aimerai créer une liste d'entiers, toujours à partir d'une suite d'entier séparé par des espaces. Pour cela, j'ai tenté d'utiliser cette fonction : "let rec lire_delta len = if len=0 then [] else (Scanf.scanf "%d " (fun x->x))::(lire_delta (len-1));;" mais j'ai une erreur.

Voici le code complet :
« let rec lire_delta len = if len=0 then [] else (Scanf.scanf "%d " (fun x->x))::(lire_delta (len-1));;

let len=read_int() in
vantardise (lire_delta len);; »

Et lorsque j'entre par exemple :
«2
1 3»
J'obtiens « Exception: Failure "int_of_string". »

Et sur d'autres tests j'obtiens « Exception:
Scanf.Scan_failure
"scanf: bad input at char number 10: ``character ';' is not a decimal digit''". » (Par exemple si je fais d'abord un retour chariot avec d'écrire les nombres)

En espérant que vous pourrez m'aider,

Princeps.

P.S. : En fait j'ai le même genre d'erreurs pour générer un tableau.

Edit : Peut-être que le problème vient du fait que je fais mes tests sans compiler, dans un interpréteur.

Ah merci, ça me débloque à moi aussi.
J'ai un problème similaire au niveau des entrées sorties pour le problème 5, quelqu'un pourrait me donner un code qui passe tous les tests please? Juste pour voir comment vous avez fait.

Je ne suis pas sûr que le « à moi aussi » soit utile après « ça me débloque ».
Je n'ai malheureusement pas réussi l'exercice 5.

Effectivement, avec les fonctions de France-ioi ça marche !

Si j'ai bien analysé le problème, c'est dans le paramètre de filtrage du Scanf.scanf, j'utilisais "%d " (je crois que j'avais trouvé ça dans des anciens sujets de Prologin mais pas sûr) alors que chez France-ioi, ils utilisent " %d" (l'espace est avant).

Merci, je vais pouvoir affiner tout ça.

Par contre, une petite question : dans les fonctions de france-ioi, pour générer une liste il y a ça :

let scan_int_list_of_size n =
Array.to_list (Array.init n (fun _ -> scan_int()))

Je trouve ça assez sale de générer d'abord un tableau puis de le transformer en liste, même si en complexité asymptotique c'est la même chose à priori (O(n)... Quelqu'un aurait pas une idée de truc mieux qui marche ? Je vais essayer aussi de trouver quelque chose.

Princeps.

Ça y est, j'ai un code qui marche sans tableau. Je n'utilise pas de liste parce que je n'ai pas besoin de stocker les valeurs mais je pourrais très bien les mettre dans une liste. Il suffit en fait d'utiliser scan_int (défini par let scan_int () = Scanf.scanf " %d" (fun x -> x) , merci france-ioi) pour extraire les entiers successivement d'une suite d'entiers séparés par des espaces.

Mon code utilise "%d " et passe les tests comme tu peux le voir plus haut.
Tu peux créer une fonction d'initialisation de liste similaire à Array.init comme tu l'as fait plus haut, ce sera simplement plus long à écrire ; ça n'a de toute façon aucun intérêt ici.

Effectivement, j'avais oublié...

Du coup je comprends pas ce qui plantait dans mon code au début mais j'ai la flemme de refaire des tests maintenant, j'éluciderai ça plus tard. Maintenant j'arrive à lire l'entrée, j'ai pu mettre en pratique sur les exos suivants, ça me va pour l'instant ;).

Merci,

Princeps.

Suite aux problèmes techniques (surcharge du serveur), on lasse les soumissions ouvertes un peu plus longtemps (non, vous n'aurez pas tout le week-end cette année), donc il est toujours interdit de publier du code

Répondre au sujet

Vous devez vous enregistrer ou vous connecter pour poster des messages.