Алгоритм решения / генерации судоку в переполнении стека

У меня проблемы с определенной частью моего алгоритма, и я надеялся, что кто-то поймет, что я делаю неправильно.

Моя программа в основном работает так:

Создайте 81 пустую ячейку, заполните каждый шаг ячейки за шаг, проверяя, действительно ли она там.

У меня есть 3 действительных чека, и горизонтальный действительный чек (если числа двойные или больше в 1 строке) уже доставляет мне неприятности.

Это моя функция:

private function isValidHorizontal($index)
{
for ($i = 0; $i < 81; $i += 9){

$firstIndex = $i * 9;
$lastIndex = 9 * ($i + 1) - 1;

// fisrt loop tracking fowards, 2nd loop tracking backwards
if ($index >= $i && $index <= $lastIndex) {
for ($j = 0; $j <= $lastIndex; $j++) {
if ($this->cell[$index]->getValue() == $j) {
return false;
}
}
for ($k = 0; $k >= $firstIndex; $k--){
if ($this->cell[$index]->getValue() == $j) {
return false;
}
}
}
}

return true;
}

$index это положение клетки, поэтому, когда $index = 0 это будет самая первая клетка. Последняя ячейка будет $index = 80

$this->cell[$index]->getValue() возвращает проверенное мной целое число, поэтому я правильно получаю значение.

Проблема как-то никогда не вернется

Есть идеи? очевидно, это всего лишь часть кода, если вам нужно больше помочь, напишите комментарий, и я буду редактировать 🙂

3

Решение

Во втором внутреннем цикле вы используете $j вместо $k:

for ($k = 0; $k >= $firstIndex; $k--){
if ($this->cell[$index]->getValue() == $j) { // Here, change to $k
1

Другие решения

Вы уже получили правильный ответ от @ this.lau_, но если я могу предложить какой-то совет, вы можете немного его сократить, изменив логику. PHP на самом деле не самый подходящий язык для этого, поэтому он все равно будет выглядеть немного неуклюже, но, возможно, стоит взглянуть на него. 🙂

private function isValidHorizontal($index) {
$taken = [];
foreach (range($index, 81, 9) as $i) {
$value = $this->cell[$i]->getValue();
if (is_int($value) && in_array($value, $taken)) {
return false;
}
$taken[] = $value;
}
return true;
}
1

По вопросам рекламы [email protected]