I have been having difficulty solving the N Queen problem, I am able to implement most of my functions, but the function that places the Queen recursively with backtracking. The placeQueens function is using a provided pseudocode that is required for the project. I had to create the array on the heap that is pointing to boardPtr, which is also required. I have a while loop condition that I have but I am not sure if it's correct. I have tried looking online for similar code but none of them were able to help me.
Here is my code:
#include <iostream>
#include "ChessBoard.h"
int main()
{
// Create a board
ChessBoard myBoard;
/* Loop through board sizes from 3 to 13.
Since 3 and 13 are invalid you should see
board sizes 4 and 12 twice. */
for (int i = 3; i <= 13; i++)
{
myBoard.setSize(i);
/* Attempt to solve the N-Queens Problem. If the solve
code is working it should find solutions for all
sizes. */
if (!myBoard.solve())
std::cout << "Sorry, no solution was found for board size "
<< myBoard.getSize() << "." << std::endl << std::endl;
else
{
std::cout << "Size " << myBoard.getSize()
<< " solution:" << std::endl;
myBoard.displayBoard();
std::cout << std::endl << std::endl;
}
}
return 0;
}
#include "ChessBoard.h"
#include <iostream>
using namespace std;
bool ChessBoard::placeQueens( int column)
{
int row = 0;
if (column >= boardSize)
{
// The board is filled, problem is solved.
return true;
}
else
{
while (row < boardSize && column < boardSize) // unconsidered rows exist in column
{
if ((canPlace(boardPtr, row, column)) == true) //[row][column] is unattacked
{
//Place a queen in the un - attacked square.
boardPtr[row][column] = 'Q';
//Do a recursive call to try and place queens in subsequent columns :
if (!placeQueens(column + 1))
{
//If we’re here, placement of the last queen resulted in a dead end; no solution could be found.Remove the last queen placed.
boardPtr[row][column] = '*';
//Move to next row so search can continue in next iteration.
row++;
}
else
{
// If we’re here, recursive calls were able to place queens in all columns to the right of column, the problem is solved.
return true;
}
}
else
{
//Square is attacked, move to next row.
row++;
}
}
//All rows have been considered in column without a successful queen placement.Backtrack by returning false.
return false;
}
}
bool ChessBoard::canPlace(char** boardPtr, int row, int column)
{
int i, j;
// Check row
for (i = 0; i < column; i++)
if (boardPtr[row][i] )
return false;
// Check upper diagonal
for (i = row, j = column; i >= 0 && j >= 0; i--, j--)
if (boardPtr[i][j])
return false;
// Check lower diagonal
for (i = row, j = column; j >= 0 && i < boardSize; i++, j--)
if (boardPtr[i][j] )
return false;
return true;
}
ChessBoard::ChessBoard()
{
boardSize = 8;
boardPtr = nullptr;
}
ChessBoard::ChessBoard(int size)
{
if (size < 4)
{
boardSize = 4;
}
else if (size > 12)
{
boardSize = 12;
}
}
ChessBoard::~ChessBoard()
{
}
int ChessBoard::setSize(int size)
{
delete[] boardPtr;
//Initialize array at size 4
if (size < 4)
{
boardSize = 4;
char** chessBoard = new char* [4];
for (int i = 0; i < 4; i++)
{
chessBoard[i] = new char[4];
}
// Point initialized ChessBoard to boardPtr
boardPtr = chessBoard;
// Fill ChessBoard with *
for (int i = 0; i < boardSize; i++)
{
for (int j = 0; j < boardSize; j++)
{
boardPtr[i][j] = '*';
}
}
}
//Initialize array at size 12
else if (size > 12)
{
boardSize = 12;
char** chessBoard = new char* [12];
for (int i = 0; i < size; i++)
{
chessBoard[i] = new char[12];
}
// Point initialized ChessBoard to boardPtr
boardPtr = chessBoard;
// Fill ChessBoard with *
for (int i = 0; i < boardSize; i++)
{
for (int j = 0; j < boardSize; j++)
{
boardPtr[i][j] = '*';
}
}
}
//Initialize array at given size
else
{
boardSize = size;
char** chessBoard = new char* [size];
for (int i = 0; i < size; i++)
{
chessBoard[i] = new char[size];
}
// Point initialized ChessBoard to boardPtr
boardPtr = chessBoard;
// Fill ChessBoard with *
for (int i = 0; i < boardSize; i++)
{
for (int j = 0; j < boardSize; j++)
{
boardPtr[i][j] = '*';
}
}
}
return 1;
}
int ChessBoard::getSize()
{
return boardSize;
}
bool ChessBoard::solve()
{
int column = 0;
if (placeQueens(column) == false)
{
return false;
}
else
{
return true;
}
}
void ChessBoard::displayBoard()
{
for (int i = 0; i < boardSize; i++)
{
for (int j = 0; j < boardSize; j++)
{
cout << boardPtr[i][j] << " ";
}
cout << endl;
}
}
#ifndef CHESSBOARD_H
#define CHESSBOARD_H
class ChessBoard
{
private:
char** boardPtr;
int boardSize;
bool placeQueens( int column);
bool canPlace(char** boardPtr, int row, int col);
public:
ChessBoard();
ChessBoard(int size);
~ChessBoard();
int setSize(int size);
int getSize();
bool solve();
void displayBoard();
};
#endif
Interesting task you have! I decided to implement my own code from scratch for solving N Queen problem. Actually I implemented it for any board size N, not just equal to 8.
I didn't fix bugs in your code, but instead implemented my own solution. Although it may be not the answer you want, still it would be a good thing from educational point of view. Hoping that there would be other answers later that are fixing bugs in your code, as you wished.
I made code very optimized, so it is not very simple from first side, but solves task very fast, using BackTracking, with several extra techniques of speeding it up.
After program finishes it prints to console all solutions in a nice form. Please scroll down below the code to see example of console output.
First program has some extra descriptive comments to show what's happenning in program.
Notice that I provided two codes below, first is simplified version, that is more easy to understand, so it is better from educational point of view. Second code is advanced one, it is more difficult, but solves task fast. Please look at first code if you want just to learn basics, and look at second code if you want to learn advanced techniques.
Simplified:
Try it online!
#include <iostream>
#include <vector>
#include <string>
void Output(std::vector<std::vector<bool>> & board, std::vector<std::string> & lines, bool last);
void Solve(std::vector<std::vector<bool>> & board, std::vector<std::string> & lines,
int N, int & num_sol, int cnt = 0, int start_i = 0, int start_j = 0, int depth = 0) {
if (cnt >= N) {
Output(board, lines, false);
// Increase number of solutions.
++num_sol;
return;
}
// Traverse whole board starting from last queen
for (int i = start_i; i < board.size(); ++i)
for (int j = i == start_i ? start_j : 0; j < board[i].size(); ++j) {
bool attacked = false;
// k-loop checks if position [i][j] is being attacked
for (int k = 0; k < (board.size() > board[i].size() ?
board.size() : board[i].size()); ++k)
if (
// Is there horizontal attack
k < board[i].size() && k != j && board[i][k] ||
// Is there vertical attack
k < board.size() && k != i && board[k][j] ||
// Is there main diagonal attack
k < board.size() && k != i && 0 <= j - i + k &&
j - i + k < board[i].size() && board[k][j - i + k] ||
// Is there secondary diagonal attack
k < board.size() && k != i && 0 <= j + i - k &&
j + i - k < board[i].size() && board[k][j + i - k]
) {
attacked = true;
break;
}
if (attacked)
continue;
// Position [i][j] is not under attack, hence placing a queen
board[i][j] = true;
// Recursive descend to place another queen
Solve(board, lines, N, num_sol, cnt + 1, i, j + 1, depth + 1);
// Backtrack, to delete previous queen
board[i][j] = false;
}
if (depth == 0)
Output(board, lines, true);
}
// Function of outputting solutions to console
void Output(std::vector<std::vector<bool>> & board, std::vector<std::string> & lines, bool last) {
if (1) {
if (!last) {
for (int i = 0; i < board.size(); ++i) {
for (int j = 0; j < board[i].size(); ++j)
lines[i].push_back(board[i][j] ? 'Q' : '.');
lines[i] += "|";
}
}
if (lines.at(0).size() >= 70 || last && !lines.at(0).empty()) {
for (int i = 0; i < lines.size(); ++i)
std::cout << lines[i] << std::endl;
for (int j = 0; j < lines.at(0).size(); ++j)
std::cout << (lines.at(0)[j] == '|' ? '+' : '-');
std::cout << std::endl;
lines.clear();
lines.resize(board.size());
}
}
}
int main() {
// rows - number of rows in a board, cols - number of columns in a board
// N - number of queens to be placed
int const rows = 8, cols = 8, N = 8;
// Filling with empty values board [rows][cols]
std::vector<std::vector<bool>> board(rows, std::vector<bool>(cols));
std::vector<std::string> lines(rows);
// Answer, number of solutions
int num_sol = 0;
// Starting a backtracking
Solve(board, lines, N, num_sol);
// Outputting answer
std::cout << "Number of solutions: " << num_sol << std::endl;
}
Advanced:
Try it online!
#include <iostream>
#include <string>
#define MAX(a, b) ((a) >= (b) ? (a) : (b))
enum { max_rows = 32, max_cols = 32, max_max_rows_cols = MAX(max_rows, max_cols) };
void Output(bool (& board)[max_rows][max_cols], std::string (& lines)[max_rows],
int rows, int cols, bool last);
void Solve(bool (& board)[max_rows][max_cols], std::string (& lines)[max_rows],
bool (& busy_cols)[max_cols], bool (& busy_diagA)[2 * max_max_rows_cols],
bool (& busy_diagB)[2 * max_max_rows_cols],
int rows, int cols, int N, int & num_sol, int cnt = 0, int start_i = 0, int depth = 0) {
if (cnt >= N) {
Output(board, lines, rows, cols, false);
++num_sol;
return;
}
int const max_rows_cols = MAX(rows, cols);
if (rows - start_i < N - cnt)
return;
int avail_cols[max_cols];
int avail_cols_cnt = 0;
for (int j = 0; j < cols; ++j)
if (!busy_cols[j]) {
avail_cols[avail_cols_cnt] = j;
++avail_cols_cnt;
}
if (avail_cols_cnt < N - cnt)
return;
for (int i = start_i; i < rows; ++i)
for (int jj = 0; jj < avail_cols_cnt; ++jj) {
int const j = avail_cols[jj];
if (busy_diagA[max_rows_cols + j - i] || busy_diagB[j + i])
continue;
board[i][j] = true;
busy_cols[j] = true;
busy_diagA[max_rows_cols + j - i] = true;
busy_diagB[j + i] = true;
Solve(board, lines, busy_cols, busy_diagA, busy_diagB,
rows, cols, N, num_sol, cnt + 1, i + 1, depth + 1);
board[i][j] = false;
busy_cols[j] = false;
busy_diagA[max_rows_cols + j - i] = false;
busy_diagB[j + i] = false;
}
if (depth == 0)
Output(board, lines, rows, cols, true);
}
void Output(bool (& board)[max_rows][max_cols], std::string (& lines)[max_rows],
int rows, int cols, bool last) {
if (1) {
if (!last) {
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j)
lines[i].push_back(board[i][j] ? 'Q' : '.');
lines[i] += "|";
}
}
if (lines[0].size() >= 70 || last && !lines[0].empty()) {
for (int i = 0; i < rows; ++i)
std::cout << lines[i] << std::endl;
for (int j = 0; j < lines[0].size(); ++j)
std::cout << (lines[0][j] == '|' ? '+' : '-');
std::cout << std::endl;
for (int i = 0; i < rows; ++i)
lines[i].clear();
}
}
}
int main() {
int const rows = 8, cols = 8, N = 8;
bool board[max_rows][max_cols] = {};
std::string lines[max_rows] = {};
bool busy_cols[max_cols] = {};
bool busy_diagA[2 * max_max_rows_cols] = {};
bool busy_diagB[2 * max_max_rows_cols] = {};
int num_sol = 0;
Solve(board, lines, busy_cols, busy_diagA, busy_diagB, rows, cols, N, num_sol);
std::cout << "Number of solutions: " << num_sol << std::endl;
}
Output:
Q.......|Q.......|Q.......|Q.......|.Q......|.Q......|.Q......|.Q......|
....Q...|.....Q..|......Q.|......Q.|...Q....|....Q...|....Q...|.....Q..|
.......Q|.......Q|...Q....|....Q...|.....Q..|......Q.|......Q.|Q.......|
.....Q..|..Q.....|.....Q..|.......Q|.......Q|Q.......|...Q....|......Q.|
..Q.....|......Q.|.......Q|.Q......|..Q.....|..Q.....|Q.......|...Q....|
......Q.|...Q....|.Q......|...Q....|Q.......|.......Q|.......Q|.......Q|
.Q......|.Q......|....Q...|.....Q..|......Q.|.....Q..|.....Q..|..Q.....|
...Q....|....Q...|..Q.....|..Q.....|....Q...|...Q....|..Q.....|....Q...|
--------+--------+--------+--------+--------+--------+--------+--------+
.Q......|.Q......|.Q......|.Q......|..Q.....|..Q.....|..Q.....|..Q.....|
.....Q..|......Q.|......Q.|.......Q|Q.......|....Q...|....Q...|....Q...|
.......Q|..Q.....|....Q...|.....Q..|......Q.|.Q......|.Q......|......Q.|
..Q.....|.....Q..|.......Q|Q.......|....Q...|.......Q|.......Q|Q.......|
Q.......|.......Q|Q.......|..Q.....|.......Q|Q.......|.....Q..|...Q....|
...Q....|....Q...|...Q....|....Q...|.Q......|......Q.|...Q....|.Q......|
......Q.|Q.......|.....Q..|......Q.|...Q....|...Q....|......Q.|.......Q|
....Q...|...Q....|..Q.....|...Q....|.....Q..|.....Q..|Q.......|.....Q..|
--------+--------+--------+--------+--------+--------+--------+--------+
..Q.....|..Q.....|..Q.....|..Q.....|..Q.....|..Q.....|..Q.....|..Q.....|
....Q...|.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|
.......Q|.Q......|.Q......|.Q......|...Q....|...Q....|.......Q|.......Q|
...Q....|....Q...|......Q.|......Q.|Q.......|.Q......|Q.......|Q.......|
Q.......|.......Q|Q.......|....Q...|.......Q|.......Q|...Q....|....Q...|
......Q.|Q.......|...Q....|Q.......|....Q...|....Q...|......Q.|......Q.|
.Q......|......Q.|.......Q|.......Q|......Q.|......Q.|....Q...|.Q......|
.....Q..|...Q....|....Q...|...Q....|.Q......|Q.......|.Q......|...Q....|
--------+--------+--------+--------+--------+--------+--------+--------+
..Q.....|..Q.....|..Q.....|..Q.....|...Q....|...Q....|...Q....|...Q....|
.....Q..|......Q.|......Q.|.......Q|Q.......|Q.......|.Q......|.Q......|
.......Q|.Q......|.Q......|...Q....|....Q...|....Q...|....Q...|......Q.|
.Q......|.......Q|.......Q|......Q.|.......Q|.......Q|.......Q|..Q.....|
...Q....|....Q...|.....Q..|Q.......|.Q......|.....Q..|.....Q..|.....Q..|
Q.......|Q.......|...Q....|.....Q..|......Q.|..Q.....|Q.......|.......Q|
......Q.|...Q....|Q.......|.Q......|..Q.....|......Q.|..Q.....|Q.......|
....Q...|.....Q..|....Q...|....Q...|.....Q..|.Q......|......Q.|....Q...|
--------+--------+--------+--------+--------+--------+--------+--------+
...Q....|...Q....|...Q....|...Q....|...Q....|...Q....|...Q....|...Q....|
.Q......|.Q......|.Q......|.Q......|.....Q..|.....Q..|.....Q..|......Q.|
......Q.|......Q.|.......Q|.......Q|Q.......|.......Q|.......Q|Q.......|
..Q.....|....Q...|....Q...|.....Q..|....Q...|.Q......|..Q.....|.......Q|
.....Q..|Q.......|......Q.|Q.......|.Q......|......Q.|Q.......|....Q...|
.......Q|.......Q|Q.......|..Q.....|.......Q|Q.......|......Q.|.Q......|
....Q...|.....Q..|..Q.....|....Q...|..Q.....|..Q.....|....Q...|.....Q..|
Q.......|..Q.....|.....Q..|......Q.|......Q.|....Q...|.Q......|..Q.....|
--------+--------+--------+--------+--------+--------+--------+--------+
...Q....|...Q....|...Q....|...Q....|...Q....|...Q....|....Q...|....Q...|
......Q.|......Q.|......Q.|.......Q|.......Q|.......Q|Q.......|Q.......|
..Q.....|....Q...|....Q...|Q.......|Q.......|....Q...|...Q....|.......Q|
.......Q|.Q......|..Q.....|..Q.....|....Q...|..Q.....|.....Q..|...Q....|
.Q......|.....Q..|Q.......|.....Q..|......Q.|Q.......|.......Q|.Q......|
....Q...|Q.......|.....Q..|.Q......|.Q......|......Q.|.Q......|......Q.|
Q.......|..Q.....|.......Q|......Q.|.....Q..|.Q......|......Q.|..Q.....|
.....Q..|.......Q|.Q......|....Q...|..Q.....|.....Q..|..Q.....|.....Q..|
--------+--------+--------+--------+--------+--------+--------+--------+
....Q...|....Q...|....Q...|....Q...|....Q...|....Q...|....Q...|....Q...|
Q.......|.Q......|.Q......|.Q......|.Q......|..Q.....|..Q.....|..Q.....|
.......Q|...Q....|...Q....|.....Q..|.......Q|Q.......|Q.......|.......Q|
.....Q..|.....Q..|......Q.|Q.......|Q.......|.....Q..|......Q.|...Q....|
..Q.....|.......Q|..Q.....|......Q.|...Q....|.......Q|.Q......|......Q.|
......Q.|..Q.....|.......Q|...Q....|......Q.|.Q......|.......Q|Q.......|
.Q......|Q.......|.....Q..|.......Q|..Q.....|...Q....|.....Q..|.....Q..|
...Q....|......Q.|Q.......|..Q.....|.....Q..|......Q.|...Q....|.Q......|
--------+--------+--------+--------+--------+--------+--------+--------+
....Q...|....Q...|....Q...|....Q...|....Q...|....Q...|....Q...|....Q...|
......Q.|......Q.|......Q.|......Q.|......Q.|......Q.|.......Q|.......Q|
Q.......|Q.......|.Q......|.Q......|.Q......|...Q....|...Q....|...Q....|
..Q.....|...Q....|...Q....|.....Q..|.....Q..|Q.......|Q.......|Q.......|
.......Q|.Q......|.......Q|..Q.....|..Q.....|..Q.....|..Q.....|......Q.|
.....Q..|.......Q|Q.......|Q.......|Q.......|.......Q|.....Q..|.Q......|
...Q....|.....Q..|..Q.....|...Q....|.......Q|.....Q..|.Q......|.....Q..|
.Q......|..Q.....|.....Q..|.......Q|...Q....|.Q......|......Q.|..Q.....|
--------+--------+--------+--------+--------+--------+--------+--------+
.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|
Q.......|.Q......|.Q......|..Q.....|..Q.....|..Q.....|..Q.....|..Q.....|
....Q...|......Q.|......Q.|Q.......|Q.......|Q.......|....Q...|....Q...|
.Q......|Q.......|Q.......|......Q.|.......Q|.......Q|......Q.|.......Q|
.......Q|..Q.....|...Q....|....Q...|...Q....|....Q...|Q.......|Q.......|
..Q.....|....Q...|.......Q|.......Q|.Q......|.Q......|...Q....|...Q....|
......Q.|.......Q|....Q...|.Q......|......Q.|...Q....|.Q......|.Q......|
...Q....|...Q....|..Q.....|...Q....|....Q...|......Q.|.......Q|......Q.|
--------+--------+--------+--------+--------+--------+--------+--------+
.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|.....Q..|
..Q.....|..Q.....|..Q.....|...Q....|...Q....|...Q....|...Q....|.......Q|
......Q.|......Q.|......Q.|Q.......|.Q......|......Q.|......Q.|.Q......|
.Q......|.Q......|...Q....|....Q...|.......Q|Q.......|Q.......|...Q....|
...Q....|.......Q|Q.......|.......Q|....Q...|..Q.....|.......Q|Q.......|
.......Q|....Q...|.......Q|.Q......|......Q.|....Q...|.Q......|......Q.|
Q.......|Q.......|.Q......|......Q.|Q.......|.Q......|....Q...|....Q...|
....Q...|...Q....|....Q...|..Q.....|..Q.....|.......Q|..Q.....|..Q.....|
--------+--------+--------+--------+--------+--------+--------+--------+
......Q.|......Q.|......Q.|......Q.|......Q.|......Q.|......Q.|......Q.|
Q.......|.Q......|.Q......|..Q.....|..Q.....|...Q....|...Q....|....Q...|
..Q.....|...Q....|.....Q..|Q.......|.......Q|.Q......|.Q......|..Q.....|
.......Q|Q.......|..Q.....|.....Q..|.Q......|....Q...|.......Q|Q.......|
.....Q..|.......Q|Q.......|.......Q|....Q...|.......Q|.....Q..|.....Q..|
...Q....|....Q...|...Q....|....Q...|Q.......|Q.......|Q.......|.......Q|
.Q......|..Q.....|.......Q|.Q......|.....Q..|..Q.....|..Q.....|.Q......|
....Q...|.....Q..|....Q...|...Q....|...Q....|.....Q..|....Q...|...Q....|
--------+--------+--------+--------+--------+--------+--------+--------+
.......Q|.......Q|.......Q|.......Q|
.Q......|.Q......|..Q.....|...Q....|
...Q....|....Q...|Q.......|Q.......|
Q.......|..Q.....|.....Q..|..Q.....|
......Q.|Q.......|.Q......|.....Q..|
....Q...|......Q.|....Q...|.Q......|
..Q.....|...Q....|......Q.|......Q.|
.....Q..|.....Q..|...Q....|....Q...|
--------+--------+--------+--------+
Number of solutions: 92
There are several issues, starting from the multiple memory leaks (see e.g. the empty destructor or the delete[] boardPtr; at the beginning of ChessBoard::setSize), but what prevents the program to solve the problem is this:
bool ChessBoard::canPlace(char** boardPtr, int row, int column)
{
int i, j;
// Check row
for (i = 0; i < column; i++)
if (boardPtr[row][i] )
// ^^^^^^^^^^^^^^^^
return false;
// ...
}
That condition and the following ones should be boardPtr[row][i] == 'Q', because, as written, it just check if the char is not 0, while an empty spot is indicated by a . in this program.
I need make Pascal Triangle matrix using vectors and then print it.
This algorithm would work with arrays, but somehow it doesn't work with matrix using vectors.
#include <iomanip>
#include <iostream>
#include <vector>
typedef std::vector<std::vector<int>> Matrix;
int NumberOfRows(Matrix m) { return m.size(); }
int NumberOfColumns(Matrix m) {
if (m.size() != 0)
return m[0].size();
return 0;
}
Matrix PascalTriangle(int n) {
Matrix mat;
int a;
for (int i = 1; i <= n; i++) {
a = 1;
for (int j = 1; j <= i; j++) {
if (j == 1)
mat.push_back(j);
else
mat.push_back(a);
a = a * (i - j) / j;
}
}
return mat;
}
void PrintMatrix(Matrix m, int width) {
for (int i = 0; i < NumberOfRows(m); i++) {
for (int j = 0; j < NumberOfColumns(m); j++)
std::cout << std::setw(width) << m[i][j];
std::cout << std::endl;
}
}
int main() {
Matrix m = PascalTriangle(7);
PrintMatrix(m, 10);
return 0;
}
I get nothing on screen, and here's the same code just without matrix using vectors program (which works fine).
Could you help me fix this code?
The main problem is that in PascalTriangle, you are starting out with an empty Matrix in both the number of rows and columns.
Since my comments mentioned push_back, here is the way to use it if you did not initialize the Matrix with the number of elements that are passed in.
The other issue is that NumberOfColumns should specify the row, not just the matrix vector.
The final issue is that you should be passing the Matrix by const reference, not by value.
Addressing all of these issues, results in this:
Matrix PascalTriangle(int n)
{
Matrix mat;
for (int i = 0; i < n; i++)
{
mat.push_back({}); // creates a new empty row
std::vector<int>& newRow = mat.back(); // get reference to this row
int a = 1;
for (int j = 0; j < i + 1; j++)
{
if (j == 0)
newRow.push_back(1);
else
newRow.push_back(a);
a = a * (i - j) / (j + 1);
}
}
return mat;
}
And then in NumberOfColumns:
int NumberOfColumns(const Matrix& m, int row)
{
if (!m.empty())
return m[row].size();
return 0;
}
And then, NumberOfRows:
int NumberOfRows(const Matrix& m) { return m.size(); }
And last, PrintMatrix:
void PrintMatrix(const Matrix& m, int width)
{
for (int i = 0; i < NumberOfRows(m); i++)
{
for (int j = 0; j < NumberOfColumns(m, i); j++)
std::cout << std::setw(width) << m[i][j];
std::cout << std::endl;
}
}
Here is a live demo
Your code won't compile because you have numerous errors in PascalTriangle.
For one, you initialize a matrix with no elements. Additionally, you use matrix indices starting at 1 rather than 0.
The following prints things for me:
Matrix PascalTriangle(int n) {
Matrix mat(n, std::vector<int>(n, 0)); // Construct Matrix Properly
int a;
for (int i = 0; i < n; i++) { // Start index at 0
a = 1;
for (int j = 0; j < i + 1; j++) { // Start index at 0
if (j == 0) // Changed 1 to 0
mat[i][j] = 1;
else
mat[i][j] = a;
a = a * (i - j) / (j+1); // Changed j to j+1 since j starts at 0
}
}
return mat;
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I am writing a C++ code for a Sudoku solver.
The code must work for a 9x9, 16x16 and 25x25 grid. My code only works for a 9x9 grid. I am not sure why. May someone please help me. I think I need to make the 16x16 and 25x25 codes work faster somehow. How do I do this?
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
using namespace std;
vector<int> tokenize(string s, string del);
void readAPuzzle(vector<vector<int>> &grid);
void printGrid(vector<vector<int>> grid);
bool isValid(int i, int j, vector<vector<int>> grid);
bool isValid(vector<vector<int>> grid);
bool search(vector<vector<int>> &grid);
int getFreeCellList(vector<vector<int>> grid, vector<pair<int, int>> &freeCellList);
int main()
{
// Read a Sudoku puzzle
vector<vector<int>> puzzle;
readAPuzzle(puzzle);
if (!isValid(puzzle))
cout << "Invalid input" << endl;
else if (search(puzzle)){
printGrid(puzzle);
}
else
cout << "No solution" << endl;
return 0;
}
vector<int> tokenize(string s, string del)
{
vector<int> row;
int start = 0;
int end = s.find(del);
while (end != -1) {
row.push_back(stoi( s.substr(start, end - start)));
start = end + del.size();
end = s.find(del, start);
}
row.push_back(stoi( s.substr(start, end - start)));
return row;
}
void readAPuzzle(vector<vector<int>> &grid){
string line;
getline(cin, line);
vector<int> firstRow = tokenize(line, " ");
grid.push_back(firstRow);
for(int i = 0; i < firstRow.size()-1; i++){
getline(cin, line);
vector<int> row = tokenize(line, " ");
grid.push_back(row);
}
}
/** Obtain a list of free cells from the puzzle */
int getFreeCellList(vector<vector<int>> grid, vector<pair<int, int>> &freeCellList)
{
// 81 is the maximum number of free cells
int numberOfFreeCells = 0;
for (int i = 0; i < grid.size(); i++)
for (int j = 0; j < grid.size(); j++)
if (grid[i][j] == 0)
{
freeCellList[numberOfFreeCells].first = i;
freeCellList[numberOfFreeCells].second = j;
numberOfFreeCells++;
}
return numberOfFreeCells;
}
/** Print the values in the grid */
void printGrid(vector<vector<int>> grid)
{
for (int i = 0; i < grid.size(); i++)
{
for (int j = 0; j < grid.size(); j++)
cout << grid[i][j] << " ";
cout << endl;
}
}
/** Search for a solution */
bool search(vector<vector<int>> &grid)
{
int k = 0; // Start from the first free cell
bool found = false; // Solution found?
const int n = grid.size();
vector<pair<int, int>> freeCellList(n*n);
int numberOfFreeCells = getFreeCellList(grid, freeCellList);
while (!found)
{
int i = freeCellList[k].first;
int j = freeCellList[k].second;
if (grid[i][j] == 0)
grid[i][j] = 1; // Start with 1
if (isValid(i, j, grid))
{
if (k + 1 == numberOfFreeCells)
{ // No more free cells
found = true; // A solution is found
}
else
{ // Move to the next free cell
k++;
}
}
else if (grid[i][j] < grid.size())
{
grid[i][j] = grid[i][j] + 1; // Check the next possible value
}
else
{ // grid[i][j] is 9, backtrack
while (grid[i][j] == grid.size())
{
grid[i][j] = 0; // Reset to free cell
if (k == 0)
{
return false; // No possible value
}
k--; // Backtrack
i = freeCellList[k].first;
j = freeCellList[k].second;
}
grid[i][j] = grid[i][j] + 1; // Check the next possible value
}
}
return true; // A solution is found
}
/** Check whether grid[i][j] is valid in the grid */
bool isValid(int i, int j, vector<vector<int>> grid)
{
// Check whether grid[i][j] is valid at the i's row
for (int column = 0; column < grid.size(); column++)
if (column != j && grid[i][column] == grid[i][j])
return false;
// Check whether grid[i][j] is valid at the j's column
for (int row = 0; row < grid.size(); row++)
if (row != i && grid[row][j] == grid[i][j])
return false;
int n = sqrt(grid.size());
// Check whether grid[i][j] is valid in the 3 by 3 box
for (int row = (i / n) * n; row < (i / n) * n + n; row++)
for (int col = (j / n) * n; col < (j / n) * n + n; col++)
if (row != i && col != j && grid[row][col] == grid[i][j])
return false;
return true; // The current value at grid[i][j] is valid
}
/** Check whether the fixed cells are valid in the grid */
bool isValid(vector<vector<int>> grid)
{
// Check for duplicate numbers
for (int i = 0; i < grid.size(); i++)
for (int j = 0; j < grid.size(); j++)
if (grid[i][j] != 0)
if (!isValid(i, j, grid))
return false;
// Check whether numbers are in the range
for (int i = 0; i < grid.size(); i++)
for (int j = 0; j < grid.size(); j++)
if ((grid[i][j] < 0) || (grid[i][j] > 9))
return false;
return true; // The fixed cells are valid
}
This is the code I have written so far.
Thank you.
In bool isValid(vector<vector<int>>) you have
if ((grid[i][j] < 0) || (grid[i][j] > 9))
return false;
ie a grid with a number > 9 is never considered valid. I cannot tell if there are other errors, but when you only allow numbers in [0,9] it cannot work for 16x16 or 25x25 sized grids.
You are passing the grid by value to some of the functions. You should pass them as const reference instead to avoid unnecessary copies.
I was trying to solve this proble:
A gallery with plants is divided into n parts, numbered : 0,1,2,3...n-1. There are provisions for attaching water sprinklers at every partition. A sprinkler with range x at partition i can water all partitions from i-x to i+x.
Given an array gallery[ ] consisting of n integers, where gallery[i] is the range of sprinkler at partition i (power==-1 indicates no sprinkler attached), return the minimum number of sprinklers that need to be turned on to water the complete gallery.
If there is no possible way to water the full length using the given sprinklers, print -1.
and this is how I ended up trying-
Create a frequency array such that the ith element contains the number of sprinklers that are watering the ith part of the gallery.
If any element of this array is zero after going through all the sprinklers, then return -1 as even if all the sprinklers tried they couldn't water each part.
Then, std::stable_sort all the sprinklers based on their range, in increasing order.
Then, remove a sprinkler if it is redundant, starting from the smallest range to the largest.
My implementation of the same-
typedef struct sprinkler {
int l;
int r;
} sprinkler;
int min_sprinklers(int gallery[], int n)
{
int freq[n];
vector<sprinkler> vec;
for(int i = 0; i < n; i++) freq[i] = 0;
for(int i = 0 ; i < n; i++) {
int x = gallery[i];
if(x == -1) continue;
int l = max(0, i - x);
int r = min(n-1, i + x);
sprinkler s;
s.l = l;
s.r = r;
vec.push_back(s);
for(int j = l; j <= r; j++) {
freq[j]++;
}
}
for(int i = 0; i < n; i++) {
if(freq[i] == 0) return -1;
}
stable_sort(vec.begin(), vec.end(), [](sprinkler s1, sprinkler s2) { return s1.r-s1.l < s2.r-s2.l; });
int sprinklers = vec.size();
for(int i = 0; i < vec.size(); i++) {
int l = vec[i].l;
int r = vec[i].r;
bool flag = false;
for(int j = l; j <= r; j++) {
if(freq[j] == 1) {
flag = true;
break;
}
}
if(!flag) {
for(int j = l; j <= r; j++) freq[j]--;
sprinklers--;
}
}
return sprinklers;
}
But I still seem to be missing something and still don't know what.
Link to try my code:
https://practice.geeksforgeeks.org/problems/410d51d667ab93f2219b15126f001f32e8bb029e/0/?category[]=Greedy&category[]=Greedy&difficulty[]=1&page=1&query=category[]Greedydifficulty[]1page1category[]Greedy#
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I've decided that i'll find the index of the max and min value and then change it, but i can't find a way to get the index:
int findmax(int row, int col, float** arr) {
float max = arr[0][0];
for (int i = 0;i < row;i++) {
for (int j = 0;j < col;j++) {
if (arr[i][j] > max) {
max = arr[i][j];
}
}
}
int p=0;
for (int i = 0;i < row;i++) {
for (int j = 0;j < col;j++) {
if (arr[i][j] != max) {
p++;
}
else if (arr[i][j]==max){
break;
}
}
}
return p;
}
The program doesn't stop when the max value is found
It only works when the array has 1 row.
The better way for your 2D array to save pair of indexes for each extreme. You could try next solution:
std::pair<int, int> findmax(int row, int col, float** arr) {
float max = arr[0][0];
std::pair<int, int> indexes;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (arr[i][j] > max) {
max = arr[i][j];
indexes = std::make_pair(i, j);
}
}
}
return indexes;
}
Your code works we expected:
int findmax(int row, int col, float** arr) {
float max = arr[0][0];
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (arr[i][j] > max) {
max = arr[i][j];
}
}
}
int p = 0;
for (int i = 0; i < row; i++) {
for (int j = 0; j < col; j++) {
if (arr[i][j] != max) {
p++;
}
else if (arr[i][j] == max) {
break;
}
}
}
return p;
}
int main()
{
float **ppAr;
ppAr = new float*[2];
for (int i = 0; i < 2; ++i) {
ppAr[i] = new float[10];
}
ppAr[0][0] = (float)1; //0
ppAr[0][1] = (float)2; //1
ppAr[1][0] = (float)4; //2 -> max
ppAr[1][1] = (float)3;
return findmax(2, 2, ppAr);
}
This one returns 2 .