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";
class Grille {
class Grille
{
public $grille;
public $hauteur;
public $largeur;
@ -11,9 +12,9 @@ class Grille {
private $lettres_suivantes;
private $positions;
private $nb_positions;
private $mots_utilises = [];
public function __construct($hauteur, $largeur, $id="") {
public function __construct($hauteur, $largeur, $id = "")
{
$this->hauteur = $hauteur;
$this->largeur = $largeur;
$this->grille = array_fill(0, $hauteur, array_fill(0, $largeur, ''));
@ -24,9 +25,9 @@ class Grille {
mt_srand(crc32($id));
}
$this->lettres_suivantes = [];
foreach ($hauteur == $largeur? [$hauteur]: [$hauteur, $largeur] as $longueur) {
foreach ($hauteur == $largeur ? [$hauteur] : [$hauteur, $largeur] as $longueur) {
$this->lettres_suivantes[$longueur] = [];
foreach(mots_espaces($longueur) as $mot) {
foreach (mots_espaces($longueur) as $mot) {
for ($i = 0; $i <= $longueur; $i++) {
$debut = substr($mot, 0, $i);
if (!isset($this->lettres_suivantes[$longueur][$debut])) {
@ -45,11 +46,12 @@ class Grille {
}
}
$this->nb_positions = count($this->positions);
$this->grilles = $this->generateur();
}
public function get_ligne($y, $largeur) {
public function get_ligne($y, $largeur)
{
$ligne = "";
for ($x = 0; $x < $largeur; $x++) {
$ligne .= $this->grille[$y][$x];
@ -57,73 +59,76 @@ class Grille {
return $ligne;
}
public function get_colonne($x, $hauteur) {
public function get_colonne($x, $hauteur)
{
$colonne = "";
for ($y = 0; $y < $hauteur; $y++) {
$colonne .= $this->grille[$y][$x];
}
return $colonne;
}
public function generateur($index=0) {
if ($index == $this->nb_positions) {
yield $this;
return;
public function generateur()
{
$mots_utilises = [];
$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];
$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 => $_) {
while (!empty($pile)) {
[$i, $lettre] = array_pop($pile);
[$x, $y] = $this->positions[$i];
$this->grille[$y][$x] = $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;
}
$mots_utilises[$y] = $this->get_ligne($y, $x);
} else {
unset($mots_utilises[$y]);
}
$mot_colonne = NULL;
if ($y == $this->hauteur - 1) {
$mot_colonne = $this->get_colonne($x, $y);
if (isset($this->mots_utilises[$mot_colonne])) {
if (in_array($this->get_colonne($x, $y), $mots_utilises)) {
continue;
} else {
$this-> mots_utilises[$mot_colonne] = true;
}
}
yield from $this->generateur($index + 1);
if ($mot_ligne) {
unset($this-> mots_utilises[$mot_ligne]);
$i++;
if ($i == $this->nb_positions) {
yield $this;
continue;
}
if ($mot_colonne) {
unset($this-> mots_utilises[$mot_colonne]);
[$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];
}
}
}
public function current() {
public function current()
{
return $this->grilles->current();
}
public function valid() {
public function valid()
{
return $this->grilles->valid();
}
public function hash() {
public function hash()
{
$string = "";
foreach ($this->grille as $ligne) {
$string .= implode("", $ligne);
}
return hash('sha256', $string);
}
}
}

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

@ -2369,7 +2369,7 @@ UPAS Malais à lorigine de malaises. André Counson
UPPERCUT Pain levé. Lionel Leteur
UR Ses enfants sont sages. Marc Aussitot
URANIUM Nouveau riche. Robert Scipion
URBAIN Civil … et si ville. Robert Scipion
URBAIN Civil… et si ville. Robert Scipion
URBANISTE Il laisse toujours son travail en plan. Lucien Lacau
URE Bœuf au cœur d'un taureau. Jean-Paul Vanden Branden
URI Dans zurich ou pas très loin. Philippe Harang
@ -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
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
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
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

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_2 = 1;
// const MAX_MOTS = 100000;
const MAX_MOTS = 100000;
$dico = [];
if (($lecteur = fopen("dico.csv", "r")) !== FALSE) {
@ -25,7 +24,6 @@ if (($lecteur = fopen("dico.csv", "r")) !== FALSE) {
} else {
$dico[$mot] = [];
}
}
}
fclose($lecteur);
@ -59,9 +57,9 @@ function mots_espaces($longueur)
fisherYatesShuffle($mots_de_n_lettres[$longueur]);
foreach ($mots_de_n_lettres[$longueur] as $mot) {
yield $mot;
// if (++$nb_mots > MAX_MOTS) {
// return;
// }
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) {
@ -69,12 +67,14 @@ 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";
// $nb_mots += 2;
// if ($nb_mots > MAX_MOTS) {
// return;
// }
if (++$nb_mots >= MAX_MOTS) {
return;
}
}
}
}