285 lines
8.1 KiB
Markdown
285 lines
8.1 KiB
Markdown
# 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
|
|
|
|
```bash
|
|
-r, --remove-letters <NOMBRE>
|
|
```
|
|
|
|
Autorise le retrait jusqu'à `<NOMBRE>` lettres pour maximiser la prononçabilité.
|
|
|
|
### Exemples
|
|
|
|
#### Mot difficile sans voyelles
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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 :
|
|
|
|
1. **Explore différentes configurations** : Teste 0, 1, 2, ..., N retraits de lettres
|
|
2. **Sélection aléatoire** : Choisit aléatoirement quelles lettres retirer
|
|
3. **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`
|
|
|
|
```rust
|
|
pub enum LetterRemovalStrategy {
|
|
/// No letters will be removed
|
|
None,
|
|
/// Remove up to N letters to maximize pronounceability
|
|
Adaptive { max_removals: usize },
|
|
}
|
|
```
|
|
|
|
### Configuration
|
|
|
|
```rust
|
|
// 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
|
|
|
|
```rust
|
|
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](tests/letter_removal_tests.rs) :
|
|
|
|
1. **Configuration** :
|
|
- `test_letter_removal_disabled_by_default`
|
|
- `test_letter_removal_can_be_enabled`
|
|
- `test_config_builder_with_letter_removal`
|
|
- `test_letter_removal_strategy_with_method`
|
|
|
|
2. **Comportement** :
|
|
- `test_generation_without_removal_produces_same_length`
|
|
- `test_generation_with_removal_may_produce_shorter_words`
|
|
- `test_letter_removal_respects_max_removals`
|
|
- `test_letter_removal_maintains_min_word_length`
|
|
|
|
3. **Efficacité** :
|
|
- `test_letter_removal_improves_pronounceability`
|
|
- `test_letter_removal_with_good_word`
|
|
|
|
### Exécuter les tests
|
|
|
|
```bash
|
|
# 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
|
|
|
|
1. **Early exit** : Si un score parfait est atteint avec 0 retrait, arrêt immédiat
|
|
2. **Limite adaptative** : Ne teste pas plus de retraits que nécessaire
|
|
3. **Sélection intelligente** : Préfère les mots plus longs à score égal
|
|
|
|
### Recommandations
|
|
|
|
- **Petites valeurs** : Utilisez `--remove-letters 2-3` pour la plupart des cas
|
|
- **Valeurs moyennes** : `--remove-letters 4-5` pour 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
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
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
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
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
|
|
|
|
1. **Sélection aléatoire** : Les lettres à retirer sont choisies aléatoirement
|
|
- Amélioration possible : Cibler les consonnes problématiques
|
|
|
|
2. **Pas de cache** : Recalcule à chaque tentative
|
|
- Amélioration possible : Mémoriser les scores calculés
|
|
|
|
3. **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
|
|
|
|
```rust
|
|
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
|
|
|
|
```rust
|
|
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](src/generator.rs)
|
|
- Tests : [tests/letter_removal_tests.rs](tests/letter_removal_tests.rs)
|
|
- Documentation API : `cargo doc --open`
|