Code de César ?

L'auteur de ce sujet a trouvé une solution à son problème.
Auteur du sujet

Bonjour à tous,

Je cherche à écrire en OCaml une fonction qui permet de calculer le code de César d'une chaîne, quelque chose comme ça :

1
val cesar -> string -> int -> string

Mon idée était d'utiliser String.map pour appliquer la transformation à chaque caractère de la chaîne donnée en entrée. Cependant, la fonction attendue par String.map est de type Char -> Char, et je n'ai pas trouvé dans Char de fonction me permettant de réaliser la transformation que je recherche.

Est-ce que c'est moi qui ai manqué quelque chose, ou est-ce que je dois contourner ce manque d'une autre manière, comme en passant par l'ASCII du caractère, ou quelque chose du genre ? D'ailleurs, le code de César proposé sur RosettaCode me paraît assez laid : je sais bien qu'OCaml gère plutôt la programmation impérative, mais on devrait pouvoir s'en sortir sans, je me trompe ?

Cette réponse a aidé l'auteur du sujet

Ta solution avec String.map me semble la plus logique à utiliser.

Comme tu l'as souligné, il n'existe pas de fonction qui te fasse la transformation directement. Il faut que tu la fasses toi-même. Pour cela, la méthode la plus simple me semble être d'utiliser le code ASCII des caractères (avec Char.code et Char.chr). Il faudra cependant faire attention à ne pas décaler les caractères non alphabétique.

Tu peux facilement repérer ce genre de caractères via :

1
2
if Char.code c >= Char.code 'a' && Char.code c <= Char.code 'z' then
   ...

Je te conseille fortement de laisser les constructions du type Char.code 'a' tels quels afin d'avoir un code plus lisible.

+0 -0
Auteur du sujet

Bon, donc c'est bien moi qui avais manqué quelque chose. Merci ! :)

EDIT : Char.code et Char.chr n'existent pas chez moi. Qu'est-ce qui peut provoquer ça ? J'utilise utop avec OCaml 4.02.1 et la bibliothèque Core, si ça peut aider.

Édité par Richou D. Degenne

Auteur du sujet

Voilà le résultat, pour ceux que ça intéresse. :)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
open Core.Std

let cesar s n =
    let move c n =
        if Char.is_alpha c then
            let padding = Char.to_int (if Char.is_lowercase c then 'a' else 'A') in
            Char.of_int ((Char.to_int c - padding + n) % 26 + padding)
        else
            Some c
    in
    String.map s ~f:(fun c -> match move c n with | None -> assert false | Some e -> e)

let () =
    let message = "Ceci Est Un Test Avec un z Et Un Z." in
    printf "%s\n%s\n" message (cesar message 1)
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte