Skip to content
Merged

Dev #11

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 134 additions & 0 deletions .github/workflows/pr-validation.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
name: 🔍 PR Title Validation

on:
pull_request:
types: [opened, edited, synchronize]

jobs:
validate-title:
name: 📋 Validate PR Title Format
runs-on: ubuntu-latest

steps:
- name: 📥 Checkout Code
uses: actions/checkout@v4

- name: 🔍 Validate PR Title
env:
PR_TITLE: ${{ github.event.pull_request.title }}
run: |
echo "🔍 Validating PR title: '$PR_TITLE'"

# Pattern pour les conventions de commit
# Format: type(scope): description
if [[ "$PR_TITLE" =~ ^(feat|fix|docs|style|refactor|test|chore)(\([a-z0-9-]+\))?: .{1,50}$ ]]; then
Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR title "Dev" does not follow the conventional commit format that the newly added PR validation workflow enforces. According to the workflow validation regex on line 24, PR titles must follow the format "type(scope): description" (e.g., "feat(soundex): add multilingual support"). This PR will fail its own validation workflow.

Copilot uses AI. Check for mistakes.
echo "✅ PR title follows conventional format"
echo "## ✅ PR Title Validation" >> $GITHUB_STEP_SUMMARY
echo "Le titre de la PR suit les conventions du projet:" >> $GITHUB_STEP_SUMMARY
echo "\`$PR_TITLE\`" >> $GITHUB_STEP_SUMMARY
else
echo "❌ PR title should follow format: type(scope): description"
echo "Current title: $PR_TITLE"
echo ""
echo "Examples:"
echo " feat(autocomplete): add new autocompletion engine"
echo " fix(similarity): correct Levenshtein calculation"
echo " docs(readme): update API documentation"
echo ""
echo "Valid types: feat, fix, docs, style, refactor, test, chore"

# Ajouter au résumé GitHub
echo "## ❌ PR Title Validation Failed" >> $GITHUB_STEP_SUMMARY
echo "Le titre de la PR ne suit pas les conventions:" >> $GITHUB_STEP_SUMMARY
echo "\`$PR_TITLE\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 📋 Format attendu:" >> $GITHUB_STEP_SUMMARY
echo "\`type(scope): description\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### ✅ Exemples valides:" >> $GITHUB_STEP_SUMMARY
echo "- \`feat(autocomplete): add new autocompletion engine\`" >> $GITHUB_STEP_SUMMARY
echo "- \`fix(similarity): correct Levenshtein calculation\`" >> $GITHUB_STEP_SUMMARY
echo "- \`docs(readme): update API documentation\`" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### 🔧 Types valides:" >> $GITHUB_STEP_SUMMARY
echo "\`feat\`, \`fix\`, \`docs\`, \`style\`, \`refactor\`, \`test\`, \`chore\`" >> $GITHUB_STEP_SUMMARY

exit 1
fi

suggest-labels:
name: 🏷️ Suggest PR Labels
runs-on: ubuntu-latest
needs: validate-title
if: success()

steps:
- name: 🏷️ Analyze PR and Suggest Labels
env:
PR_TITLE: ${{ github.event.pull_request.title }}
PR_BODY: ${{ github.event.pull_request.body }}
run: |
echo "🏷️ Analyzing PR for label suggestions..."
echo "## 🏷️ Suggested Labels" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY

# Extraire le type du titre
if [[ "$PR_TITLE" =~ ^(feat|fix|docs|style|refactor|test|chore) ]]; then
TYPE="${BASH_REMATCH[1]}"
echo "📌 Type: \`$TYPE\`" >> $GITHUB_STEP_SUMMARY

case $TYPE in
"feat")
echo "- \`enhancement\`" >> $GITHUB_STEP_SUMMARY
echo "- \`feature\`" >> $GITHUB_STEP_SUMMARY
;;
"fix")
echo "- \`bug\`" >> $GITHUB_STEP_SUMMARY
echo "- \`fix\`" >> $GITHUB_STEP_SUMMARY
;;
"docs")
echo "- \`documentation\`" >> $GITHUB_STEP_SUMMARY
;;
"test")
echo "- \`testing\`" >> $GITHUB_STEP_SUMMARY
;;
"refactor")
echo "- \`refactoring\`" >> $GITHUB_STEP_SUMMARY
;;
"style")
echo "- \`style\`" >> $GITHUB_STEP_SUMMARY
;;
"chore")
echo "- \`maintenance\`" >> $GITHUB_STEP_SUMMARY
;;
esac
fi

