Построение Шидоку

Нужно написать программу для Шидоку (4 на 4 Судоку). Алгоритм понятен, но как заменять пустые клетки?

Что-то я написал,но это нечто считает неправильно

Например:

1234
?4?1
2143
4312

должно быть:

1234
3421
2143
4312

А выводит

1234
1431
2143
4312

Код:

#include <iostream>
#include <string>
#include <iomanip>
#include <vector>
#include <fstream>
using namespace std;

void test(int i, int j) {}

int main()
{

    //ввод строк

    vector<string> a(4);

    for (int i = 0; i < 4; i++)
    {
        cout << "Input the row #" << i + 1 << ">";
        while (!(cin >> a[i]) || (cin.peek() != '\n') || (a[i].size() < 4) || (a[i].size() > 4))    //пока не будет введено нормальное число, выполняем цикл
        {
            cin.clear();
            while (cin.get() != '\n');
            std::cout << "Error!\n" << "Try again.Enter row with length = 4 > ";
        }
        for (int j = 0; j < 4; j++)
        {
            if (a[i][j] != '1' && a[i][j] != '2' && a[i][j] != '3' && a[i][j] != '4' && a[i][j] != '?')
            {
                //проверка
                cout << "lox";
                //проверка
            }
        }
    }

    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            if (a[i][j] == '?')
            {

                a[i][j] = '1';

                for (int k = 0; k < 4; k++)
                {
                    if (((int) a[i][j] == (int) a[i][k]) && (a[i][k] != '?'))
                    {
                        a[i][j] = (int) a[i][j] + 1;
                    }
                }

                int k = j;

                for (int c = 0; c < 4; c++)
                {
                    if (((int) a[i][j] == (int) a[c][j]) && (a[c][j] != '?'))
                    {
                        a[i][j] = (int) a[i][j] + 1;
                    }
                }

                /*a[i][j] -= 2; */
            }
        }
    }

    cout << endl;
    for (int i = 0; i < 4; i++)
    {
        for (int j = 0; j < 4; j++)
        {
            cout << a[i][j] << " ";
        }
        cout << endl;
    }
}

Ответы (1 шт):

Автор решения: Tamada

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

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

bool check_wish(bool wish)
{

    string no;//переменная,отвечающая за продолжение
    do
    {
        if (no == "y" || no == "yes")
        {
            wish = true;
        }

        cout << "Continue? (Y/N)>";

        while (!(cin >> no) || (cin.peek() != '\n')) //цикл,отвечающий за проверку вводимых типов данных
        {
            cin.clear();
            while (cin.get() != '\n');
            std::cout << "Continue? (Y/N) > ";

        }

        transform(no.begin(), no.end(), no.begin(), ::tolower); // понимжение регистра

    } while (no != "n" && no != "no" && no != "y" && no != "yes");

    if (no == "n" || no == "no")
    {
        wish = false;
    }
    return wish;
}

bool check_col(int col, int num,int grid[4][4]) 
{ //проверка на то,находится ли число в столбце сейчас или нет
    for (int row = 0; row < 4; row++)
        if (grid[row][col] == num)
            return true;
    return false;
}

bool check_row(int row, int num,int grid[4][4]) 
{ //check whether num is present in row or not
    for (int col = 0; col < 4; col++)
        if (grid[row][col] == num)
            return true;
    return false;
}

bool check_2x2(int _2x2StartRow, int _2x2StartCol, int num,int grid[4][4]) 
{
    //проверка на то,находится ли число в 2x2 квадрате
    for (int row = 0; row < 2; row++)
        for (int col = 0; col < 2; col++)
            if (grid[row + _2x2StartRow][col + _2x2StartCol] == num)
                return true;
    return false;
}

void show_grid(int grid[4][4]) 
{ //print the sudoku grid after solve
    for (int row = 0; row < 4; row++) 
    {
        for (int col = 0; col < 4; col++) 
        {
            cout << grid[row][col] << " ";
        }
        cout << endl;
    }
}

bool empty_checker(int& row, int& col,int grid[4][4]) 
{ //
    for (row = 0; row < 4; row++)
        for (col = 0; col < 4; col++)
            if (grid[row][col] == 0) //0 - пусто
                return true;
    return false;
}

bool check_valid(int row, int col, int num,int grid[4][4]) 
{
    //Вернуть отрицательный результат,когда число не равно 1-4 и не находится в 2x2 квадрате
    return !check_row(row, num,grid) && !check_col(col, num,grid) && !check_2x2(row - row % 2,
        col - col % 2, num,grid);
}

bool solve(int grid[4][4]) 
{
    int row, col;
    //если все заполнено,то вернуть труе
    if (!empty_checker(row, col,grid))
        return true; 
    //проверка на то, являются ли числа правильными(1-4)
    for (int num = 1; num <= 4; num++) 
    { 
        if (check_valid(row, col, num,grid)) 
        { 
            grid[row][col] = num;
            //рекурсивно проверяем решается ли 2x2
            if (solve(grid)) 
                return true;
            //переход к следующему месту,если is_Valid вернуло 
            grid[row][col] = 0; 
        }
    }
    return false;
}

string row_check(string a)
{
    while (!(cin >> a) || (cin.peek() != '\n') || (a.size() < 4) || (a.size() > 4))//пока не будет введено нормальное число, выполняем цикл
    {
        cin.clear();
        while (cin.get() != '\n');
        std::cout << "Error!\n" << "Try again.Enter row with length = 4 > ";
    }
    return a;
}

char valid_num_check(char a,int i,int j)
{
    int wish = 1;
    while (wish == 1) //цикл,который отвечает за момент,когда пользователь не ввел Y/N
    {
        std::cout << "a[" << i << "][" << j << "] can only be equal to 1/2/3/4/?\nCurrent value is >" << a << "\nEnter 1/2/3/4/? > ";
        while (!(cin >> a) || (cin.peek() != '\n'))//пока не будет введено нормальное число, выполняем цикл
        {
            cin.clear();
            while (cin.get() != '\n');
            std::cout << "Error!\n" << "Try again.Enter 1/2/3/4/? > ";

        }

        if (a == '1' || a == '2' || a == '3' || a == '4' || a == '?')
            wish = 2;
    }
    return a;
}

int converter(char shidoku, int grid)
{
    if ((int)shidoku == 49)
    {
        grid = 1;
    }
    else
        if ((int)shidoku == 50)
        {
            grid = 2;
        }
        else
            if ((int)shidoku == 51)
            {
                grid = 3;
            }
            else
                if ((int)shidoku == 52)
                {
                    grid = 4;
                }
                else
                    if ((int)shidoku == 63)
                    {
                        grid = 0;
                    }
    return grid;
}

int main() {
    bool wish = true;
    while (wish)
    {
        int grid[4][4];
        vector<string> a(4);
        char shidoku[4][4];

        for (int i = 0; i < 4; i++)
        {
            cout << "Input the row #" << i + 1 << ">";
            a[i] = row_check(a[i]);

            for (int j = 0; j < 4; j++)
            {
                if (a[i][j] != '1' && a[i][j] != '2' && a[i][j] != '3' && a[i][j] != '4' && a[i][j] != '?')
                {
                    a[i][j] = valid_num_check(a[i][j],i,j);
                }
            }
        }

        for (int i = 0; i < 4; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                shidoku[i][j] = a[i][j];
            }
        }

        for (int i = 0; i < 4; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                grid[i][j] = converter(shidoku[i][j], grid[i][j]);
            }
        }



        if (solve(grid) == true)
            show_grid(grid);
        else
            cout << "No solution\n";

        wish = check_wish(wish);
    }
}
→ Ссылка