So here is my code for the knight's tour problem, and I have been pulling my hair out trying to figure out what is wrong with it.
#include <iostream>
#include <vector>
using namespace std;
void Knights_tour(int x, int y, int move_count);
bool isSafe(int x, int y);
int m,n,start_x,start_y;
int valid_x [8] = {2,2,-2,-2,1,1,-1,-1};
int valid_y [8] = {1,-1,1,-1,2,-2,2,-2};
vector<vector<int>> board;
int main(int argc, char* argv[])
{
m=atoi(argv[1]);
n=atoi(argv[2]);
start_x=atoi(argv[3]);
start_y=atoi(argv[4]);
board.resize(m);
for(int i=0; i<m; i++)
board[i].resize(n);
Knights_tour(start_x, start_y, 1);
for(int i=0; i<m; i++)
{
for(int j=0; j<n; j++)
{
cout<<"[ "<<board[i][j]<<" ]";
}
cout << endl;
}
return(0);
}
void Knights_tour(int x, int y, int move_count)
{
board[x][y]=move_count;
if(move_count==(m*n))
{
cout << "Success!" << endl;
return;
}
for(int i=0; i<8; i++)
{
if(isSafe((valid_x[i]+x), (valid_y[i]+y)))
{
move_count++;
Knights_tour((valid_x[i]+x), (valid_y[i]+y), move_count);
}
}
}
bool isSafe(int x, int y)
{
if(x>=0 && x<n && y>=0 && y<m && board[x][y]==0)
return true;
else
return false;
}
It takes the dimensions of the board as well as the starting coordinates through the command line. For example, running "./Knight 5 5 0 0" yields a 5x5 matrix and starts at coordinate 0. Here is what that looks like
[ 1 ][ 18 ][ 16 ][ 12 ][ 15 ]
[ 17 ][ 13 ][ 13 ][ 7 ][ 15 ]
[ 17 ][ 2 ][ 9 ][ 4 ][ 11 ]
[ 14 ][ 18 ][ 6 ][ 14 ][ 8 ]
[ 8 ][ 16 ][ 3 ][ 10 ][ 5 ]
As you can see it works perfectly up until 13, when it begins repeating itself. I cannot figure out why my recursive function would do this. Any help would be appreciated. Thank you
If I understand your code correctly, you are trying to find one Knights tour of an mxn board using recursive bruteforce trying every possible solution.
The error probably happens because recursive calls not leading to a solution still modifies the board, but doesn't backtrack to clear up the modified board values. Other recursive calls then fail to find a solution since board[x][y]==0 fails.
One solution is to pass a copy of the board onto every recursive call, and then return the board at the end.
Also: using bruteforce, you can probably not expect to find a tour for much larger boards since the running time increases exponentially asymptotically.
edit: typos
edit2: added possible solution
Creating a whole copy of the board on each call would use a lot of memory. I think you can avoid it by having Knights_tour return a bool which is true when a solution is found. The return value can be used when you unwind the stack to decide on if you should unset board[x][y].
if(!Knights_tour((valid_x[i]+x), (valid_y[i]+y), move_count))
{
board[x][y] = 0;
}
Related
Problem statement:
Check if two arrays are equal or not.Two arrays are said to be equal if both of them contain same set of elements, arrangements (or permutation) of elements may be different though.
This is the snippet of my code
#include <iostream>
#include<algorithm>
using namespace std;
int main() {
int t; cin>>t;
while(t--)
{
int n,i;
cin>>n;
int arr1[n],arr2[n];
for(i=0;i<n;i++)
cin>>arr1[i];
for(i=0;i<n;i++)
cin>>arr2[i];
sort(arr1,arr1+n);
sort(arr2,arr2+n);
for(i=0;i<n;i++)
{
if(arr1[i]!=arr2[i])
break;
i++;
}
if(i==n) cout<<"1\n";
else cout<<"0\n";
}
return 0;
}
For Input:
2 [ number of test cases ]
5 [ size of the array for test case #1 ]
1 2 5 4 0 [ array 1 ]
2 4 5 0 1 [ array 2 ]
3 [ size of the array for test case #1 ]
1 2 5 [ array 1 ]
2 4 15 [ array 2 ]
Expected Output
1
0
My code's output
0
0
You donot have to increment i++ again inside for loop.
for(i=0;i<n;i++) //As,i already gets incremented here
{
if(arr1[i]!=arr2[i])
break;
// i++;
}
I am working on a class that I have some problems in finding positions of values in one of elements of the class. I have defined my class as follows:
typedef class Chrom
{
public:
vector<vector < int>> bit;
vector<vector < bool>> jobisconsidered;
vector<vector <float>> WaitingTime;
void variablesresize()
{
int i = 0, j, k;
float a;
std::vector<float> datapoints;
std::ifstream myfile("Input.dat", std::ios_base::in);
i = 0; //making zero counter of characters
myfile.open("Input.dat");//now we reread numerical values
while (!myfile.eof())
{
myfile >> a;
// cout << "i=" << i << '\n';
if (!myfile) // not an int
{
myfile.clear(); // clear error status
myfile.ignore(1); // skip one char at input
}
else
{
datapoints.push_back(a);
++i;
}
}
myfile.close();
Jobs = datapoints[0];
Machines = datapoints[1];
WaitingTime.resize(Machines);
bit.resize(Machines);
for (int i = 0; i < Machines - 1; ++i) WaitingTime[i].resize(Jobs);
bit[i].resize(Jobs);
}
}
} c;
c popcurrent[50];
In the class, bit is a 2D element and if I define it as m*n, all values in the rows are the same. However, when I want to find position in bit, for example if popcurrent[0].bit for 2 rows and 3 columns is = { {3,2,1},{3,2,1} }, and I want to find position of the first "3" in the vector is 0 and popcurrent[0].bit[0][0]=3 , I have problems.
Specificaly I tried c++ search a vector for element first seen position with the following commands:
auto p = std::lower_bound(popcurrent[0].bit.begin(), popcurrent[0].bit.end(), 1);
int position = p - popcurrent[0].bit.begin();
But I get following error:
Error 109 error C2893: Failed to specialize function template
'unknown-type std::less<void>::operator ()(_Ty1 &&,_Ty2 &&) const'
I know one way is to use for and if loops. But I wonder is there any more automated way to do this such as build in functions.
I didn't notice it at first - there's too much irrelevant code - but the problem is quite simple: you're trying to find the first element of type std::vector<int> not less than value of type int.
popcurrent[0].bit.begin() points to the first element of std::vector<std::vector<int>>, that is a vector. There's no "less than" operator for comparing a vector of ints and an int.
I want to find position of the first "3" in the vector is 0 and
popcurrent[0].bit[0][0] = 3 , I have problems. Specificaly I tried
c++ search a vector for element first seen position with the following
commands:
auto p=std::lower_bound(popcurrent[0].bit.begin(), popcurrent[0].bit.end(), 1);
int position = p - popcurrent[0].bit.begin();
There are mainly two problems:
Problem - 1: std::lower_bound takes parameters first, last, which are forward-iterator types which defining the partially-ordered range. In your case(popcurrent[0].bit.begin()), you are passing a iterator which has the pointed element as a vector of integers (remember std::vector<std::vector<int>> is an array of vectors(vector<int>) not integers) for which std::lower_bound, could not find any definition for operator<. This is the reason of your error, where compiler complaining that:
" Hey, I don't have a specialisation for operator< your given range
or vectors, to instantiate the template "
Problem - 2: You can not use std::lower_bound here, as it needs a strictly sorted array to binary search the value which has been provided. As you provided an unsorted vectors to check, the result won't be correct. See above link to read more:
Solution: You can use std::find_if which has a time complexity, up to linear in the distance between first and last iterator, according to the predicate provided, which will search for each element until a match is found. This could be an alternative if you do not want to sort each vector in the class, which is actually a 3-dimensional array of vectors.
Following is a sample solution: SEE LIVE HERE
#include <iostream>
#include <vector>
#include <algorithm>
#include <tuple>
typedef std::vector<std::vector < int>> Type ;
struct Chrom // to demonstrate
{
Type bit;
};
std::tuple<int, int, int> findPosition(const std::vector<Chrom>& vec3D, const int& val)
{
int First = 0, Second = 0, Third = -1; // initilize the positions
for(const Chrom& each_chrom: vec3D)
{
for(const std::vector<int>& innerVec: each_chrom.bit)
{
std::vector <int>::const_iterator get_pos;
get_pos = std::find(innerVec.cbegin(), innerVec.cend(), val);
Third = (*get_pos == val) ? get_pos - innerVec.cbegin(): -1; // check val found otherwise -1
if(Third != -1) return std::make_tuple(First, Second, Third); // if found return them
++Second;
}
Second = 0;
Third = -1;
++First;
}
return std::make_tuple(First, Second, Third);
}
int main()
{
// this is a 3 dimensional vector
std::vector<Chrom> popcurrent(2); // position inside the popcurrent
popcurrent[0].bit = { {3,2,1}, // (0,0,0) (0,0,1) (0,0,2)
{3,10,1} }; // (0,1,0) (0,1,1) (0,1,2)
popcurrent[1].bit = { {5,8,11}, // (1,0,0) (1,0,1) (1,0,2)
{4,7,1} }; // (1,1,0) (1,1,1) (1,1,2)
int pos_popcurrent, pos_bit, pos_inner_vec;
for(int val = 1; val <= 12; ++val)
{
std::cout << "\nCurrently looking for: " << val ;
std::tie(pos_popcurrent, pos_bit, pos_inner_vec) = findPosition(popcurrent, val);
(pos_inner_vec != -1) ?
std::cout << " found # popcurrent[ " << pos_popcurrent << " ].bit[ " << pos_bit << " ][ " << pos_inner_vec <<" ]":
std::cout << " Not found";
}
return 0;
}
Output:
Currently looking for: 1 found # popcurrent[ 0 ].bit[ 0 ][ 2 ]
Currently looking for: 2 found # popcurrent[ 0 ].bit[ 0 ][ 1 ]
Currently looking for: 3 found # popcurrent[ 0 ].bit[ 0 ][ 0 ]
Currently looking for: 4 found # popcurrent[ 1 ].bit[ 1 ][ 0 ]
Currently looking for: 5 found # popcurrent[ 1 ].bit[ 0 ][ 0 ]
Currently looking for: 6 Not found
Currently looking for: 7 found # popcurrent[ 1 ].bit[ 1 ][ 1 ]
Currently looking for: 8 found # popcurrent[ 1 ].bit[ 0 ][ 1 ]
Currently looking for: 9 Not found
Currently looking for: 10 found # popcurrent[ 0 ].bit[ 1 ][ 1 ]
Currently looking for: 11 found # popcurrent[ 1 ].bit[ 0 ][ 2 ]
Currently looking for: 12 Not found
problem statement:
Johnny has some difficulty memorizing the small prime numbers. So, his computer science teacher has asked him to play with the following puzzle game frequently.
The puzzle is a 3x3 board consisting of numbers from 1 to 9. The objective of the puzzle is to swap the tiles until the following final state is reached:
1 2 3
4 5 6
7 8 9
At each step, Johnny may swap two adjacent tiles if their sum is a prime number. Two tiles are considered adjacent if they have a common edge.
Help Johnny to find the shortest number of steps needed to reach the goal state.
My solution so far
#include<bits/stdc++.h>
using namespace std;
bool prime[20];
int matrix[3][3];
int solved[3][3] = {
{1,2,3},
{4,5,6},
{7,8,9}
};
void display()
{
for(int row = 0; row<3;row++)
{
for(int col = 0;col<3;col++)
{
cout<<matrix[row][col]<<" ";
}
cout<<endl;
}
cout<<endl<<endl;
}
bool check(){
for(int i=0;i<3;i++){
for(int j=0;j<3;j++){
if(matrix[i][j]!=solved[i][j])
return false;
}
}
return true;
}
int min(int a,int b)
{
return (a<b)?a:b;
}
void generate(){
memset(prime,true,sizeof(prime));
for(int i=2;i*i<20;i++){
if(prime[i]==true)
{
for(int j=2*i;j<20;j+=i)
prime[j]=false;
}
}
}
int getMoves(int row, int col){
if(row < 0 ||col< 0 || row>=3||col>=3){
return 0;
}
if(check()){
return 0;
}
int moves = 0;
for(int i = row-1 ; i<= row+1 ;i++)
{
for(int j = col -1 ; j<=col+1;j++)
{
if((i!=row-1&&j!=col-1)||(i!=row+1&&j!=col+1)||(i!=row+1&&j!=col-1)||(i!=row-1&&j!=col+1)){
if(prime[matrix[row][col]+matrix[i][j]]==true)
{
moves+=getMoves(i,j);
int temp;
temp = matrix[i][j];
matrix[i][j] = matrix[row][col];
matrix[row][col] = temp;
display();
}
}
}
}
return moves;
}
int Moves(){
int minMoves = INF;
for(int row = 0;row<3;row++)
{
for(int col = 0;col<3;col++)
{
int moves = getMoves(row,col);
minMoves = min(moves,minMoves);
}
}
return minMoves;
}
int main(){
generate();
int t;
cin>>t;
while(t--)
{
for(int row = 0; row<3;row++)
{
for(int col = 0;col<3;col++)
{
cin>>matrix[row][col];
}
}
}
cout<<Moves();
}
sample testcase
Input:
2
7 3 2
4 1 5
6 8 9
9 8 5
2 4 1
3 7 6
Output:
6
-1
the program keeps crashing I guess because of memory overflow issue.
if (row < 0 || col< 0 || row >= 3 || row <= 3) {
return 0;
}
The code after this part is 'not accessible' because this condition is always true (... row >= 3 || row <= 3). You probably meant to write: (... row >= 3 || col >= 3)
I'm afraid your code is completely wrong and I don't think it could by fixed without complete rewrite. For example in function getMoves() your variables i and j can acquire value -1 so you will face access violation error. Secondly you have a recursion there, but you don't change data before you invoke recursion. Let's assume you want to swap 7 and 4. In the next step (because you didn't change input) you can swap 4 and 1. But it's not a correct move, because in that time, 4 should't be there. Thirdly your function getMoves() can end in an endless loop.
In conclusion, these kinds of problem are solved quite differently. You can for exmaple use backtracking algorithm or you can use A* algorithm. You will have to evaluate your current state. Let assume the following state:
7 3 2
4 5 6
1 8 9
You can measure number of moves that the number has to do to go to its correct position. So in this case 1 has to do 2 moves, 7 has to do 2 moves, 2 has to do 1 move as well as the number 3. The value of this state is 2 + 2 + 1 + 1 = 6. It's called an heuristic function. Now you can take this function and put it in an A* algorithm, and you should see the correct result.
I can't figure out the logic behind this one... here's what I have so far:
#include <iostream>
using namespace std;
int thearray[4][4];
int NbPos = 4;
int main() {
int i2;
int q2;
for(int i = 1; i < 4; i++) {
for(int q = 1; q < 4; q++) {
for(int c = 0; c < NbPos; c++) {
thearray[i][q] = c;
}
}
}
}
This is filling the array up to the end is still:
3 3 3
3 3 3
3 3 3
but it's doing so without hitting anywhere near every possible combination.
Ideally once it gets to:
0 0 0
0 0 0
0 0 3
the next step SHOULD be:
0 0 0
0 0 0
0 1 0
so it hits a TON of combinations. Any ideas on how to make it hit them all? I'm stumped on the logic!
with the way you're iterating over this, a 1-dimensional array would make the looping simpler. you can still mentally treat it to have rows and columns, however they are just layed out end-to-end in the code.
you could try something like this; however if you want it in a 2D format specifically that challenge is left to you ;)
#include <iostream>
using namespace std;
#define rows 4
#define columns 4
int main() {
int thearray[rows * columns] = {0};
int NbPos = 4;
int lastPos = rows * columns - 1;
while (true) {
thearray[lastPos]++;
int pos = lastPos;
while (thearray[pos] == NbPos and pos >= 1) {
thearray[pos - 1]++;
thearray[pos] = 0;
pos--;
}
bool finished = true;
for (int i = 0; i < rows * columns; i++) {
if (thearray[i] != NbPos - 1) {
finished = false;
}
}
if (finished) {
break;
}
}
for (int i = 0; i < rows * columns; i++) {
std::cout << thearray[i] << " ";
if (i % rows == rows - 1) {
cout << endl; // makes it look like a 2D array
}
}
}
It makes sense to have the final form as all 3s , since you loop every element of the array and you assign it at the end with 3 .
So the next element will only take into account the combination with the final value of the previous element (which will be 3).
Thinking in math terms, your complexity is N^3 so to speak (actually is N^2 * 4 , but since your N is 3 ...).
Your approach is wrong, since you want to find permutations, which are defined by a factorial function , not a polinomial function.
The necessary complexity for the output doesn't match the complexity of your algorithm (your algorithm is incredbily fast for the amount of output needed).
What you are looking for is backtracking (backtacking will match the complexity needed for your output).
The recursion function should be something like this (thinking on a 1D array, with 9 elements):
RecursiveGeneratePermutations(int* curArray, int curIdx)
{
if (curIDX==9)
{
for (int i=0; i<9;i++)
{
// write the array
}
} else {
curArray[curIdx]=0;
RecursiveGeneratePermutations(curIdx+1);
curArray[curIdx]=1;
RecursiveGeneratePermutations(curIdx+1);
curArray[curIdx]=2;
RecursiveGeneratePermutations(curIdx+1);
curArray[curIdx]=3;
RecursiveGeneratePermutations(curIdx+1);
}
}
Now you only need to call the function for the index 0 :
RecursiveGeneratePermutations(arrayPtr,0);
Then wait...allot :).
I am trying to create a minesweeper game that loads the board from a flat file (no, it's not random). As per the assignment instructions, I am to pass a 2d array to a load function which will then parse the file which was passed as a command-line arguement.
Anyway, my problem is passing the 2D array. What is the proper way to go about doing it? Below is the code that I have thus-far:
#include <iostream>
using namespace std;
struct Tile
{
bool mine, visible;
int danger;
};
bool loadBoard( Tile **board, string filename );
const int gridSize = 6;
int main( int argc, char* argv[] )
{
Tile board[ gridSize ][ gridSize ];
loadBoard( board, argv[ 1 ] );
system("PAUSE");
return EXIT_SUCCESS;
}
bool loadBoard( Tile **board, string filename ) {
}
Since you're using C++, why not use
std::vector<std::vector<Tile>>
in preference to a C-style array?
Since you seem to need to use C-style arrays, you could use the approach arpanchaudhury suggests or you could pass Tile* and do something like
static void loadBoard(Tile *board, int rows, int cols, string filename) {
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
Tile* tile = &board[(row*gridSize)+col];
// populate Tile
}
}
}
In case you want to to pass the 2d-array please specify number of columns in the array.
bool loadBoard( Tile board[][size], string filename ) {}
though it is preferable to use vectors instead of simple arrays since you need not specify a pre-defined size
As long as you're using C++...
#include <iostream>
using namespace std;
struct Tile
{
bool mine, visible;
int danger;
};
// load a square board of declared-size.
template<size_t N>
void loadboard( Tile (&board)[N][N], const std::string& filename)
{
// load board here.
cout << "Loading from file: " << filename << endl;
for (size_t i=0;i<N;++i)
{
cout << "board[" << i << "]: [ ";
for (size_t j=0;j<N;++j)
{
// load element board[i][j] here
cout << j << ' ';
}
cout << ']' << endl;
}
cout << endl;
}
int main()
{
Tile board[6][6];
loadboard(board, "yourfilename.bin"); // OK dims are the same
Tile smaller[3][3];
loadboard(smaller, "anotherfile.bin"); // OK. dims are the same
// Tile oddboard[5][6];
// loadboard(oddboard, "anotherfile.bin"); // Error: dims are not the same.
return 0;
}
Output
Loading from file: yourfilename.bin
board[0]: [ 0 1 2 3 4 5 ]
board[1]: [ 0 1 2 3 4 5 ]
board[2]: [ 0 1 2 3 4 5 ]
board[3]: [ 0 1 2 3 4 5 ]
board[4]: [ 0 1 2 3 4 5 ]
board[5]: [ 0 1 2 3 4 5 ]
Loading from file: anotherfile.bin
board[0]: [ 0 1 2 ]
board[1]: [ 0 1 2 ]
board[2]: [ 0 1 2 ]
Of course, there are probably "specific instructions" to not use the templates feature of the language either. Then again, I bet those instructions don't include having SO users solve your problem either, so I don't take much stock in those being followed rigorously anytime soon.