8.1 KiB
Fonctionnalité de retrait de lettres
Vue d'ensemble
La fonctionnalité de retrait de lettres permet de générer des anagrammes plus prononçables en supprimant stratégiquement certaines lettres du mot source. Cette approche est particulièrement utile pour créer des pseudonymes à partir de mots difficiles à prononcer.
Motivation
Certains mots contiennent des combinaisons de lettres qui rendent difficile la création d'anagrammes prononçables :
- Mots avec peu ou pas de voyelles (ex: "rhythm", "strength")
- Mots avec de nombreuses consonnes consécutives
- Mots longs avec une distribution difficile de lettres
Le retrait stratégique de lettres permet d'augmenter considérablement le taux de réussite et la qualité des pseudonymes générés.
Utilisation
Option CLI
-r, --remove-letters <NOMBRE>
Autorise le retrait jusqu'à <NOMBRE> lettres pour maximiser la prononçabilité.
Exemples
Mot difficile sans voyelles
# Sans retrait : aucun résultat avec score ≥ 60
cargo run -- --word bcdfghjkl --count 5 --min-score 60
# Résultat: No anagrams generated.
# Avec retrait : résultats possibles
cargo run -- --word bcdfghjkl --count 5 --min-score 40 --remove-letters 5
Mot avec consonnes consécutives
# Sans retrait
cargo run -- --word strength --count 10 --min-score 60
# Résultat: No anagrams generated.
# Avec retrait de 2 lettres
cargo run -- --word strength --count 10 --min-score 60 --remove-letters 2
# Résultats: thsetr, rtethg, trgent, hgestn, etc.
Algorithme
Stratégie adaptative
L'algorithme utilise une stratégie LetterRemovalStrategy::Adaptive qui :
- Explore différentes configurations : Teste 0, 1, 2, ..., N retraits de lettres
- Sélection aléatoire : Choisit aléatoirement quelles lettres retirer
- Critères de sélection :
- Priorise le score de prononçabilité le plus élevé
- À score égal, préfère les mots plus longs (moins de retraits)
Pseudo-code
pour chaque tentative de génération:
meilleur_anagramme = None
pour nombre_retraits de 0 à max_removals:
lettres_gardées = sélection_aléatoire(source, taille - nombre_retraits)
anagramme_candidat = mélanger(lettres_gardées)
score = évaluer_prononçabilité(anagramme_candidat)
si score >= score_minimum:
si meilleur_anagramme == None ou score > meilleur_score:
meilleur_anagramme = anagramme_candidat
sinon si score == meilleur_score et len(candidat) > len(meilleur):
meilleur_anagramme = anagramme_candidat
retourner meilleur_anagramme
Limites
- Longueur minimale : Au moins 1 lettre doit rester
- Limite de retrait :
min(max_removals, len(mot) - 2) - Pas de retrait excessif : Garde au moins 2 caractères pour maintenir un sens
Architecture logicielle
Enum LetterRemovalStrategy
pub enum LetterRemovalStrategy {
/// No letters will be removed
None,
/// Remove up to N letters to maximize pronounceability
Adaptive { max_removals: usize },
}
Configuration
// Par défaut : pas de retrait
let config = GenerationConfig::default();
assert_eq!(config.letter_removal, LetterRemovalStrategy::None);
// Avec retrait
let config = GenerationConfig::default()
.allow_removing_letters(3);
// Ou explicitement
let config = GenerationConfig::default()
.with_letter_removal(LetterRemovalStrategy::Adaptive { max_removals: 3 });
Méthodes du générateur
impl<R: Rng, S: PronounceabilityScorer> AnagramGenerator<R, S> {
// Point d'entrée selon la stratégie
fn try_generate_one(...) -> Option<Anagram>
// Génération sans retrait (comportement original)
fn try_generate_without_removal(...) -> Option<Anagram>
// Génération avec retrait adaptatif
fn try_generate_with_removal(...) -> Option<Anagram>
// Essai avec un nombre spécifique de retraits
fn try_with_specific_removals(...) -> Option<Anagram>
}
Tests
Couverture des tests
10 tests dédiés dans tests/letter_removal_tests.rs :
-
Configuration :
test_letter_removal_disabled_by_defaulttest_letter_removal_can_be_enabledtest_config_builder_with_letter_removaltest_letter_removal_strategy_with_method
-
Comportement :
test_generation_without_removal_produces_same_lengthtest_generation_with_removal_may_produce_shorter_wordstest_letter_removal_respects_max_removalstest_letter_removal_maintains_min_word_length
-
Efficacité :
test_letter_removal_improves_pronounceabilitytest_letter_removal_with_good_word
Exécuter les tests
# Tous les tests
cargo test
# Tests spécifiques au retrait de lettres
cargo test --test letter_removal_tests
# Un test particulier
cargo test test_letter_removal_improves_pronounceability
Performance
Impact sur le temps d'exécution
Le retrait de lettres ajoute une complexité computationnelle :
- Sans retrait : O(1) par tentative (un seul shuffle)
- Avec retrait (N max) : O(N) par tentative (N+1 shuffles)
Optimisations
- Early exit : Si un score parfait est atteint avec 0 retrait, arrêt immédiat
- Limite adaptative : Ne teste pas plus de retraits que nécessaire
- Sélection intelligente : Préfère les mots plus longs à score égal
Recommandations
- Petites valeurs : Utilisez
--remove-letters 2-3pour la plupart des cas - Valeurs moyennes :
--remove-letters 4-5pour des mots très difficiles - Augmentez les tentatives : Combinez avec
--max-attempts 5000+pour des mots problématiques
Cas d'usage
1. Génération de pseudonymes courts
cargo run -- --word "christopher" --count 10 --min-score 70 --remove-letters 5
# Génère des pseudonymes de 8-13 lettres prononçables
2. Mots techniques ou étrangers
cargo run -- --word "krzyzewski" --count 5 --min-score 50 --remove-letters 4
# Adapte des mots difficiles en pseudonymes prononçables
3. Amélioration du taux de réussite
# Faible taux de réussite sans retrait
cargo run -- --word "complexity" --count 20 --min-score 75
# Meilleur taux avec retrait
cargo run -- --word "complexity" --count 20 --min-score 75 --remove-letters 3
4. Création de noms de marque
cargo run -- --word "innovative" --count 15 --min-score 80 --remove-letters 2
# Génère des noms courts et mémorables
Principes SOLID respectés
Single Responsibility Principle
LetterRemovalStrategy: Définit la stratégie- Méthodes séparées pour chaque comportement
Open/Closed Principle
- Extensible : Nouvelles stratégies peuvent être ajoutées
- Fermé : Code existant non modifié
Liskov Substitution Principle
- Toute stratégie respecte le contrat
- Comportement prévisible
Dependency Inversion Principle
- Configuration injectable
- Pas de dépendance hard-codée
Limitations actuelles
-
Sélection aléatoire : Les lettres à retirer sont choisies aléatoirement
- Amélioration possible : Cibler les consonnes problématiques
-
Pas de cache : Recalcule à chaque tentative
- Amélioration possible : Mémoriser les scores calculés
-
Pas de heuristiques phonétiques : Ne considère pas la structure phonétique
- Amélioration possible : Retirer préférentiellement certaines consonnes
Extensions possibles
Stratégies avancées
pub enum LetterRemovalStrategy {
None,
Adaptive { max_removals: usize },
// Nouvelles stratégies possibles :
TargetedConsonants { max_removals: usize },
PreserveVowels { min_vowels: usize },
PhoneticOptimization { target_score: u32 },
}
Configuration fine
pub struct AdaptiveRemovalConfig {
pub max_removals: usize,
pub prefer_consonant_removal: bool,
pub preserve_starting_letter: bool,
pub target_length: Option<usize>,
}
Références
- Code source : src/generator.rs
- Tests : tests/letter_removal_tests.rs
- Documentation API :
cargo doc --open