Skip to content

Commit 478b94c

Browse files
authored
Merge pull request #11 from MXASoundNDEv/Dev
Dev
2 parents 2e760ee + dcc74df commit 478b94c

File tree

13 files changed

+975
-320
lines changed

13 files changed

+975
-320
lines changed
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
name: 🔍 PR Title Validation
2+
3+
on:
4+
pull_request:
5+
types: [opened, edited, synchronize]
6+
7+
jobs:
8+
validate-title:
9+
name: 📋 Validate PR Title Format
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: 📥 Checkout Code
14+
uses: actions/checkout@v4
15+
16+
- name: 🔍 Validate PR Title
17+
env:
18+
PR_TITLE: ${{ github.event.pull_request.title }}
19+
run: |
20+
echo "🔍 Validating PR title: '$PR_TITLE'"
21+
22+
# Pattern pour les conventions de commit
23+
# Format: type(scope): description
24+
if [[ "$PR_TITLE" =~ ^(feat|fix|docs|style|refactor|test|chore)(\([a-z0-9-]+\))?: .{1,50}$ ]]; then
25+
echo "✅ PR title follows conventional format"
26+
echo "## ✅ PR Title Validation" >> $GITHUB_STEP_SUMMARY
27+
echo "Le titre de la PR suit les conventions du projet:" >> $GITHUB_STEP_SUMMARY
28+
echo "\`$PR_TITLE\`" >> $GITHUB_STEP_SUMMARY
29+
else
30+
echo "❌ PR title should follow format: type(scope): description"
31+
echo "Current title: $PR_TITLE"
32+
echo ""
33+
echo "Examples:"
34+
echo " feat(autocomplete): add new autocompletion engine"
35+
echo " fix(similarity): correct Levenshtein calculation"
36+
echo " docs(readme): update API documentation"
37+
echo ""
38+
echo "Valid types: feat, fix, docs, style, refactor, test, chore"
39+
40+
# Ajouter au résumé GitHub
41+
echo "## ❌ PR Title Validation Failed" >> $GITHUB_STEP_SUMMARY
42+
echo "Le titre de la PR ne suit pas les conventions:" >> $GITHUB_STEP_SUMMARY
43+
echo "\`$PR_TITLE\`" >> $GITHUB_STEP_SUMMARY
44+
echo "" >> $GITHUB_STEP_SUMMARY
45+
echo "### 📋 Format attendu:" >> $GITHUB_STEP_SUMMARY
46+
echo "\`type(scope): description\`" >> $GITHUB_STEP_SUMMARY
47+
echo "" >> $GITHUB_STEP_SUMMARY
48+
echo "### ✅ Exemples valides:" >> $GITHUB_STEP_SUMMARY
49+
echo "- \`feat(autocomplete): add new autocompletion engine\`" >> $GITHUB_STEP_SUMMARY
50+
echo "- \`fix(similarity): correct Levenshtein calculation\`" >> $GITHUB_STEP_SUMMARY
51+
echo "- \`docs(readme): update API documentation\`" >> $GITHUB_STEP_SUMMARY
52+
echo "" >> $GITHUB_STEP_SUMMARY
53+
echo "### 🔧 Types valides:" >> $GITHUB_STEP_SUMMARY
54+
echo "\`feat\`, \`fix\`, \`docs\`, \`style\`, \`refactor\`, \`test\`, \`chore\`" >> $GITHUB_STEP_SUMMARY
55+
56+
exit 1
57+
fi
58+
59+
suggest-labels:
60+
name: 🏷️ Suggest PR Labels
61+
runs-on: ubuntu-latest
62+
needs: validate-title
63+
if: success()
64+
65+
steps:
66+
- name: 🏷️ Analyze PR and Suggest Labels
67+
env:
68+
PR_TITLE: ${{ github.event.pull_request.title }}
69+
PR_BODY: ${{ github.event.pull_request.body }}
70+
run: |
71+
echo "🏷️ Analyzing PR for label suggestions..."
72+
echo "## 🏷️ Suggested Labels" >> $GITHUB_STEP_SUMMARY
73+
echo "" >> $GITHUB_STEP_SUMMARY
74+
75+
# Extraire le type du titre
76+
if [[ "$PR_TITLE" =~ ^(feat|fix|docs|style|refactor|test|chore) ]]; then
77+
TYPE="${BASH_REMATCH[1]}"
78+
echo "📌 Type: \`$TYPE\`" >> $GITHUB_STEP_SUMMARY
79+
80+
case $TYPE in
81+
"feat")
82+
echo "- \`enhancement\`" >> $GITHUB_STEP_SUMMARY
83+
echo "- \`feature\`" >> $GITHUB_STEP_SUMMARY
84+
;;
85+
"fix")
86+
echo "- \`bug\`" >> $GITHUB_STEP_SUMMARY
87+
echo "- \`fix\`" >> $GITHUB_STEP_SUMMARY
88+
;;
89+
"docs")
90+
echo "- \`documentation\`" >> $GITHUB_STEP_SUMMARY
91+
;;
92+
"test")
93+
echo "- \`testing\`" >> $GITHUB_STEP_SUMMARY
94+
;;
95+
"refactor")
96+
echo "- \`refactoring\`" >> $GITHUB_STEP_SUMMARY
97+
;;
98+
"style")
99+
echo "- \`style\`" >> $GITHUB_STEP_SUMMARY
100+
;;
101+
"chore")
102+
echo "- \`maintenance\`" >> $GITHUB_STEP_SUMMARY
103+
;;
104+
esac
105+
fi
106+
107+
# Extraire le scope du titre
108+
if [[ "$PR_TITLE" =~ \(([a-z0-9-]+)\) ]]; then
109+
SCOPE="${BASH_REMATCH[1]}"
110+
echo "🎯 Scope: \`$SCOPE\`" >> $GITHUB_STEP_SUMMARY
111+
echo "- \`$SCOPE\`" >> $GITHUB_STEP_SUMMARY
112+
fi
113+
114+
# Analyser le contenu pour des labels supplémentaires
115+
CONTENT="$PR_TITLE $PR_BODY"
116+
117+
if [[ $CONTENT =~ (test|testing|unit.test|integration.test) ]]; then
118+
echo "- \`testing\`" >> $GITHUB_STEP_SUMMARY
119+
fi
120+
121+
if [[ $CONTENT =~ (performance|benchmark|optimization|faster) ]]; then
122+
echo "- \`performance\`" >> $GITHUB_STEP_SUMMARY
123+
fi
124+
125+
if [[ $CONTENT =~ (breaking.change|breaking|major) ]]; then
126+
echo "- \`breaking-change\`" >> $GITHUB_STEP_SUMMARY
127+
fi
128+
129+
if [[ $CONTENT =~ (security|vulnerability|CVE) ]]; then
130+
echo "- \`security\`" >> $GITHUB_STEP_SUMMARY
131+
fi
132+
133+
echo "" >> $GITHUB_STEP_SUMMARY
134+
echo "💡 **Note**: Les labels doivent être ajoutés manuellement par un maintainer ayant les permissions appropriées." >> $GITHUB_STEP_SUMMARY