# Extraire le scope du titre
if [[ "$PR_TITLE" =~ \(([a-z0-9-]+)\) ]]; then
SCOPE="${BASH_REMATCH[1]}"
echo "🎯 Scope: \`$SCOPE\`" >> $GITHUB_STEP_SUMMARY
echo "- \`$SCOPE\`" >> $GITHUB_STEP_SUMMARY
fi

# Analyser le contenu pour des labels supplémentaires
CONTENT="$PR_TITLE $PR_BODY"

if [[ $CONTENT =~ (test|testing|unit.test|integration.test) ]]; then
echo "- \`testing\`" >> $GITHUB_STEP_SUMMARY
fi

if [[ $CONTENT =~ (performance|benchmark|optimization|faster) ]]; then
echo "- \`performance\`" >> $GITHUB_STEP_SUMMARY
fi

if [[ $CONTENT =~ (breaking.change|breaking|major) ]]; then
echo "- \`breaking-change\`" >> $GITHUB_STEP_SUMMARY
fi

if [[ $CONTENT =~ (security|vulnerability|CVE) ]]; then
echo "- \`security\`" >> $GITHUB_STEP_SUMMARY
fi

echo "" >> $GITHUB_STEP_SUMMARY
echo "💡 **Note**: Les labels doivent être ajoutés manuellement par un maintainer ayant les permissions appropriées." >> $GITHUB_STEP_SUMMARY
36 changes: 36 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,42 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [1.0.2] - 2026-01-09

### Added
#### Algorithmes et Utilitaires
- **Fisher-Yates Shuffle** - Algorithme de mélange aléatoire déterministe de tableaux
- Fonction standalone `fisherYatesShuffle()` exportée
- Support des générateurs aléatoires personnalisés (RNG)
- Tests unitaires complets avec validation du déterminisme
- Définitions TypeScript complètes

#### Améliorations Soundex
- **Support des cartes personnalisées** - Possibilité de passer des mappings de caractères personnalisés
- Paramètre `customMap` pour définir des encodages phonétiques spécifiques
- Priorité donnée aux custom maps sur les maps de langue
- Tests de validation des mappings personnalisés
- **Support multilingue étendu** - Amélioration de la normalisation pour le français
- Normalisation des caractères accentués (é, è, ê, à, ù, etc.)
- Gestion du ç → s et œ → e
- Mappings spécifiques français (F et V → 7 au lieu de 1)
- Tests pour tous les cas de normalisation

### Enhanced
- **Documentation README**
- Ajout d'un tableau de performance pour tous les algorithmes
- Section "Fonctionnalités" complète avec toutes les capacités de la bibliothèque
- Benchmarks détaillés (ops/s) pour petites, moyennes et grandes chaînes
- Performance du RandomEngine avec toutes ses fonctions
- **Tests unitaires** - 152 tests passant (amélioration de la couverture)
Copy link

Copilot AI Jan 8, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The CHANGELOG states "152 tests passant" but the README badge and text indicate "115 passing". These test counts should be consistent across all documentation.

Suggested change
- **Tests unitaires** - 152 tests passant (amélioration de la couverture)
- **Tests unitaires** - amélioration de la couverture de tests

Copilot uses AI. Check for mistakes.
- **TypeScript** - Définitions mises à jour pour fisherYatesShuffle et Soundex

### Fixed
- **Soundex** - Correction de la logique pour les custom maps
- Le code de la première lettre est maintenant inclus uniquement avec customMap
- Tests corrigés pour Alfred/Olivier avec mappings français
- Conversion String() pour les codes numériques

## [1.0.1] - 2025-08-05

### Added
Expand Down
149 changes: 143 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,99 @@

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

> Collection complète d'algorithmes de similarité textuelle et moteur de génération aléatoire avancé

