I am implementing Sudoku solver and using 2D vector and passing it around using reference but still, when at the end of the main I try to print the 2D vector it prints the initial 2D vector.
#include <iostream>
#include <vector>
#include <map>
using namespace std;
void display(vector<vector<int>>& _board) {
for (auto row: _board) {
for (auto col: row) {
cout << col << " ";
}
cout << endl;
}
}
bool isBoardSolved(vector<vector<int>>& _board) {
for (auto row: _board) {
for (auto col: row) { //style[1] of 2D vector traversal
if (col == 0) {
return false;
}
}
}
return true;
}
map<int, int> findOptions(vector<vector<int>>& _board, int _row, int _col) {
map<int, int> options;
int x, y;
for (int digit = 1; digit < 10; ++digit) {
options[digit] = 0; //state 0 means available as options
}
//col in a row
for (y = 0; y < 9; ++y) {
if (_board[_row][y] != 0) {
options[_board[_row][y]] = 1;
}
}
//row in a col
for (x = 0; x < 9; ++x) {
if (_board[x][_col] != 0) {
options[_board[x][_col]] = 1;
}
}
//in a rectangular 3*3 matrix
if (_row <= 2)
x = 0;
else if (_row > 2 && _row <= 5)
x = 3;
else
x = 6;
if (_col <= 2)
y = 0;
else if (_col > 2 && _col <= 5)
y = 3;
else
y = 6;
for (int i = x; i < x + 3; ++i) {
for (int j = y; j < y + 3; ++j) {
if (_board[i][j] != 0) {
options[_board[i][j]] = 1;
}
}
}
return options;
}
void solveBoard(vector<vector<int>>& _board) {
int row = 0;
int col = 0;
bool flag = false;
if (isBoardSolved(_board)) {
// cout << "Solved Sudoku Board" << endl;
// display(_board); //gives correct answer when I print it here
return;
}
else {
for (int x = 0; x < 9; ++x) { //not using the style[1] because I need explicit index of empty slot
flag = false;
for (int y = 0; y < 9; ++y) {
if (_board[x][y] == 0) {
row = x;
col = y;
flag = true;
break;
}
}
if (flag)
break;
}
}
auto options = findOptions(_board, row, col);
for (auto digit: options) {
if (digit.second != 1) {
_board[row][col] = digit.first;
solveBoard(_board);
}
}
_board[row][col] = 0;
}
int main(int argc, char *argv[]) {
vector<vector<int>> board(9, vector<int>(9, 0));
board[0][3] = 3;
board[0][6] = 2;
board[2][1] = 7;
board[2][2] = 8;
board[2][3] = 0;
board[2][4] = 6;
board[2][6] = 3;
board[2][7] = 4;
board[3][1] = 4;
board[3][2] = 2;
board[3][3] = 5;
board[3][4] = 1;
board[4][0] = 1;
board[4][1] = 0;
board[4][2] = 6;
board[4][6] = 4;
board[4][7] = 0;
board[4][8] = 9;
board[5][4] = 8;
board[5][5] = 6;
board[5][6] = 1;
board[5][7] = 5;
board[6][1] = 3;
board[6][2] = 5;
board[6][4] = 9;
board[6][6] = 7;
board[6][7] = 6;
board[7][3] = 7;
board[8][2] = 9;
board[8][5] = 5;
cout << "Given Sudoku Board" << endl;
display(board);
solveBoard(board);
cout << "Solved Sudoku Board" << endl;
display(board); //gives unchanged answer when i print it here
}
What is wrong I am doing and how to correct it.
When I try this :
void change(vector<vector<int>>& _b){
_b[0][1] = 99;
}
int main(){
vector<vector<int>> b(1, vector<int>(9, 1));
cout<<b[0][1]<<endl;
change(b);
cout<<b[0][1];
return 0;
}
This displays the changed value for 2D vecor b.
You are not exiting the recursion call stack correctly in solveBoard(). Note the new bool function signature for solveBoard() being returned to signal up the invocation chain to exit early. Also note the three different return points now depending on where you are.
bool solveBoard(vector<vector<int>>& _board) {
int row = 0;
int col = 0;
bool flag;
if (isBoardSolved(_board)) {
// cout << "Solved Sudoku Board" << endl;
// display(_board); //gives correct answer when I print it here
return true;
}
else {
for (int x = 0; x < 9; ++x) { //not using the style[1] because I need explicit index of empty slot
flag = false;
for (int y = 0; y < 9; ++y) {
if (_board[x][y] == 0) {
row = x;
col = y;
flag = true;
break;
}
}
if (flag)
break;
}
}
auto options = findOptions(_board, row, col);
for (auto digit : options) {
if (digit.second != 1) {
_board[row][col] = digit.first;
if (solveBoard(_board))
return true;
}
}
_board[row][col] = 0;
return false;
}
Related
I'm getting an error message in Codeblocks C++ 'Program received signal SIGSEGV, Segmentation fault' in comparison between a vector element and a size of vector of vectors inside for loop (line 133 if (parz_przestrzenie[i] != parz_dystanse[i].size())).
Could anyone tell me why?
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int bloki_parz[100000], bloki_nieparz[100000];
int silnia(int n)
{
int liczba = 1;
for (int i = 1; i <= n; i++)
{
liczba *= i;
}
return liczba;
}
int main()
{
int n, czapka, wolne_miejsca = 0, wynik = 1;
vector<int> parz, nieparz, parz_przestrzenie, nieparz_przestrzenie, parz_przestrzenie2, nieparz_przestrzenie2;
vector<vector<int>> parz_dystanse;
vector<vector<int>> nieparz_dystanse;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> czapka;
if (i % 2 == 0)
{
parz.push_back(czapka);
}
else
{
nieparz.push_back(czapka);
}
}
int parz_size = parz.size(), nieparz_size = nieparz.size();
// sprawdzamy czy dane nie sÂą sprzeczne ; gdy zabraknie nam miejsc do rozmieszczania
vector<int> parz_duplicate = parz;
vector<int> nieparz_duplicate = nieparz;
parz_duplicate.erase(unique(parz_duplicate.begin(), parz_duplicate.end()), parz_duplicate.end());
nieparz_duplicate.erase(unique(nieparz_duplicate.begin(), nieparz_duplicate.end()), nieparz_duplicate.end());
int parz_dupl_size = parz_duplicate.size(), nieparz_dupl_size = nieparz_duplicate.size();
if (parz_size < nieparz_dupl_size)
{
cout << 0 << endl;
return 0;
}
if (nieparz_size < parz_dupl_size)
{
cout << 0 << endl;
return 0;
}
for (int i = 0; i < parz_size - 1; i++)
{
if (parz[i] == parz[i + 1])
{
bloki_parz[i + 1] = 1;
}
}
for (int i = 0; i < nieparz_size - 1; i++)
{
if (nieparz[i] == nieparz[i + 1])
{
bloki_nieparz[i] = 1;
}
}
for (int i = 0; i < parz_size; i++)
{
vector<int> bloczek;
for (int j = i; j < parz_size; j++)
{
if (parz[j] != parz[j + 1])
{
bloczek.push_back(parz[j]);
}
else
{
i += 1;
break;
}
}
if (bloczek.size() != 0)
{
parz_dystanse.push_back(bloczek);
}
}
int parz_dyst_size = parz_dystanse.size();
if (parz[parz_size - 1] != parz[parz_size - 2])
{
parz_dystanse[parz_dyst_size - 1].push_back(parz[parz_size - 1]);
}
for (int i = 0; i < nieparz_size; i++)
{
vector<int> bloczek;
for (int j = i; j < nieparz_size; j++)
{
if (nieparz[j] != nieparz[j + 1])
{
bloczek.push_back(nieparz[j]);
}
else
{
i += 1;
break;
}
}
if (bloczek.size() != 0)
{
nieparz_dystanse.push_back(bloczek);
}
}
int nieparz_dyst_size = nieparz_dystanse.size();
int current_wynik = 0;
for (int i = 0; i < nieparz_size; i++)
{
if (bloki_parz[i] == 0)
{
current_wynik++;
}
else
{
if (current_wynik != 0)
{
parz_przestrzenie.push_back(current_wynik);
}
current_wynik = 0;
}
}
parz_przestrzenie.push_back(current_wynik);
current_wynik = 0;
for (int i = 0; i < parz_size; i++)
{
if (bloki_nieparz[i] == 0)
{
current_wynik++;
}
else
{
if (current_wynik != 0)
{
nieparz_przestrzenie.push_back(current_wynik);
}
current_wynik = 0;
}
}
nieparz_przestrzenie.push_back(current_wynik);
int parz_przest_size = parz_przestrzenie.size(), nieparz_przest_size = nieparz_przestrzenie.size();
for (int i = 0; i < 1; i++)
{
if (parz_przestrzenie[i] != parz_dystanse[i].size())
{
wynik *= parz_przestrzenie[i];
wolne_miejsca++;
}
}
for (int i = 0; i < nieparz_przest_size; i++)
{
if (nieparz_przestrzenie[i] != nieparz_dystanse[i].size())
{
wynik *= nieparz_przestrzenie[i];
wolne_miejsca++;
}
}
cout << wynik * silnia(wolne_miejsca) << endl;
}
parz_dystanse is a vector of a vector. In this case the return value of parz_dystanse.size() is a long unsigned int, whereas an element of parz_przestrzenie is an int.
You need to make explicit that parz_dystanse.size() returns an int in order to make comparitions between integer expressions of different signedness.
This will fix that problem:
if (parz_przestrzenie[i] != (int)parz_dystanse[i].size())
The issue in my code lies in the minimax algorithm, more specifically the return values. My current solution written in C++ is below, using tuples, returning score, x and y positions.
I've decided to do something similar in C using struct.
The algorithm finds every possible endstate given the current board position [3468] correctly, but doesn't return correct next move coordinates.
Given that it is X-s turn, we should get [score = 0, x = 0, y = 1] from the function. Currently the returned values are [score = 1, x = 1, y = 0].
How should I implement the struct correctly for the algorithm to work properly?
#include <stdio.h>
int s = 3; //Board size
int cnt = 0;
char player = 'X', opponent = 'O';
struct Best {
int score, x, y;
};
void printBoard(char v[][s]);
char eval(char v[][s]);
struct Best miniMax(char Table[][s], int depth, bool isMaximising); //Problem: structs?
int main(int argc, char const *argv[]) {
char b[3][3] = {
{'X','_','_'},
{'_','O','_'},
{'_','_','_'}
};
printBoard(b);
struct Best s = miniMax(b, 0, true);
printf("Possible games: %d\n", cnt);
cnt = 0;
printf("Score: %d, Best move: [%d][%d]\n", s.score, s.x, s.y);
return 0;
}
void printBoard(char v[][s]){
for (size_t i = 0; i < s; i++){
for (size_t j = 0; j < s; j++){
printf("%c|", v[i][j]);
}
printf("\n");
}
printf("\n");
}
char eval(char v[][s]){
for (size_t i = 0; i < s; i++) {
if (v[i][0] == v[i][1] && v[i][1] == v[i][2] && v[i][0] != '_') //Row
return v[i][0];
if (v[0][i] == v[1][i] && v[1][i] == v[2][i] && v[0][i] != '_') //Col
return v[0][i];
}
if (v[0][0] == v[1][1] && v[1][1] == v[2][2] && v[0][0] != '_') //Diag
return v[0][0];
if (v[0][2] == v[1][1] && v[1][1] == v[2][0] && v[0][2] != '_') //Diag2
return v[0][2];
for (size_t i = 0; i < s; i++) {
for (size_t j = 0; j < s; j++) {
if (v[i][j] == '_')
return '\0';
}
}
return '=';
}
Here is the problematic miniMax function implementation in C:
struct Best miniMax(char Table[][s], int depth, bool isMaximising) {
struct Best v;
char result = eval(Table);
if (result == 'X') {
cnt++;
v.score = 1;
v.x = 0;
v.y = 0;
return v;
}
if (result == 'O') {
cnt++;
v.score = -1;
v.x = 0;
v.y = 0;
return v;
}
if (result == '=') {
cnt++;
v.score = 0;
v.x = 0;
v.y = 0;
return v;
}
if (isMaximising) {
int bestScore = -100;
for (size_t i = 0; i < s; i++) {
for (size_t j = 0; j < s; j++) {
if (Table[i][j] == '_') {
Table[i][j] = player;
v = miniMax(Table, depth + 1, false);
if (v.score > bestScore) {
bestScore = v.score;
v.score = bestScore;
v.x = i;
v.y = j;
}
Table[i][j] = '_';
}
}
}
return v;
} else {
int bestScore = 100;
for (size_t i = 0; i < s; i++) {
for (size_t j = 0; j < s; j++) {
if (Table[i][j] == '_') {
Table[i][j] = opponent;
v = miniMax(Table, depth + 1, true);
if (v.score < bestScore) {
bestScore = v.score;
v.score = bestScore;
v.x = i;
v.y = j;
}
Table[i][j] = '_';
}
}
}
return v;
}
}
Implementation in C++:
#include <tuple>
#include <iostream>
using namespace std;
tuple <int, int, int> Minimax(char Board[][s], int depth, bool isMaximising){
char res = eval(Board);
if (res == 'X') {
cnt++;
return {1, 0, 0};
}
if (res == 'O') {
cnt++;
return {-1, 0, 0};
}
if (res == '=') {
cnt++;
return {0, 0, 0};
}
if (isMaximising) {
int bestScore = -100;
int px = 0, py = 0;
for (size_t i = 0; i < s; i++) {
for (size_t j = 0; j < s; j++) {
if (Board[i][j] == '_') {
Board[i][j] = player;
auto [score, x, y] = Minimax(Board, depth + 1, false);
if (score > bestScore) {
bestScore = score;
px = i;
py = j;
}
Board[i][j] = '_';
}
}
}
return {bestScore, px, py};
} else {
int bestScore = 100;
int qx = 0, qy = 0;
for (size_t i = 0; i < s; i++) {
for (size_t j = 0; j < s; j++) {
if (Board[i][j] == '_') {
Board[i][j] = opponent;
auto [score, x, y] = Minimax(Board, depth + 1, true);
if (score < bestScore) {
bestScore = score;
qx = i;
qy = j;
}
Board[i][j] = '_';
}
}
}
return {bestScore, qx, qy};
}
}
The basic problem is that every time miniMax recursively calls itself, it overwrites v with the returned value, losing the saved best value from any earlier iteration. So you always end up with x/y from the last tested position, not from the best found one.
Add a new struct Best best value that is the one you update and return when you find a better move. Note that you also don't need the bestScore local then -- you can just use best.score
I'm taking an intro to c++ class and I am quite stuck on a part to this project.
I need to have my character, 'H' move freely around the array. I have written a good amount of my code, but when I compile and run it, my hero isn't given the option to move. I don't know what is going wrong when I am calling my function in main. Any help would be gladly appreciated. I need his new position in the array to be maintained so that he can find the villain who is randomly placed in the array. I can work on the randint part later, but I am having a hard time simply getting 'H' to move.
Here is what I have so far:
Thank you.
#include <iostream>
using namespace std;
void printBoard(char board[][8])
{
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
{
cout << board[x][y];
}
cout << endl;
}
}
void move(char board[][8], char umove)
{
cout << "Please enter which direction you would like to move." << endl;
cin >> umove;
if (umove == 'x')
{
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
{
board[x][y] = x - 1;
}
}
}
else if (umove == 'd')
{
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
{
board[x][y] = y + 1;
}
}
}
else if (umove == 'a')
{
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
{
board[x][y] = y - 1;
}
}
}
else if (umove == 'w')
{
for (int x = 0; x < 8; x++)
{
for (int y = 0; y < 8; y++)
{
board[x][y] = x + 1;
}
}
}
}
char userinput()
{
char usermove;
cout << "Please enter the direction you want to go." << endl;
cin >> usermove;
return usermove;
}
int main()
{
char board[8][8];
int x;
int y;
while (true)
{
for (x = 0; x < 8; x++)
{
for (y = 0; y < 8; y++)
{
board[x][y] = 'e';
}
}
board[0][0] = 'H';
printBoard(board);
void move();
return 0;
}
}
you call void move() which is a method declaration and you must use move(...) instead for calling method. return 0 cause the app to finish which is not correct in this situation. you use infinite loop and you must use a condition for finish game.
depend on your description I suggest:
void printBoard(char board[][8]) {
// same as before
}
bool move(char board[][8], int &Hx, int &Hy) {
char umove;
cout << "Please enter which direction you would like to move." << endl;
cin >> umove;
if (umove == 'f') // f mean finish it
return false;
board[Hx][Hy] = 'e';
if (umove == 'a') // a mean left
Hy = Hy == 0 ? 7 : Hy - 1;
else if (umove == 'd') // d mean right
Hy = Hy == 7 ? 0 : Hy + 1;
else if (umove == 'w') // w mean up
Hx = Hx == 0 ? 7 : Hx - 1;
else if (umove == 's') // s mean down
Hx = Hx == 7 ? 0 : Hx + 1;
board[Hx][Hy] = 'H';
return true;
}
int main() {
char board[8][8];
int Hx = 0, Hy = 0;
for (int x = 0; x < 8; x++) {
for (int y = 0; y < 8; y++) {
board[x][y] = 'e';
}
}
board[Hx][Hy] = 'H';
bool res = true;
while (res) {
printBoard(board);
res = move(board, Hx, Hy);
}
cout << "Game finished!";
return 0;
}
You can make char board[][] and Hx and Hy (which contain current position of H) global and avoid sending them to method but this is not good at all.
I hope this is what you want.
I know that this question was asked many times but I couldn't find the solution for my error
I am trying to make a program to check whether the matrix given is symmetric or not the user enters the number of test cases then the size then the matrix and the output is whether it's symmetric or not
the program works fine until I try a size more than 3 it breaks with this error and when debugging it seems that it breaks at delete[]arrL
#include <iostream>
#include <string>
using namespace std;
int n(char s)
{
switch (s)
{
case '0':
return 0;
case '1':
return 1;
case '2':
return 2;
case '3':
return 3;
case '4':
return 4;
case '5':
return 5;
case '6':
return 6;
case '7':
return 7;
case '8':
return 8;
case '9':
return 9;
}
}
int getnumber(string a)
{
string num = "";
for (int i = 0; i < a.size(); i++)
{
if (isdigit(a[i]))
num += a[i];
}
if (num.size() == 1)
{
return n(num[0]);
}
if (num.size() == 2)
{
return (n(num[0]) * 10) + (n(num[1]));
}
if (num.size() == 3)
{
return (n(num[0]) * 100) + (n(num[1]) * 10) + (n(num[2]));
}
}
bool matrix2(long int**p, int r)
{
int c = 0, u = 0, ss = 0;
for (int i = 0; i < r; i++)
{
for (int j = 0; j < r; j++)
{
if (p[i][j]<0)
return false;
}
}
long int*arrL = new long int[r];
long int*arrR = new long int[r];
for (int i = 0; i < r; i++)
{
for (int j = 0; j < i; j++)
{
arrL[c++] = p[i][j];
ss++;
}
}
for (int i = 0; i < r; i++)
{
for (int j = i + 1; j < r; j++)
{
arrR[u++] = p[i][j];
}
}
for (int i = 0; i < ss; i++)
{
int q = ss - i - 1;
long int a = arrR[i];
long int b = arrL[q];
if (!(a == b))
{
delete[]arrL;
delete[]arrR;
return false;
}
}
delete[]arrL;
delete[]arrR;
return true;
}
int main()
{
int t;
cin >> t;
for (int num = 0; num < t;num++)
{
int yy = num + 1;
string dimension;
cin.ignore();
getline(cin, dimension);
int r = getnumber(dimension);
long int**p = new long int*[r];
for (int w = 0; w < r; w++){
p[w] = new long int[r];
}
for (int w = 0; w < r; w++)
{
for (int ww = 0; ww < r; ww++)
{
cin >> p[w][ww];
}
}
bool result = matrix2(p, r);
if (result)
{
cout << "Test #" << yy << ": Symmetric." << endl;
}
else
{
cout << "Test #" << yy << ": Non-symmetric." << endl;
}
for (int i = 0; i < r; i++)
{
delete[]p[i];
}
delete[] p;
}
return 0;
}
arrL and arrR are allocated of size r, but then
arrL[c++] = p[i][j];
is executed more than r times, so c exceeds r, so you've corrupted your heap.
I'm attempting to create a text-based version of this game.
Code:
#include <iostream>
#include <vector>
#include <ctime>
class Clickomania {
public:
Clickomania();
std::vector<std::vector<int> > board;
int move(int, int);
bool isSolved();
void print();
void pushDown();
bool isValid();
};
Clickomania::Clickomania()
: board(12, std::vector<int>(8,0)) {
srand((unsigned)time(0));
for(int i = 0; i < 12; i++) {
for(int j = 0; j < 8; j++) {
int color = (rand() % 3) + 1;
board[i][j] = color;
}
}
}
void Clickomania::pushDown() {
for(int i = 0; i < 8; i++) {
for(int j = 0; j < 12; j++) {
if (board[j][i] == 0) {
for(int k = j; k > 0; k--) {
board[k][i] = board[k-1][i];
}
board[0][i] = 0;
}
}
}
}
int Clickomania::move(int row, int col) {
bool match = false;
int totalMatches = 0;
if (row > 12 || row < 0 || col > 8 || col < 0) {
return 0;
}
int currentColor = board[row][col];
board[row][col] = 0;
if ((row + 1) < 12) {
if (board[row+1][col] == currentColor)
{
match = true;
totalMatches++;
totalMatches += move(row+1, col);
}
}
if ((row - 1) >= 0) {
if (board[row-1][col] == currentColor) {
match = true;
totalMatches++;
totalMatches += move(row-1, col);
}
}
if ((col + 1) < 8) {
if (board[row][col+1] == currentColor) {
match = true;
totalMatches++;
totalMatches += move(row, col+1);
}
}
if ((col - 1) >= 0) {
if (board[row][col-1] == currentColor) {
match = true;
totalMatches++;
totalMatches += move(row, col-1);
}
}
return totalMatches;
}
void Clickomania::print() {
for(int i = 0; i < 12; i++) {
for(int j = 0; j < 8; j++) {
std::cout << board[i][j];
}
std::cout << "\n";
}
}
int main() {
Clickomania game;
game.print();
int row;
int col;
std::cout << "Enter row: ";
std::cin >> row;
std::cout << "Enter col: ";
std::cin >> col;
int numDestroyed = game.move(row,col);
game.print();
std::cout << "Destroyed: " << numDestroyed << "\n";
}
The method that is giving me trouble is my "move" method. This method, given a pair of coordinates, should delete all the squares at that coordinate with the same number and likewise with all the squares with the same number connected to it.
If you play the link I gave above you'll see how the deletion works on a click.
int Clickomania::move(int row, int col) {
bool match = false;
int totalMatches = 0;
if (row > 12 || row < 0 || col > 8 || col < 0) {
return 0;
}
int currentColor = board[row][col];
board[row][col] = 0;
if ((row + 1) < 12) {
if (board[row+1][col] == currentColor) {
match = true;
totalMatches++;
totalMatches += move(row+1, col);
}
}
if ((row - 1) >= 0) {
if (board[row-1][col] == currentColor) {
match = true;
totalMatches++;
totalMatches += move(row-1, col);
}
}
if ((col + 1) < 8) {
if (board[row][col+1] == currentColor)
{
match = true;
totalMatches++;
totalMatches += move(row, col+1);
}
}
if ((col - 1) >= 0) {
if (board[row][col-1] == currentColor) {
match = true;
totalMatches++;
totalMatches += move(row, col-1);
}
}
return totalMatches;
}
My move() method above works fine, as in it will delete the appropriate "blocks" and replace them with zeros, however the number of destroyed (value returned) is always one off (too small). I believe this is because the first call of move() isn't being counted, but I don't know how to differentiate between the first call or subsequent calls in that recursive method.
How can I modify my move() method so it returns the correct number of destroyed blocks?
It looks like you're incrementing totalMoves in the wrong place(s). You should count the match at the point where you set board[r][c] = 0 and remove the other references to totalMoves++.
You are right that the first call isn't being counted, it's only counting the recursive calls.
0 based indexing. You dont want to check > you want >=
you wanna check row >= 12 col >= 8