CHANGELOG.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,42 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.0.2] - 2026-01-09
9+
10+
### Added
11+
#### Algorithmes et Utilitaires
12+
- **Fisher-Yates Shuffle** - Algorithme de mélange aléatoire déterministe de tableaux
13+
- Fonction standalone `fisherYatesShuffle()` exportée
14+
- Support des générateurs aléatoires personnalisés (RNG)
15+
- Tests unitaires complets avec validation du déterminisme
16+
- Définitions TypeScript complètes
17+
18+
#### Améliorations Soundex
19+
- **Support des cartes personnalisées** - Possibilité de passer des mappings de caractères personnalisés
20+
- Paramètre `customMap` pour définir des encodages phonétiques spécifiques
21+
- Priorité donnée aux custom maps sur les maps de langue
22+
- Tests de validation des mappings personnalisés
23+
- **Support multilingue étendu** - Amélioration de la normalisation pour le français
24+
- Normalisation des caractères accentués (é, è, ê, à, ù, etc.)
25+
- Gestion du ç → s et œ → e
26+
- Mappings spécifiques français (F et V → 7 au lieu de 1)
27+
- Tests pour tous les cas de normalisation
28+
29+
### Enhanced
30+
- **Documentation README**
31+
- Ajout d'un tableau de performance pour tous les algorithmes
32+
- Section "Fonctionnalités" complète avec toutes les capacités de la bibliothèque
33+
- Benchmarks détaillés (ops/s) pour petites, moyennes et grandes chaînes
34+
- Performance du RandomEngine avec toutes ses fonctions
35+
- **Tests unitaires** - 152 tests passant (amélioration de la couverture)
36+
- **TypeScript** - Définitions mises à jour pour fisherYatesShuffle et Soundex
37+
38+
### Fixed
39+
- **Soundex** - Correction de la logique pour les custom maps
40+
- Le code de la première lettre est maintenant inclus uniquement avec customMap
41+
- Tests corrigés pour Alfred/Olivier avec mappings français
42+
- Conversion String() pour les codes numériques
43+
844
## [1.0.1] - 2025-08-05
945