## ✨ Fonctionnalités

### 🔍 Algorithmes de Similarité Textuelle
- **Levenshtein** - Distance d'édition avec insertions, suppressions et substitutions
- **Jaro-Winkler** - Optimisé pour les préfixes communs (noms propres)
- **Jaro** - Version de base sans bonus de préfixe
- **Hamming** - Comparaison caractère par caractère (même longueur)
- **Jaccard** - Similarité basée sur les ensembles de caractères
- **Cosine** - Similarité cosinus des vecteurs de fréquence
- **Dice Coefficient** - Basé sur les bigrammes communs
- **Trigram Score** - Score de similarité par trigrammes
- **Soundex** - Encodage phonétique (support multilingue: EN, FR)

### 🎲 Génération Aléatoire (RandomEngine)
#### Fonctions de Base
- `uniform()` - Nombres aléatoires uniformes
- `int()` - Entiers aléatoires dans un intervalle
- `bool()` - Booléens aléatoires avec probabilité configurable
- `pick()` - Sélection aléatoire d'un élément dans un tableau
- `shuffle()` - Mélange Fisher-Yates d'un tableau

#### Distributions Probabilistes
- `normal()` - Distribution normale (Gaussienne)
- `exponential()` - Distribution exponentielle
- `poisson()` - Distribution de Poisson
- `binomial()` - Distribution binomiale
- `geometric()` - Distribution géométrique
- `weighted()` - Sélection pondérée

#### Génération de Texte
- `randomChar()` - Caractères aléatoires (avec jeux de caractères personnalisés)
- `randomString()` - Chaînes aléatoires de longueur donnée
- `randomWord()` - Mots aléatoires basés sur des syllabes
- `uuid()` - Génération d'UUID v4

#### Fonctions de Bruit
- `perlin1D()`, `perlin2D()`, `perlin3D()` - Bruit de Perlin (1D, 2D, 3D)
- `valueNoise()` - Bruit de valeur
- `whiteNoise()` - Bruit blanc
- `pinkNoise()` - Bruit rose (1/f)

#### Crypto Sécurisé
- `cryptoInt()` - Entiers cryptographiquement sécurisés

### 🔤 Autocomplétion Intelligente
- **Recherche rapide** - Structure Trie pour recherches O(m)
- **Support multilingue** - Dictionnaires français et anglais intégrés
- **Extensible** - Ajout facile de dictionnaires personnalisés
- **API simple** - `autocomplete()`, `addWord()`, `addWords()`

### 🔧 Utilitaires
- **fisherYatesShuffle** - Mélange aléatoire déterministe de tableaux
- **compareAll** - Compare deux chaînes avec tous les algorithmes simultanément

## ⚡ Performance des Algorithmes

Benchmarks effectués sur Node.js v24.5.0 (Linux x64)

### Algorithmes de Similarité

| Algorithme | Petites chaînes<br>(3-5 car.) | Chaînes moyennes<br>(20-30 car.) | Grandes chaînes<br>(100-200 car.) |
| ---------------- | ----------------------------- | -------------------------------- | --------------------------------- |
| **Hamming** | **720,599 ops/s** | **535,742 ops/s** | **1,230,436 ops/s** |
| **Jaro-Winkler** | **334,056 ops/s** | **492,129 ops/s** | **126,682 ops/s** |
| **Jaro** | 159,534 ops/s | 300,080 ops/s | 119,637 ops/s |
| **Trigram** | 171,536 ops/s | 337,487 ops/s | 170,423 ops/s |
| **Dice** | 157,987 ops/s | 163,419 ops/s | 36,190 ops/s |
| **Jaccard** | 119,827 ops/s | 121,730 ops/s | 73,290 ops/s |
| **Cosine** | 95,908 ops/s | 120,913 ops/s | 59,148 ops/s |
| **Levenshtein** | 33,657 ops/s | 42,996 ops/s | 12,548 ops/s |

**compareAll()** : 13,316 ops/s (compare avec tous les algorithmes simultanément)

### RandomEngine

