Petits exercices sur Caml

Discutez d'informatique ici !
jonses
Membre Relatif
Messages: 496
Enregistré le: 19 Mai 2013, 09:33

petits exercices sur Caml

par jonses » 09 Fév 2014, 20:06

Bonjour,

Je viens de commencer à aborder le langage Caml en cours, et j'avoue que j'ai dû mal à programmer des choses simples.
Je suis bloqué sur deux petits exercices :

1) Afficher tous les caractères standards visibles (le code ASCII est compris entre 32 et 127) à raison de 32 caractères par ligne

2) Ecrire une fonction "miroir" qui renvoie le miroir d'un entier naturel donné. Par exemple en entrant 123456, la fonction doit renvoyer 654321.


Pour la 1), je n'y arrive tout simplement pas et pour la 2) j'ai écrit une fonction abominable qui ne donne finalement pas le résultat demandé

Si quelqu'un peut m'aider svp.
Je vous remercie d'avance pour vos réponses



Avatar de l’utilisateur
ampholyte
Membre Transcendant
Messages: 3940
Enregistré le: 21 Juil 2012, 07:03

par ampholyte » 10 Fév 2014, 09:19

Bonjour,

Pour la première partie, tu as la fonction "char_of_int" qui devrait t'aider

Pourrais-tu mettre ton code pour la seconde partie ?

Doraki
Habitué(e)
Messages: 5021
Enregistré le: 20 Aoû 2008, 11:07

par Doraki » 10 Fév 2014, 14:31

T'as fait quoi pour le 2 ?

jonses
Membre Relatif
Messages: 496
Enregistré le: 19 Mai 2013, 09:33

par jonses » 10 Fév 2014, 23:29

Pour la 1) j'ai fait ça

----
for i=32 to 127 do
print_char(char_of_int(i));
if (i mod 32)=0 then print_newline
done;;

---

Mais clairement, il y a un problème de typage : print_newline est du type "unit->unit" alors qu'il faut du type "unit" à la place. J'arrive pas à résoudre le problème


Pour la 2) :

----

let miroir n=
let r =ref 0 in
let s = ref n in
let a = ref 10 in
let b = ref 1 in
while n/(!b)0 do
b:= !b*10 done;
while !s/ !a0 do
r:= !r + !b*( !s mod !a);
s:= !s/(!a);
a:= !a*10;
b:= !b/10
done;
!r;;

----

Pour celle-là, Caml me donne pour 123456, le nombre 10500000

Monsieur23
Habitué(e)
Messages: 3966
Enregistré le: 01 Oct 2006, 17:24

par Monsieur23 » 11 Fév 2014, 00:12

Aloha,

Si print_newline est de type unit -> unit, ça veut dire qu'il faut lui passer un argument de type unit pour obtenir un résultat de type unit. Ici, tu ne lui passes pas d'argument, c'est normal que ça plante.

Ton code pour la deuxième question est effectivement pas terrible (disons, pas dans l'esprit fonctionnel de Caml).

Que dirais-tu d'un code en 3 fonctions :
— une fonction qui transforme ton entier en liste de chiffres ;
— une fonction qui "miroirise" une liste ;
— la fonction inverse de la première, qui transforme une liste de chiffres en entier.

Tu peux définir ces trois fonctions de manière fonctionnelle, inductive.
« Je ne suis pas un numéro, je suis un homme libre ! »

jonses
Membre Relatif
Messages: 496
Enregistré le: 19 Mai 2013, 09:33

par jonses » 11 Fév 2014, 08:51

Monsieur23 a écrit:Ton code pour la deuxième question est effectivement pas terrible (disons, pas dans l'esprit fonctionnel de Caml).

Que dirais-tu d'un code en 3 fonctions :
— une fonction qui transforme ton entier en liste de chiffres ;
— une fonction qui "miroirise" une liste ;
— la fonction inverse de la première, qui transforme une liste de chiffres en entier.

Tu peux définir ces trois fonctions de manière fonctionnelle, inductive.


C'est ce à quoi je pensais en premier, mais comme je n'ai toujours pas appris à manipuler les listes, j'ai dû faire sans. C'est une des raisons pour lesquelles mon programme est pourri (que ce soit en Caml ou en un autre langage)

Monsieur23
Habitué(e)
Messages: 3966
Enregistré le: 01 Oct 2006, 17:24

par Monsieur23 » 11 Fév 2014, 09:36

Alors disons, même sans liste, tu peux utiliser une fonction inductive directement sur les entiers :
— le miroir d'un entier à un chiffre, c'est lui-même ;
— le miroir d'un entier quelconque, c'est le dernier chiffre, suivi du miroir du reste.
« Je ne suis pas un numéro, je suis un homme libre ! »

Doraki
Habitué(e)
Messages: 5021
Enregistré le: 20 Aoû 2008, 11:07

par Doraki » 11 Fév 2014, 09:40

Ton code pour le 2 est équivalent à

let miroir n=
let r,s,a,b = 0,n,10,1 in
let rec boucle1 b = if n/b > 0 then let b = 10*b in boucle1 b else b in
let b = boucle1 b in
let rec boucle2 r s a b = if s/a > 0 then
let r = r+b*(s mod a) in
let s = s/a in
let a = a*10 in
let b = b/10 in
boucle2 r s a b
else r in
boucle2 r s a b

ou encore :

let miroir n=
let rec boucle1 b = if n/b > 0 then boucle1 (10*b) else b in
let rec boucle2 r s a b = if s/a > 0 then
boucle2 (r+b*(s mod a)) (s/a) (a*10) (b/10)
else r in
boucle2 0 n 10 (boucle1 b)

Donc si j'ai bien suivi, d'abord tu détermines la plus petite puissance de 10, b = 10^k telle que n<10^k . k est donc le nombre de chiffres de n. Ensuite voici ce qui se passe sur n=123456 et b = 10^6 :

-1er tour : r,s,a,b = 0,123456,10,1000000
- s mod a vaut 6, donc tu continues avec
- 2ème tour : r,s,a,b = 6000000,12345,100,100000
(déjà r est trop grand tu devrais avoir 600000 à la place)
- s mod a vaut 45 : pourquoi DIABLE est-ce que tu as augmenté a !?!?
tu continues avec :
-3ème tour : r,s,a,b = 10500000,123,1000,10000
ici s
Donc tu as 3 problèmes : le décalage des puissances de 10, l'existence de a, et le fait que tu t'arrêtes un coup trop tôt.

jonses
Membre Relatif
Messages: 496
Enregistré le: 19 Mai 2013, 09:33

par jonses » 11 Fév 2014, 19:31

Oui je sais, ce que j'ai fait est archi-naze :ptdr:

Bon j'ai changé :

Pour la 1)

--

for i=32 to 127 do
if (i mod 32)=0 then print_newline();
print_char(char_of_int(i)) done;;

--

et pour la 2)

--

let miroir n=
let r=ref 0 in
let s=ref n in
while !s<>0 do
r:=(!r)*10 + (!s mod 10);
s:= !s/10
done;
!r;;

 

Retourner vers ϟ Informatique

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 8 invités

Tu pars déja ?



Fais toi aider gratuitement sur Maths-forum !

Créé un compte en 1 minute et pose ta question dans le forum ;-)
Inscription gratuite

Identification

Pas encore inscrit ?

Ou identifiez-vous :

Inscription gratuite