pile à la place de la récursion

This commit is contained in:
Adrien MALINGREY 2025-04-29 17:47:45 +02:00
parent 1416b8bd54
commit 88d95e42ad
4 changed files with 60 additions and 204 deletions

View File

@ -3,7 +3,8 @@
include_once "dico.php"; include_once "dico.php";
class Grille { class Grille
{
public $grille; public $grille;
public $hauteur; public $hauteur;
public $largeur; public $largeur;
@ -11,9 +12,9 @@ class Grille {
private $lettres_suivantes; private $lettres_suivantes;
private $positions; private $positions;
private $nb_positions; private $nb_positions;
private $mots_utilises = [];
public function __construct($hauteur, $largeur, $id="") { public function __construct($hauteur, $largeur, $id = "")
{
$this->hauteur = $hauteur; $this->hauteur = $hauteur;
$this->largeur = $largeur; $this->largeur = $largeur;
$this->grille = array_fill(0, $hauteur, array_fill(0, $largeur, '')); $this->grille = array_fill(0, $hauteur, array_fill(0, $largeur, ''));
@ -49,7 +50,8 @@ class Grille {
$this->grilles = $this->generateur(); $this->grilles = $this->generateur();
} }
public function get_ligne($y, $largeur) { public function get_ligne($y, $largeur)
{
$ligne = ""; $ligne = "";
for ($x = 0; $x < $largeur; $x++) { for ($x = 0; $x < $largeur; $x++) {
$ligne .= $this->grille[$y][$x]; $ligne .= $this->grille[$y][$x];
@ -57,7 +59,8 @@ class Grille {
return $ligne; return $ligne;
} }
public function get_colonne($x, $hauteur) { public function get_colonne($x, $hauteur)
{
$colonne = ""; $colonne = "";
for ($y = 0; $y < $hauteur; $y++) { for ($y = 0; $y < $hauteur; $y++) {
$colonne .= $this->grille[$y][$x]; $colonne .= $this->grille[$y][$x];
@ -65,61 +68,63 @@ class Grille {
return $colonne; return $colonne;
} }
public function generateur($index=0) { public function generateur()
if ($index == $this->nb_positions) { {
yield $this; $mots_utilises = [];
return; $pile = [];
$lettres_possibles = array_intersect_assoc(
$this->lettres_suivantes[$this->largeur][""],
$this->lettres_suivantes[$this->hauteur][""]
);
foreach ($lettres_possibles as $lettre => $_) {
$pile[] = [0, $lettre];
} }
[$x, $y] = $this->positions[$index]; while (!empty($pile)) {
[$i, $lettre] = array_pop($pile);
[$x, $y] = $this->positions[$i];
$this->grille[$y][$x] = $lettre;
if ($x == $this->largeur - 1) {
$mots_utilises[$y] = $this->get_ligne($y, $x);
} else {
unset($mots_utilises[$y]);
}
if ($y == $this->hauteur - 1) {
if (in_array($this->get_colonne($x, $y), $mots_utilises)) {
continue;
}
}
$i++;
if ($i == $this->nb_positions) {
yield $this;
continue;
}
[$x, $y] = $this->positions[$i];
$lettres_possibles = array_intersect_assoc( $lettres_possibles = array_intersect_assoc(
$this->lettres_suivantes[$this->largeur][$this->get_ligne($y, $x)], $this->lettres_suivantes[$this->largeur][$this->get_ligne($y, $x)],
$this->lettres_suivantes[$this->hauteur][$this->get_colonne($x, $y)] $this->lettres_suivantes[$this->hauteur][$this->get_colonne($x, $y)]
); );
foreach ($lettres_possibles as $lettre => $_) { foreach ($lettres_possibles as $lettre => $_) {
$this->grille[$y][$x] = $lettre; $pile[] = [$i, $lettre];
$mot_ligne = NULL;
if ($x == $this->largeur - 1) {
$mot_ligne = $this->get_ligne($y, $x);
if (isset($this->mots_utilises[$mot_ligne])) {
continue;
} else {
$this-> mots_utilises[$mot_ligne] = true;
}
}
$mot_colonne = NULL;
if ($y == $this->hauteur - 1) {
$mot_colonne = $this->get_colonne($x, $y);
if (isset($this->mots_utilises[$mot_colonne])) {
continue;
} else {
$this-> mots_utilises[$mot_colonne] = true;
}
}
yield from $this->generateur($index + 1);
if ($mot_ligne) {
unset($this-> mots_utilises[$mot_ligne]);
}
if ($mot_colonne) {
unset($this-> mots_utilises[$mot_colonne]);
} }
} }
} }
public function current() { public function current()
{
return $this->grilles->current(); return $this->grilles->current();
} }
public function valid() { public function valid()
{
return $this->grilles->valid(); return $this->grilles->valid();
} }
public function hash() { public function hash()
{
$string = ""; $string = "";
foreach ($this->grille as $ligne) { foreach ($this->grille as $ligne) {
$string .= implode("", $ligne); $string .= implode("", $ligne);

View File

@ -1,149 +0,0 @@
<?php
include_once "dico.php";
class Grille {
public $grille;
public $hauteur;
public $largeur;
private $grilles;
private $debuts;
private $mots_utilises = [];
public function __construct($hauteur, $largeur, $id="") {
$this->hauteur = $hauteur;
$this->largeur = $largeur;
$this->grille = array_fill(0, $hauteur, array_fill(0, $largeur, '.'));
if ($id == "") {
mt_srand();
} else {
mt_srand(crc32($id));
}
$this->debuts = [];
foreach ($hauteur == $largeur? [$hauteur]: [$hauteur, $largeur] as $longueur) {
$this->debuts[$longueur] = [];
foreach(mots_espaces($longueur) as $mot) {
for ($i = 0; $i <= $longueur; $i++) {
$debut = substr($mot, 0, $i);
if (!isset($this->debuts[$longueur][$debut])) {
$this->debuts[$longueur][$debut] = [];
}
$this->debuts[$longueur][$debut][] = $mot;
}
}
}
mt_srand();
$this->grilles = $this->generateur();
}
public function get_ligne($y, $largeur) {
$ligne = "";
for ($x = 0; $x < $largeur; $x++) {
$ligne .= $this->grille[$y][$x];
}
return $ligne;
}
public function set_ligne($y, $mot) {
for ($i = 0; $i < strlen($mot); $i++) {
$this->grille[$y][$i] = $mot[$i];
}
}
public function get_colonne($x, $hauteur) {
$colonne = "";
for ($y = 0; $y < $hauteur; $y++) {
$colonne .= $this->grille[$y][$x];
}
return $colonne;
}
public function set_colonne($x, $mot) {
for ($i = 0; $i < strlen($mot); $i++) {
$this->grille[$i][$x] = $mot[$i];
}
}
public function generateur() {
yield from $this->trouve_une_ligne(0);
$this->grille = array_fill(0, $this->hauteur, array_fill(0, $this->largeur, ' '));
}
private function trouve_une_ligne($y) {
global $mots_de_n_lettres;
$largeur = min($y, $this->largeur);
$hauteur = min($y + 1, $this->hauteur);
foreach ($this->debuts[$this->largeur][$this->get_ligne($y, $largeur)] as $mot_lig) {
$this->set_ligne($y, $mot_lig);
$ok = true;
for ($x = $y; $x < $this->largeur; $x++) {
if (!isset($this->debuts[$this->hauteur][$this->get_colonne($x, $hauteur)])) {
$ok = false;
break;
}
}
if (!$ok) {
continue;
}
$this->mots_utilises[$mot_lig] = true;
if ($y < $this->largeur) {
yield from $this->trouve_une_colonne($y);
} else if ($y + 1 < $this->hauteur) {
yield from $this->trouve_une_ligne($y + 1);
} else {
yield $this;
}
unset($this->mots_utilises[$mot_lig]);
}
}
private function trouve_une_colonne($x) {
global $mots_de_n_lettres;
$hauteur = min($x + 1, $this->hauteur);
$largeur = min($x + 1, $this->largeur);
foreach ($this->debuts[$this->hauteur][$this->get_colonne($x, $hauteur)] as $mot_col) {
if (isset($this->mots_utilises[$mot_col])) {
continue;
}
$this->set_colonne($x, $mot_col);
$ok = true;
for ($y = $x; $y < $this->hauteur; $y++) {
if (!isset($this->debuts[$this->largeur][$this->get_ligne($y, $largeur)])) {
$ok = false;
break;
}
}
if (!$ok) {
continue;
}
$this->mots_utilises[$mot_col] = true;
if ($x +1 < $this->hauteur) {
yield from $this->trouve_une_ligne($x + 1);
} else if ($x + 1 < $this->largeur) {
yield from $this->trouve_une_colonne($x + 1);
} else {
yield $this;
}
unset($this->mots_utilises[$mot_col]);
}
}
public function current() {
return $this->grilles->current();
}
public function valid() {
return $this->grilles->valid();
}
public function hash() {
$string = "";
foreach ($this->grille as $ligne) {
$string .= implode("", $ligne);
}
return hash('sha256', $string);
}
}

View File

@ -3673,7 +3673,7 @@ VANITE L'hommage d'un imbécile aux qualités d'un âne très intime. Ambrose Bi
VENERATION attitude spirituelle dun homme à légard de Dieu, et dun chien à légard de lhomme. Ambrose Bierce VENERATION attitude spirituelle dun homme à légard de Dieu, et dun chien à légard de lhomme. Ambrose Bierce
VERROU Appareil distinctif de la civilisation et de l'évolution de la pensée. Ambrose Bierce VERROU Appareil distinctif de la civilisation et de l'évolution de la pensée. Ambrose Bierce
VIEILLESSE Période de notre existence pendant laquelle nous composons avec les vices que nous chérissons encore, en vitupérant ceux que nous n'osons plus pratiquer. Ambrose Bierce VIEILLESSE Période de notre existence pendant laquelle nous composons avec les vices que nous chérissons encore, en vitupérant ceux que nous n'osons plus pratiquer. Ambrose Bierce
VIN jus de raisin fermenté connu de l'association des femmes chrétiennes sous le nom de "boisson" et quelquefois de "rhum". Ambrose Bierce VIN Jus de raisin fermenté connu de l'association des femmes chrétiennes sous le nom de "boisson" et quelquefois de "rhum". Ambrose Bierce
VIOLON Instrument qui titille les oreilles humaines par le frottement dune queue d'un cheval sur les boyaux d'un chat. Ambrose Bierce VIOLON Instrument qui titille les oreilles humaines par le frottement dune queue d'un cheval sur les boyaux d'un chat. Ambrose Bierce
VOCIFERATION Mode d'expression d'un adversaire. Ambrose Bierce VOCIFERATION Mode d'expression d'un adversaire. Ambrose Bierce
VOISIN Personne qu'on nous demande d'aimer comme nous-mêmes, et qui fait tout ce qu'il peut pour nous faire désobéir. Ambrose Bierce VOISIN Personne qu'on nous demande d'aimer comme nous-mêmes, et qui fait tout ce qu'il peut pour nous faire désobéir. Ambrose Bierce

Can't render this file because it contains an unexpected character in line 576 and column 23.

View File

@ -3,8 +3,7 @@
const MIN_LETTRES_MOT_1 = 2; const MIN_LETTRES_MOT_1 = 2;
const MIN_LETTRES_MOT_2 = 1; const MIN_LETTRES_MOT_2 = 1;
// const MAX_MOTS = 100000; const MAX_MOTS = 100000;
$dico = []; $dico = [];
if (($lecteur = fopen("dico.csv", "r")) !== FALSE) { if (($lecteur = fopen("dico.csv", "r")) !== FALSE) {
@ -25,7 +24,6 @@ if (($lecteur = fopen("dico.csv", "r")) !== FALSE) {
} else { } else {
$dico[$mot] = []; $dico[$mot] = [];
} }
} }
} }
fclose($lecteur); fclose($lecteur);
@ -59,9 +57,9 @@ function mots_espaces($longueur)
fisherYatesShuffle($mots_de_n_lettres[$longueur]); fisherYatesShuffle($mots_de_n_lettres[$longueur]);
foreach ($mots_de_n_lettres[$longueur] as $mot) { foreach ($mots_de_n_lettres[$longueur] as $mot) {
yield $mot; yield $mot;
// if (++$nb_mots > MAX_MOTS) { if (++$nb_mots >= MAX_MOTS) {
// return; return;
// } }
} }
for ($i = MIN_LETTRES_MOT_1; $longueur - $i - 1 >= MIN_LETTRES_MOT_2; $i++) { for ($i = MIN_LETTRES_MOT_1; $longueur - $i - 1 >= MIN_LETTRES_MOT_2; $i++) {
foreach ($mots_de_n_lettres[$i] as $mot1) { foreach ($mots_de_n_lettres[$i] as $mot1) {
@ -69,12 +67,14 @@ function mots_espaces($longueur)
if ($mot1 != $mot2) { if ($mot1 != $mot2) {
$dico["$mot1 $mot2"] = array_merge($dico[$mot1], $dico[$mot2]); $dico["$mot1 $mot2"] = array_merge($dico[$mot1], $dico[$mot2]);
yield "$mot1 $mot2"; yield "$mot1 $mot2";
if (++$nb_mots >= MAX_MOTS) {
return;
}
$dico["$mot2 $mot1"] = array_merge($dico[$mot2], $dico[$mot1]); $dico["$mot2 $mot1"] = array_merge($dico[$mot2], $dico[$mot1]);
yield "$mot2 $mot1"; yield "$mot2 $mot1";
// $nb_mots += 2; if (++$nb_mots >= MAX_MOTS) {
// if ($nb_mots > MAX_MOTS) { return;
// return; }
// }
} }
} }
} }