1046
### Added

README.md

Lines changed: 143 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,99 @@
22

33
[![npm version](https://img.shields.io/npm/v/algorith)](https://www.npmjs.com/package/algorith)
44
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5-
[![Tests](https://img.shields.io/badge/tests-114%20passing-brightgreen)](./test/)
5+
[![Tests](https://img.shields.io/badge/tests-115%20passing-brightgreen)](./test/)
66

77
> Collection complète d'algorithmes de similarité textuelle et moteur de génération aléatoire avancé
88
9+
## ✨ Fonctionnalités
10+
11+
### 🔍 Algorithmes de Similarité Textuelle
12+
- **Levenshtein** - Distance d'édition avec insertions, suppressions et substitutions
13+
- **Jaro-Winkler** - Optimisé pour les préfixes communs (noms propres)
14+
- **Jaro** - Version de base sans bonus de préfixe
15+
- **Hamming** - Comparaison caractère par caractère (même longueur)
16+
- **Jaccard** - Similarité basée sur les ensembles de caractères
17+
- **Cosine** - Similarité cosinus des vecteurs de fréquence
18+
- **Dice Coefficient** - Basé sur les bigrammes communs
19+
- **Trigram Score** - Score de similarité par trigrammes
20+
- **Soundex** - Encodage phonétique (support multilingue: EN, FR)
21+
22+
### 🎲 Génération Aléatoire (RandomEngine)
23+
#### Fonctions de Base
24+
- `uniform()` - Nombres aléatoires uniformes
25+
- `int()` - Entiers aléatoires dans un intervalle
26+
- `bool()` - Booléens aléatoires avec probabilité configurable
27+
- `pick()` - Sélection aléatoire d'un élément dans un tableau
28+
- `shuffle()` - Mélange Fisher-Yates d'un tableau
29+
30+
#### Distributions Probabilistes
31+
- `normal()` - Distribution normale (Gaussienne)
32+
- `exponential()` - Distribution exponentielle
33+
- `poisson()` - Distribution de Poisson
34+
- `binomial()` - Distribution binomiale
35+
- `geometric()` - Distribution géométrique
36+
- `weighted()` - Sélection pondérée
37+
38+
#### Génération de Texte
39+
- `randomChar()` - Caractères aléatoires (avec jeux de caractères personnalisés)
40+
- `randomString()` - Chaînes aléatoires de longueur donnée
41+
- `randomWord()` - Mots aléatoires basés sur des syllabes
42+
- `uuid()` - Génération d'UUID v4
43+
44+
#### Fonctions de Bruit
45+
- `perlin1D()`, `perlin2D()`, `perlin3D()` - Bruit de Perlin (1D, 2D, 3D)
46+
- `valueNoise()` - Bruit de valeur
47+
- `whiteNoise()` - Bruit blanc
48+
- `pinkNoise()` - Bruit rose (1/f)
49+
50+
#### Crypto Sécurisé
51+
- `cryptoInt()` - Entiers cryptographiquement sécurisés
52+
53+
### 🔤 Autocomplétion Intelligente
54+
- **Recherche rapide** - Structure Trie pour recherches O(m)
55+
- **Support multilingue** - Dictionnaires français et anglais intégrés
56+
- **Extensible** - Ajout facile de dictionnaires personnalisés
57+
- **API simple** - `autocomplete()`, `addWord()`, `addWords()`
58+
59+
### 🔧 Utilitaires
60+
- **fisherYatesShuffle** - Mélange aléatoire déterministe de tableaux
61+
- **compareAll** - Compare deux chaînes avec tous les algorithmes simultanément
62+
63+
## ⚡ Performance des Algorithmes
64+
65+
Benchmarks effectués sur Node.js v24.5.0 (Linux x64)
66+
67+
### Algorithmes de Similarité
68+
69+
| Algorithme | Petites chaînes<br>(3-5 car.) | Chaînes moyennes<br>(20-30 car.) | Grandes chaînes<br>(100-200 car.) |
70+
| ---------------- | ----------------------------- | -------------------------------- | --------------------------------- |
71+
| **Hamming** | **720,599 ops/s** | **535,742 ops/s** | **1,230,436 ops/s** |
72+
| **Jaro-Winkler** | **334,056 ops/s** | **492,129 ops/s** | **126,682 ops/s** |
73+
| **Jaro** | 159,534 ops/s | 300,080 ops/s | 119,637 ops/s |
74+
| **Trigram** | 171,536 ops/s | 337,487 ops/s | 170,423 ops/s |
75+
| **Dice** | 157,987 ops/s | 163,419 ops/s | 36,190 ops/s |
76+
| **Jaccard** | 119,827 ops/s | 121,730 ops/s | 73,290 ops/s |
77+
| **Cosine** | 95,908 ops/s | 120,913 ops/s | 59,148 ops/s |
78+
| **Levenshtein** | 33,657 ops/s | 42,996 ops/s | 12,548 ops/s |
79+
80+
**compareAll()** : 13,316 ops/s (compare avec tous les algorithmes simultanément)
81+
82+
### RandomEngine
83+
84+
| Fonction | Performance |
85+
| ------------------ | ---------------- |
86+
| `uniform()` | 12,330,231 ops/s |
87+
| `perlin1D()` | 22,104,201 ops/s |
88+
| `bool()` | 16,819,989 ops/s |
89+
| `whiteNoise()` | 16,051,877 ops/s |
90+
| `int(1, 100)` | 14,266,552 ops/s |
91+
| `exponential(1)` | 6,782,895 ops/s |
92+
| `normal(0, 1)` | 4,002,269 ops/s |
93+
| `randomWord(5)` | 559,416 ops/s |
94+
| `randomString(10)` | 287,464 ops/s |
95+
96+
> **Note** : Les performances peuvent varier selon votre environnement d'exécution.
97+
998
## 📦 Installation
1099

11100
```bash
@@ -21,7 +110,8 @@ const {
21110
hamming,
22111
compareAll,
23112
RandomEngine,
24-
AutocompleteEngine
113+
AutocompleteEngine,
114+
fisherYatesShuffle
25115
} = require('algorith');
26116

27117
// Comparaison de similarité
@@ -53,6 +143,11 @@ console.log(rng.randomWord()); // "bakaru"
53143
const autocomplete = new AutocompleteEngine({ language: 'fr' });
54144
autocomplete.addWords(['javascript', 'java', 'python']);
55145
console.log(autocomplete.autocomplete('java')); // ['java', 'javascript']
146+
147+
// Mélange Fisher-Yates
148+
const numbers = [1, 2, 3, 4, 5];
149+
const shuffled = fisherYatesShuffle(numbers);
150+
console.log(shuffled); // [3, 1, 5, 2, 4]
56151
```
57152

58153
## 📚 API Documentation
@@ -170,20 +265,48 @@ trigramScore('abc', 'xyz'); // 0.0
170265

171266
**Cas d'usage :** Analyse de séquences, comparaison de texte long.
172267

173-
#### `soundex(string)`
268+
#### `soundex(string, language = 'en', customMap = null)`
174269

175-
Génère le code Soundex d'une chaîne (algorithme phonétique).
270+
Génère le code Soundex d'une chaîne (algorithme phonétique) avec support multilingue.
271+
272+
**Paramètres :**
273+
- `string` : La chaîne à encoder
274+
- `language` : Langue pour les règles spécifiques ('en' ou 'fr', défaut: 'en')
275+
- `customMap` : Carte de correspondance personnalisée (optionnel)
176276

177277
```javascript
178278
const { soundex } = require('algorith');
179279

280+
// Usage basique (anglais par défaut)
180281
soundex('Robert'); // 'R163'
181282
soundex('Rupert'); // 'R163' (même son)
182283
soundex('Smith'); // 'S530'
183284
soundex('Smyth'); // 'S530' (même son)
285+
286+
// Support français avec normalisation des accents
287+
soundex('François', 'fr'); // 'F652'
288+
soundex('Pierre', 'fr'); // 'P600'
289+
soundex('Céline', 'fr'); // 'C450'
290+
291+
// Les accents sont automatiquement normalisés en français
292+
soundex('François', 'fr') === soundex('Francois', 'fr'); // true
293+
294+
// Carte personnalisée
295+
const customMap = {
296+
a: '', e: '', i: '', o: '', u: '',
297+
b: 9, p: 9, f: 9, v: 9, // Groupement personnalisé
298+
c: 8, k: 8, g: 8
299+
};
300+
soundex('Boat', 'en', customMap); // 'B900'
184301
```
185302

186-
**Cas d'usage :** Recherche phonétique, matching de noms.
303+
**Fonctionnalités :**
304+
- **Support multilingue** : Règles spécifiques pour l'anglais et le français
305+
- **Normalisation française** : Gestion automatique des accents (é→e, ç→s, œ→e)
306+
- **Cartes personnalisées** : Définition de vos propres règles de correspondance
307+
- **Compatibilité** : Fonctionne avec l'algorithme Soundex standard
308+
309+
**Cas d'usage :** Recherche phonétique, matching de noms, détection de doublons phonétiques, indexation par similarité sonore.
187310

188311
#### `compareAll(stringA, stringB)`
189312

@@ -486,6 +609,20 @@ rng.fade(0.5); // Fonction de lissage
486609
rng.lerp(0, 10, 0.5); // Interpolation linéaire → 5
487610
```
488611

612+
### 🔀 Mélange Fisher-Yates
613+
614+
Mélange un tableau en utilisant l'algorithme de Fisher-Yates.
615+
616+
```javascript
617+
const { fisherYatesShuffle } = require('algorith');
618+
619+
const items = ['a', 'b', 'c', 'd'];
620+
const shuffled = fisherYatesShuffle(items);
621+
622+
console.log(items); // ['a', 'b', 'c', 'd'] (non modifié)
623+
console.log(shuffled); // Mélange aléatoire
624+
```
625+
489626
## 🎯 Exemples d'Usage
490627

491628
### Détection de Doublons
@@ -579,7 +716,7 @@ const map = generateTerrain(100, 100);
579716

580717
## 🧪 Tests
581718

582-
Le module inclut 114 tests complets :
719+
Le module inclut 115 tests complets :
583720

584721
```bash
585722
# Exécuter tous les tests

algorithms/fisherYatesShuffle.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
module.exports = function fisherYatesShuffle(array, random = Math.random) {
2+
const result = array.slice();
3+
4+
for (let i = result.length - 1; i > 0; i--) {
5+
const j = Math.floor(random() * (i + 1));
6+
[result[i], result[j]] = [result[j], result[i]];
7+
}
8+
9+
return result;
10+
};

0 commit comments

Comments
 (0)