Алгоритм решения судоку
Я борюсь с проблемой создания алгоритма, который может решить супер-судоку. Мой судоку 21х9 и состоит из трех судоку 9х9 (строки 1-9 это первый, 7-15 второй и 12-21 третий). Я пытался написать алгоритм, но он не решает судоку должным образом. Я думаю, что что-то не так в функции, которая проверяет, можно ли вставить номер(notValid()Может быть, кто-то заметит, где я допустил ошибку.
Что я уже пробовал:
Вот что я пытался сделать:
#include<stdio.h> #include<algorithm> bool checkCol(int workArray[21][9], short begin, short end, short checkingValue, short y){ for (int i = begin; i < end; ++i){ if (workArray[i][y] == checkingValue){ return false; } } return true; } bool notValid(int workArray[21][9], short value, short pointX, short pointY){ short rows = (pointX / 3) * 3; short columns = (pointY / 3) * 3; for (int i = 0; i < 9; ++i){ if (workArray[rows + (i % 3)][columns + (i / 3)] == value){ return false; } } for (int i = 0; i < 9; ++i){ if (workArray[pointX][i] == value){ return false; } } if (pointX >= 0 && pointX <= 5){ if (!checkCol(workArray, 0, 9, value, pointY) && !checkCol(workArray, 6, 15, value, pointY)/* && !checkCol(workArray, 12, 21, value, pointY)*/){ return false; } } else if (pointX >= 6 && pointX <= 8){ if (!checkCol(workArray, 0, 9, value, pointY) && !checkCol(workArray, 6, 15, value, pointY) /*&& !checkCol(workArray, 12, 21, value, pointY)*/){ return false; } } else if (pointX >= 9 && pointX <= 11){ if (!checkCol(workArray, 6, 15, value, pointY) && !checkCol(workArray, 0, 9, value, pointY) && !checkCol(workArray, 12, 21, value, pointY)){ return false; } } else if (pointX >= 12 && pointX <= 14){ if (!checkCol(workArray, 12, 21, value, pointY) && !checkCol(workArray, 6, 15, value, pointY)/* && !checkCol(workArray, 0, 9, value, pointY)*/){ return false; } } else if (pointX >= 15 && pointX <= 20){ if (/*!checkCol(workArray, 6, 15, value, pointY) &&*/ !checkCol(workArray, 12, 21, value, pointY)){ return false; } } return true; } bool findEmptySpace(int workArray[21][9], short &pointX, short &pointY); bool solveTheSudoku(int workArray[21][9]){ short pointX, pointY; if (!findEmptySpace(workArray, pointX, pointY)){ return true; } for (int i=1; i<=9; ++i){ if (notValid(workArray, i, pointX, pointY)){ workArray[pointX][pointY] = i; if (solveTheSudoku(workArray)){ return true; } workArray[pointX][pointY] = 0; } } return false; } bool findEmptySpace(int workArray[21][9], short &pointX, short &pointY){ for (pointX = 20; pointX >= 0; --pointX){ for (pointY = 8; pointY >= 0; --pointY){ if (workArray[pointX][pointY] == 0){ return true; } } } return false; } void printSudoku(int sudoku[21][9]){ for (int i = 0; i < 21; ++i){ for (int j = 0; j < 9; ++j){ printf("%d ",sudoku[i][j]); }printf("\n"); } } int main(){ int sudoku[21][9] = {{0, 0, 0, 0, 0, 0, 0, 0, 9}, {4, 7, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 5, 6, 2, 0, 0, 3}, {0, 6, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 4, 0, 0, 3, 0, 6, 0}, {0, 5, 9, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 2, 0, 0, 0, 0, 0}, {6, 0, 0, 4, 0, 0, 0, 0, 0}, {0, 4, 8, 0, 0, 0, 6, 0, 0}, {0, 0, 4, 0, 0, 0, 0, 0, 0}, {0, 2, 0, 0, 0, 0, 1, 0, 0}, {0, 9, 1, 0, 0, 4, 0, 0, 5}, {0, 0, 0, 0, 0, 0, 0, 0, 0}, {4, 0, 0, 6, 0, 0, 0, 0, 5}, {5, 0, 0, 0, 0, 0, 8, 6, 0}, {0, 0, 0, 0, 8, 7, 0, 2, 1}, {0, 1, 0, 0, 0, 3, 0, 8, 4}, {0, 2, 0, 0, 0, 0, 3, 0, 0}, {8, 0, 0, 3, 0, 0, 6, 4, 2}, {0, 4, 0, 7, 0, 0, 5, 0, 8}, {3, 0, 0, 4, 2, 0, 0, 7, 0}}; //int arrayTmp[21][9]; //std::copy(sudoku, sudoku+21, arrayTmp); if (solveTheSudoku(sudoku)){ printSudoku(sudoku); } else{ printf("No solution find\n"); printSudoku(sudoku); } return 0; }
enhzflep
Как бы то ни было, здесь, в CodeProject, есть статья, в которой используется веб-камера для поиска изображений головоломки судоку. После обнаружения код решает головоломку и накладывает решение поверх живого видеопотока.
Возможно, вы получите некоторый пробег от этой статьи. Вы можете найти его здесь: Веб-Камера Реального Времени Sudoku Solver
Patrice T
Это только 3 судоку или есть связь между ними ?
weegeee
Да, они связаны. Эти три судоку накладываются друг на друга и вместе образуют одно супер-судоку.
Patrice T
Дайте подробную информацию о том, как они пересекаются.
Воспользуйся Улучшить вопрос чтобы обновить ваш вопрос.
Чтобы каждый мог обратить внимание на эту информацию.
Patrice T
Можете ли вы объяснить, как должен работать ваш код?
Ваш фактический код удивительно короток.
weegeee
Он использует обратный путь. Начиная с низа, он пытается решить судоку. Если есть пустое место, я проверяю, подходит ли номер, и ввожу его, если не подходит, я возвращаюсь к предыдущему введенному номеру.
[no name]
EDIT: я решил эту проблему и должен был удалить свой код, чтобы избежать плагиата
Это тот самый код, который мы все собираемся украсть? Упражнение бессмысленно, потому что у Google есть кэшированная копия, и вы увидите, что CP имеет управление версиями.
#include<stdio.h> #include<algorithm> bool checkCol(int workArray[21][9], short begin, short end, short checkingValue, short y){ for (int i = begin; i < end; ++i){ if (workArray[i][y] == checkingValue){ return false; } } return true; } bool notValid(int workArray[21][9], short value, short pointX, short pointY){ short rows = (pointX / 3) * 3; short columns = (pointY / 3) * 3; for (int i = 0; i < 9; ++i){ if (workArray[rows + (i % 3)][columns + (i / 3)] == value){ return false; } } for (int i = 0; i < 9; ++i){ if (workArray[pointX][i] == value){ return false; } } if (pointX >= 0 && pointX <= 5){ if (!checkCol(workArray, 0, 9, value, pointY) && !checkCol(workArray, 6, 15, value, pointY)/* && !checkCol(workArray, 12, 21, value, pointY)*/){ return false; } } else if (pointX >= 6 && pointX <= 8){ if (!checkCol(workArray, 0, 9, value, pointY) && !checkCol(workArray, 6, 15, value, pointY) /*&& !checkCol(workArray, 12, 21, value, pointY)*/){ return false; } } else if (pointX >= 9 && pointX <= 11){ if (!checkCol(workArray, 6, 15, value, pointY) && !checkCol(workArray, 0, 9, value, pointY) && !checkCol(workArray, 12, 21, value, pointY)){ return false; } } else if (pointX >= 12 && pointX <= 14){ if (!checkCol(workArray, 12, 21, value, pointY) && !checkCol(workArray, 6, 15, value, pointY)/* && !checkCol(workArray, 0, 9, value, pointY)*/){ return false; } } else if (pointX >= 15 && pointX <= 20){ if (/*!checkCol(workArray, 6, 15, value, pointY) &&*/ !checkCol(workArray, 12, 21, value, pointY)){ return false; } } return true; } bool findEmptySpace(int workArray[21][9], short &pointX, short &pointY); bool solveTheSudoku(int workArray[21][9]){ short pointX, pointY; if (!findEmptySpace(workArray, pointX, pointY)){ return true; } for (int i=1; i<=9; ++i){ if (notValid(workArray, i, pointX, pointY)){ workArray[pointX][pointY] = i; if (solveTheSudoku(workArray)){ return true; } workArray[pointX][pointY] = 0; } } return false; } bool findEmptySpace(int workArray[21][9], short &pointX, short &pointY){ for (pointX = 20; pointX >= 0; --pointX){ for (pointY = 8; pointY >= 0; --pointY){ if (workArray[pointX][pointY] == 0){ return true; } } } return false; } void printSudoku(int sudoku[21][9]){ for (int i = 0; i < 21; ++i){ for (int j = 0; j < 9; ++j){ printf("%d ",sudoku[i][j]); }printf("\n"); } } int main(){ int sudoku[21][9] = {{0, 0, 0, 0, 0, 0, 0, 0, 9}, {4, 7, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 5, 6, 2, 0, 0, 3}, {0, 6, 0, 0, 0, 0, 0, 0, 0}, {0, 0, 4, 0, 0, 3, 0