| Fonction | Performance |
| ------------------ | ---------------- |
| `uniform()` | 12,330,231 ops/s |
| `perlin1D()` | 22,104,201 ops/s |
| `bool()` | 16,819,989 ops/s |
| `whiteNoise()` | 16,051,877 ops/s |
| `int(1, 100)` | 14,266,552 ops/s |
| `exponential(1)` | 6,782,895 ops/s |
| `normal(0, 1)` | 4,002,269 ops/s |
| `randomWord(5)` | 559,416 ops/s |
| `randomString(10)` | 287,464 ops/s |

> **Note** : Les performances peuvent varier selon votre environnement d'exécution.

## 📦 Installation

```bash
Expand All @@ -21,7 +110,8 @@ const {
hamming,
compareAll,
RandomEngine,
AutocompleteEngine
AutocompleteEngine,
fisherYatesShuffle
} = require('algorith');

// Comparaison de similarité
Expand Down Expand Up @@ -53,6 +143,11 @@ console.log(rng.randomWord()); // "bakaru"
const autocomplete = new AutocompleteEngine({ language: 'fr' });
autocomplete.addWords(['javascript', 'java', 'python']);
console.log(autocomplete.autocomplete('java')); // ['java', 'javascript']

// Mélange Fisher-Yates
const numbers = [1, 2, 3, 4, 5];
const shuffled = fisherYatesShuffle(numbers);
console.log(shuffled); // [3, 1, 5, 2, 4]
```

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

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

#### `soundex(string)`
#### `soundex(string, language = 'en', customMap = null)`

Génère le code Soundex d'une chaîne (algorithme phonétique).
Génère le code Soundex d'une chaîne (algorithme phonétique) avec support multilingue.

**Paramètres :**
- `string` : La chaîne à encoder
- `language` : Langue pour les règles spécifiques ('en' ou 'fr', défaut: 'en')
- `customMap` : Carte de correspondance personnalisée (optionnel)

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

// Usage basique (anglais par défaut)
soundex('Robert'); // 'R163'
soundex('Rupert'); // 'R163' (même son)
soundex('Smith'); // 'S530'
soundex('Smyth'); // 'S530' (même son)

// Support français avec normalisation des accents
soundex('François', 'fr'); // 'F652'
soundex('Pierre', 'fr'); // 'P600'
soundex('Céline', 'fr'); // 'C450'

// Les accents sont automatiquement normalisés en français
soundex('François', 'fr') === soundex('Francois', 'fr'); // true

// Carte personnalisée
const customMap = {
a: '', e: '', i: '', o: '', u: '',
b: 9, p: 9, f: 9, v: 9, // Groupement personnalisé
c: 8, k: 8, g: 8
};
soundex('Boat', 'en', customMap); // 'B900'
```

**Cas d'usage :** Recherche phonétique, matching de noms.
**Fonctionnalités :**
- **Support multilingue** : Règles spécifiques pour l'anglais et le français
- **Normalisation française** : Gestion automatique des accents (é→e, ç→s, œ→e)
- **Cartes personnalisées** : Définition de vos propres règles de correspondance
- **Compatibilité** : Fonctionne avec l'algorithme Soundex standard

**Cas d'usage :** Recherche phonétique, matching de noms, détection de doublons phonétiques, indexation par similarité sonore.

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

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

### 🔀 Mélange Fisher-Yates

Mélange un tableau en utilisant l'algorithme de Fisher-Yates.

```javascript
const { fisherYatesShuffle } = require('algorith');

const items = ['a', 'b', 'c', 'd'];
const shuffled = fisherYatesShuffle(items);

console.log(items); // ['a', 'b', 'c', 'd'] (non modifié)
console.log(shuffled); // Mélange aléatoire
```

## 🎯 Exemples d'Usage

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

## 🧪 Tests

Le module inclut 114 tests complets :
Le module inclut 115 tests complets :

```bash
# Exécuter tous les tests
Expand Down
10 changes: 10 additions & 0 deletions algorithms/fisherYatesShuffle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module.exports = function fisherYatesShuffle(array, random = Math.random) {
const result = array.slice();

for (let i = result.length - 1; i > 0; i--) {
const j = Math.floor(random() * (i + 1));
[result[i], result[j]] = [result[j], result[i]];
}

return result;
};
Loading
Loading