diff --git a/.gitignore b/.gitignore
index e8eadbd..af079b4 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,2 @@
 __pycache__/
-*.py
\ No newline at end of file
+test*.*
\ No newline at end of file
diff --git a/Grille.php b/Grille.php
index 169824d..0f50ac4 100644
--- a/Grille.php
+++ b/Grille.php
@@ -3,6 +3,14 @@
 include_once "dico.php";
 
 
+function melanger_cles($tableau) {
+    uksort($tableau, function($a, $b) {
+        return mt_rand(-1, 1);
+    });
+    return $tableau;
+}
+
+
 class Grille
 {
     public $grille;
@@ -19,25 +27,21 @@ class Grille
         $this->largeur = $largeur;
         $this->grille = array_fill(0, $hauteur, array_fill(0, $largeur, ''));
 
-        if ($id == "") {
-            mt_srand();
-        } else {
-            mt_srand(crc32($id));
-        }
         $this->lettres_suivantes = [];
         foreach ($hauteur == $largeur ? [$hauteur] : [$hauteur, $largeur] as $longueur) {
             $this->lettres_suivantes[$longueur] = [];
             foreach (mots_espaces($longueur) as $mot) {
-                for ($i = 0; $i <= $longueur; $i++) {
-                    $debut = substr($mot, 0, $i);
-                    if (!isset($this->lettres_suivantes[$longueur][$debut])) {
-                        $this->lettres_suivantes[$longueur][$debut] = [];
+                $ref = &$this->lettres_suivantes[$longueur];
+                for ($i = 0; $i < $longueur; $i++) {
+                    $lettre = $mot[$i];
+                    if (!isset($ref[$lettre])) {
+                        $ref[$lettre] = [];
                     }
-                    $this->lettres_suivantes[$longueur][$debut][substr($mot, $i, 1)] = true;
+                    $ref = &$ref[$lettre];
                 }
+                $ref = [];
             }
         }
-        mt_srand();
 
         $this->positions = [];
         for ($y = 0; $y < $hauteur; $y++) {
@@ -47,7 +51,7 @@ class Grille
         }
         $this->nb_positions = count($this->positions);
 
-        $this->grilles = $this->generateur();
+        $this->grilles = $this->generateur($id);
     }
 
     public function get_ligne($y, $largeur)
@@ -68,15 +72,18 @@ class Grille
         return $colonne;
     }
 
-    public function generateur()
+    public function generateur($id = "")
     {
+        mt_srand($id == ""? null : crc32($id));
+        
         $mots_utilises = [];
         $pile = [];
-        $lettres_possibles = array_intersect_assoc(
-            $this->lettres_suivantes[$this->largeur][""],
-            $this->lettres_suivantes[$this->hauteur][""]
-        );
-        foreach ($lettres_possibles as $lettre => $_) {
+
+        $lettres_communes = melanger_cles(array_intersect_key(
+            $this->lettres_suivantes[$this->largeur],
+            $this->lettres_suivantes[$this->hauteur]
+        ));
+        foreach ($lettres_communes as $lettre => $_) {
             $pile[] = [0, $lettre];
         }
 
@@ -85,6 +92,11 @@ class Grille
             [$x, $y] = $this->positions[$i];
             $this->grille[$y][$x] = $lettre;
 
+            if ($i == $this->nb_positions - 1) {
+                yield $this;
+                continue;
+            }
+
             if ($x == $this->largeur - 1) {
                 $mots_utilises[$y] = $this->get_ligne($y, $x);
             } else {
@@ -97,18 +109,23 @@ class Grille
             }
 
             $i++;
-            if ($i == $this->nb_positions) {
-                yield $this;
-                continue;
+            [$x, $y] = $this->positions[$i];
+            $lettres_suivantes_ligne = $this->lettres_suivantes[$this->largeur];
+            for ($x2 = 0; $x2 < $x; $x2++) {
+                $lettres_suivantes_ligne = $lettres_suivantes_ligne[$this->grille[$y][$x2]];
             }
 
-            [$x, $y] = $this->positions[$i];
-            $lettres_possibles = array_intersect_assoc(
-                $this->lettres_suivantes[$this->largeur][$this->get_ligne($y, $x)],
-                $this->lettres_suivantes[$this->hauteur][$this->get_colonne($x, $y)]
-            );
-            foreach ($lettres_possibles as $lettre => $_) {
-                $pile[] = [$i, $lettre];
+            $lettres_suivantes_colonne = $this->lettres_suivantes[$this->hauteur];
+            for ($y2 = 0; $y2 < $y; $y2++) {
+                $lettres_suivantes_colonne = $lettres_suivantes_colonne[$this->grille[$y2][$x]];
+            }
+            
+            $lettres_communes = melanger_cles(array_intersect_key(
+                $lettres_suivantes_ligne,
+                $lettres_suivantes_colonne
+            ));
+            foreach ($lettres_communes as $lettre => $_) {
+                $pile[] = [$i, $lettre, $lettres_suivantes_ligne[$lettre]];
             }
         }
     }
diff --git a/dico.csv b/dico.csv
index bd0b733..80ade53 100644
--- a/dico.csv
+++ b/dico.csv
@@ -2339,8 +2339,8 @@ TROTTEUSE	Elle va plus vite que les deux autres, mais toujours à son rythme.	Th
 TROUILLOMETRE	Il est souvent à zéro.	Jean-Paul Vanden Branden
 TROUSSEES	Les poules le sont différemment des cocottes.	Georges Pérec
 TSAR	Le dernier vit rouge	
-TSETSE	Ses victimes lui doivent des sommes considérables.	Pangloss
-TSETSE	C'est quand elle a fini de voler qu'elle se met à piquer.	Lucien Lacau
+TSE TSE	Ses victimes lui doivent des sommes considérables.	Pangloss
+TSE TSE	C'est quand elle a fini de voler qu'elle se met à piquer.	Lucien Lacau
 TSF	Pour en avoir des nouvelles, il fallait d'abord la mettre au courant.	Michel Laclos
 TU	Familier et secret.	Dédale
 TU	Entre proches ou même pas aux proches.	Jean Teularge
@@ -3384,7 +3384,6 @@ VOLTAIRE	Célèbre par son « rictus » épouvantable.	Gustave Flaubert
 VOLTAIRE	Science superficielle.	Gustave Flaubert
 VOYAGE	Doit être fait rapidement.	Gustave Flaubert
 WAGNER	Ricaner quand on entend son nom, et faire des plaisanteries sur la musique de l’avenir.	Gustave Flaubert
-YVETOT	Voir Yvetot et mourir.	Gustave Flaubert
 CAMBRONNE	Il ne mâchait pas ses mots. Heureusement pour lui.<em>Jean Yanne</em>	
 WATERLOO	Morne plaine !	Victor Hugo
 GARDE	Meurt mais ne se rend pas.<em>Cambronne</em>	
diff --git a/dico.php b/dico.php
index 2fa2df5..841bedb 100644
--- a/dico.php
+++ b/dico.php
@@ -3,7 +3,6 @@
 
 const MIN_LETTRES_MOT_1 = 2;
 const MIN_LETTRES_MOT_2 = 1;
-const MAX_MOTS = 100000;
 
 $dico = [];
 if (($lecteur = fopen("dico.csv", "r")) !== FALSE) {
@@ -38,28 +37,14 @@ foreach ($dico as $mot => $definition) {
     $mots_de_n_lettres[$n][] = $mot;
 }
 
-function fisherYatesShuffle(&$items)
-{
-    for ($i = count($items) - 1; $i > 0; $i--) {
-        $j = mt_rand(0, $i);
-        $tmp = $items[$i];
-        $items[$i] = $items[$j];
-        $items[$j] = $tmp;
-    }
-}
-
 function mots_espaces($longueur)
 {
     global $mots_de_n_lettres;
     global $dico;
 
     $nb_mots = 0;
-    fisherYatesShuffle($mots_de_n_lettres[$longueur]);
     foreach ($mots_de_n_lettres[$longueur] as $mot) {
         yield $mot;
-        if (++$nb_mots >= MAX_MOTS) {
-            return;
-        }
     }
     for ($i = MIN_LETTRES_MOT_1; $longueur - $i - 1 >= MIN_LETTRES_MOT_2; $i++) {
         foreach ($mots_de_n_lettres[$i] as $mot1) {
@@ -67,14 +52,8 @@ function mots_espaces($longueur)
                 if ($mot1 != $mot2) {
                     $dico["$mot1 $mot2"] = array_merge($dico[$mot1], $dico[$mot2]);
                     yield "$mot1 $mot2";
-                    if (++$nb_mots >= MAX_MOTS) {
-                        return;
-                    }
                     $dico["$mot2 $mot1"] = array_merge($dico[$mot2], $dico[$mot1]);
                     yield "$mot2 $mot1";
-                    if (++$nb_mots >= MAX_MOTS) {
-                        return;
-                    }
                 }
             }
         }
diff --git a/index.php b/index.php
index 07ab631..c5df204 100644
--- a/index.php
+++ b/index.php
@@ -16,8 +16,8 @@ include_once "dico.php";
 include_once "Grille.php";
 
 
+const LARGEUR_PAR_DEFAUT = 7;
 const HAUTEUR_PAR_DEFAUT = 6;
-const LARGEUR_PAR_DEFAUT = 6;
 
 
 $hauteur = filter_input(INPUT_GET, 'lignes', FILTER_VALIDATE_INT, [
@@ -97,7 +97,7 @@ $grille->current();
                                 <?php if ($grille->grille[$y][$x] == " "): ?>
                                     <input type="text" maxlength="1" size="1" value=" " disabled />
                                 <?php else: ?>
-                                    <input type="text" maxlength="1" size="1" pattern="[A-Z]" />
+                                    <input type="text" maxlength="1" size="1" pattern="[A-Z]"/>
                                 <?php endif; ?>
                             </td>
                         <?php endfor; ?>
diff --git a/style.css b/style.css
index 22d4e88..7eea8a1 100644
--- a/style.css
+++ b/style.css
@@ -7,7 +7,7 @@ body {
 
 form {
     padding: 1rem;
-    height: calc(100vh - 2rem);
+    min-height: calc(100vh - 2rem);
     display: flex;
     flex-flow: column;
     justify-content: space-evenly;