Code de César ?

Le problème exposé dans ce sujet a été résolu.

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 ?

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.

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)
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

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