I have a 6 x 6 matrix, and I am storing its values in a one dimensional array of size 36. I want to rearrange it so that the rows are the columns and the columns are the rows. My method is trying to copy the values into another array, but sorted properly. I am trying a for loop:
for (int i = 0; i < 6; ++i){
copyArray[i]= array[i*6];
}
This works fine for the first new row made up of the first column, but how do I continue to do all of them? I have tried nested for loops but cannot come up with the proper algorithm using iterators. I could do this manually, but would like to have this done by code.
I am coding in C++, but if anyone can do it in a similar language that would be fine. I feel this is a math problem.
The Question: How do I solve for switching out the rows and columns?
(Example: if I am denoting the first rows and columns as 0, in a 6x6 matrix, then both rows and columns go from 0 to 5. Therefore, by switching rows and columns, the value in row 2, column 5 would be switched with the value in row 5, column 2.)
Couldn't you just use a nested for loop and do something like this?
for (int i = 0; i < 6; ++i)
for (int j = 0; j < 6; ++j)
copyArray[i*6+j]= array[j*6+i];
Here's a test program you can run to show it works:
#include <stdio.h>
int main()
{
int array[36] = {1,1,1,1,1,1,
2,2,2,2,2,2,
3,3,3,3,3,3,
4,4,4,4,4,4,
5,5,5,5,5,5,
6,6,6,6,6,6};
int copyarray[36];
for (int i = 0; i < 6; ++i)
for (int j = 0; j < 6; ++j)
copyarray[i*6+j]= array[j*6+i];
for (int i = 0; i < 36; ++i)
{
if (i % 6 == 0)
printf("\n");
printf("%d ", array[i]);
}
printf("\n");
printf("\n");
for (int i = 0; i < 36; ++i)
{
if (i % 6 == 0)
printf("\n");
printf("%d ", copyarray[i]);
}
return 0;
}
Output:
1 1 1 1 1 1
2 2 2 2 2 2
3 3 3 3 3 3
4 4 4 4 4 4
5 5 5 5 5 5
6 6 6 6 6 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
1 2 3 4 5 6
You should keep your one-D array inside a class.
Then you can swap the dimensionality of the data without actually moving it.
class MySwapableArray
{
bool normal;
int array[36];
public:
int& operator()(int x, int y)
{
int h = normal ? x : y;
int v = normal ? y : x;
return array[h*6+v];
}
void swapRowsAndColumns()
{
normal = ! normal;
}
};
If you want to use operator[] like A[x][y] then see: How to overload array index operator for wrapper class of 2D array?
A template for doing so.
template<class X> std::unique_ptr<typename std::pointer_traits<X>::element_type[]>
transpose(const X& p, int x, int y) {
using T = std::pointer_traits<X>::element_type;
std::unique_ptr<T[]> r = new T[x*y];
for(int a = 0; a < x; ++a)
for(int b = 0; b < y; ++b)
r[x*a+b] = p[y*b+a];
return r;
}
If you want to avoid a double-for loop, you should be able to do it mathematically with something like
for (int i = 0; i < 36; ++i) {
copyarray[6 * (i % 6) + i / 6] = array[i]
}
Basically, 6 * (i % 6) aligns you to the right row in the transposed matrix, and the i / 6 (ab)uses integer division to translate the column value into a row value. floor (i / 6.0) is more correct if you can live with the clutter.
for( int i=0;i<6;i++)
for( int j=0;j<6;j++)
{ }//You can do whatever you want on original matrix here
Let's say that you want "transpose of matrix" and do some processing .Basically switch i and j
for( int j=0;j<6;j++) // replaceed i with j
for( int i=0;i<6;i++)
{ }//You can do whatever you want on transpose matrix here
Related
I am trying to traverse a 2D matrix diagonally and the function below prints all elements in a diagonal.I want to skip the first row and first column elements and start the diagonal traversal from matrix[1][1] because the values in the 0th row and 0th column are not required.So it is like slicing the matrix from the top and starting from [1][1] but not making any changes to the bottom of the matrix.
void diagonalOrder(int matrix[][COL])
{
for(int line = 1;
line <= (ROW + COL - 1);
line++)
{
int start_col = max(0, line - ROW);
int count = min(line, (COL - start_col), ROW);
/* Print elements of this line */
for(int j = 0; j < count; j++)
cout << setw(5) <<
matrix[minu(ROW, line) - j - 1][start_col + j];
cout << "\n";
}
I will update my question with an example to make it clear.Consider the following matrix.
0 1 2 3 4
matrix[5][5] = 1 8 5 3 1
2 4 5 7 1
3 6 4 3 2
4 3 4 5 6
The above function will print the values of this diagonally.
Output:
0
1 1
2 8 2
3 4 5 3
4 6 5 3 4
3 4 7 1
4 3 1
5 2
6
I want to skip the elements of the first row and the first column and starting at matrix[1][1] want to traverse the matrix diagonally.
Desired Output:
8
4 5
6 5 3
3 4 7 1
4 3 1
5 2
6
From your example it looks like you want to print antidiagonals not diagonals, ie third line is 3 4 5 3 not 3 5 4 3.
To get started keep things simple: Indices (i,j) along an antidiagonal are those i and j where i+j == some_constant. Hence this is a simple (not efficient) way to print elements along one antidiagonal:
void print_antidiagonal(int matrix[5][5],int x){
for (int i=4;i >= 0; --i) {
for (int j=0;j < 5; ++j) {
if (i+j == x) std::cout << matrix[i][j] << " ";
}
}
std::cout << "\n";
}
Further there are nrows + (ncols-1) antidiagonals, hence you can print them all via:
for (int i=0;i < 5+4; ++i) {
print_antidiagonal(matrix,i);
}
The function above isnt very efficient, but it is simple. It is obvious how to skip the first row and first column:
for (int i=4;i >= 1; --i) { // loop till 1 instead of 0
for (int j=1;j < 5; ++j) { // loop from 1 instead of 0
This is sufficient to produce desired output (https://godbolt.org/z/7KWjb7qh7). However, not only is the above rather inefficient, but also the code is not very clear about its intent. print_antidiagonal prints elements along a single anti-diagonal, hence iterating all matrix elements is a bad surprise.
I suggest to print the indices rather than the matrix elements to get a better picture of the pattern (https://godbolt.org/z/TnrbbY4jM):
1,1
2,1 1,2
3,1 2,2 1,3
4,1 3,2 2,3 1,4
4,2 3,3 2,4
4,3 3,4
4,4
Again, in each line i+j is a constant. And that constant increments by 1 in each line. In each line i decrements while j increments, until either i == 1 or j==4. The first element is such that i is maximum and j = constant - i.
Hence:
void print_antidiagonal(int matrix[5][5],int x){
int i = std::min(x-1,4);
int j = x - i;
while (i >= 1 && j <= 4) {
std::cout << matrix[i][j] << " ";
--i;
++j;
}
std::cout << "\n";
}
Live Example.
PS: I used hardcoded indices, because I considered it simpler to follow the logic. For a more realistic solution the matrix size and offset should be parametrized of course.
I don't really get what your code is trying to do but just going by the description you need to iterate over the array items with equal row and column indices until there either are no more rows or no more columns i.e.
void print_tail_of_diagonal(int matrix[ROWS][COLS])
{
int n = std::min(ROWS, COLS);
for (int i = 1; i < n; ++i) {
std::cout << matrix[i][i] << " ";
}
std::cout << "\n";
}
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 have written a program that gives random values to two matrices and then using multiplication to print out a third matrix. Matrix 1 is 3x3 (rows, columns) and Matrix 2 is (3x2).
My output is as follows:
Matrix 1:
4 6 0
9 1 5
4 7 5
Matrix 2:
4 6
0 9
1 5
matrix 1 x matrix 2:
16 78 97059710
41 88 218384285
21 112 97059715
As you can see the third matrix gives an extra row / column with weird values. (97057910 etc.)
Below is my multiply function written in C++:
Matrix Matrix::multiply(Matrix one, Matrix two) {
int n1 = one.data[0].size();
int n2 = two.data.size();
int nCommon = one.data.size();
vector< vector<int> > temp(nCommon);
for ( int i = 0 ; i < nCommon ; i++ )
temp[i].resize(n2);
for(int i=0;i<n1;i++) {
for(int j=0;j<n2;j++) {
for(int k=0;k<nCommon;k++) {
temp[i][j]= temp[i][j] + one.data[i][k] * two.data[k][j];
}
}
}
const Matrix result = Matrix(temp);
return result;
}
Does anyone have any suggestion on how to fix this issue? I want to remove that line of weird values and only have two columns.
You're getting your numbers of rows and columns mixed up. The idea is to multiply A (I x K) by B (K x J), and here's what the code does:
int n1 = one.data[0].size(); // this is K
int n2 = two.data.size(); // this is also K
int nCommon = one.data.size(); // this is I
vector< vector<int> > temp(nCommon);
for ( int i = 0 ; i < nCommon ; i++ )
temp[i].resize(n2);
// temp is now I x K, which is not what was intended,
// and the iteration over rows and columns will not be correct.
Try this instead:
int n1 = one.data.size(); // this is I
int n2 = two.data[0].size(); // this is J
int nCommon = two.data.size(); // this is K
vector< vector<int> > temp(n1);
for ( int i = 0 ; i < nCommon ; i++ )
temp[i].resize(n2);
Even though one of your matrixes has only two columns, looks like your for-loop will still attempt to access values in the third column of each row.
two.data[k][j]
k iterates from 0 to one.data.size()-1, or 0..2.
j also iterates from 0 to two.data.size()-1, also 0..2.
However, according to your description, the two's matrix's second dimension's range is only 0..1.
Undefined behavior. The code is running off past the end of the vector, and reads garbage.
I've been working on a brute force algorithm to generate all permutations of a given set. Eventually, I want to feed each of these permutations into a nxn matrix to test if it is a valid magic square or not.
--I KNOW THAT THERE IS A WAY TO GENERATE A MAGIC SQUARE EASILY--
That is not what I want to do, though. I'm focusing on the brute force aspect of it.
For a set of 3 elements, it works wonderfully. However, once I use 4 or more elements, I lose out on a few permutations. Just from looking at the output of 4, I am missing 7 permutations.
#include <stdio.h>
#include <iostream>
using namespace std;
//ms = magic square
//n = size
void perm(int ms[], int n) {
int pivot = 0;
int index = 0;
int pivBit = 1;
int fin = 0;
int hold = 0;
//While we are not finished
while (fin == 0) {
//Incriment the index
++index;
if (index >= n) {
index = 0;
}
//if index is equal to the pivot
if (index == pivot) {
//Is this the first time visiting the pivot?
if (pivBit == 0) {
//Are we at the beginning again?
if (index == 0 && pivot == 0)
{
fin = 1;
}
pivBit = 1;
++index;
}
//Second time visiting?
else {
pivBit = 0;
++pivot;
if (pivot >= n) {
pivot = 0;
}
}
}
//If we are out of bounds
if (index >= n) {
index = 0;
}
//swap
hold = ms[index];
ms[index] = ms[pivot];
ms[pivot] = hold;
for (int i = 0; i < n; ++i) {
cout << ms[i];
if (i < n - 1) {
cout << ", ";
}
else {
cout << endl;
}
}
}
}
int main() {
cout << "Are you ready to brute force, my brother?" << endl;
//Set
int magicsquare[] = { 1, 2, 3, 4};
int size = 4;
perm(magicsquare, size);
getchar();
return 0;
}
My output is:
2 1 3 4
3 1 2 4
4 1 2 3
1 4 2 3
1 2 4 3
1 3 4 2
3 1 4 2
3 4 1 2
3 4 2 1
2 4 3 1
2 3 4 1
2 3 1 4
4 3 1 2
4 2 1 3
4 2 3 1
1 2 3 4
2 1 3 4
Looking at it, I can already see that I am missing both 1 4 3 2 and 1 3 2 4.
Where've I gone wrong in my algorithm?
The wiki article on permutation includes a common algorithm used to produce all permutations in lexicographic order, starting with an array of sequentially increasing integers, ending with that array reversed. wiki next permutation.
If dealing with an array of objects, you can generate an array of indices 0 through n-1 and use next permutation on the indices to produce all permutations of the array of objects.
You can also do a web search for next permutation to find similar algorithms. The recursive ones produce all permutations, but not in lexicographic order.
The simplest way to generate all permutations is recursive. For each i, swap the i'th element to the 0 position. Then recursively find all permutations of of the remaining array.
int buf[1000], n; // better to wrap these in a class...
void permute(int *a, int a_len) {
if (a_len == 1) {
for (int i = 0; i < n; i++) printf("%d ", buf[i]);
printf("\n");
} else {
for (int i = 0; i < a_len; i++) {
swap(a, 0, i);
permute(a + 1, a_len - 1);
swap(a, 0, i);
}
}
}
void run(int buf_len) {
for (int i = 0; i < buf_len; i++) buf[i] = i + 1;
n = buf_len;
permute(buf, buf_len);
}
This assumes no repeated elements in the original array. It's not to hard to have it take repeated elements into account.
I'm trying to get a specific element inside of a vector.
For example,
Lets say I have a vector.
std::vector<Tile> TileList;
The Vector is of size MAP_HEIGHT = 30, MAP_WIDTH = 200
So its total size is MAP_HEIGHT * MAP_WIDTH = 6000.
I use a double nested for loop to iterate through and create a vector full of tiles.
for(int Y = 0; Y < MAP_HEIGHT; Y++)
{
for(int X = 0; X < MAP_WIDTH; X++)
{
Tile TempTile;
fscanf(FileHandle, "%d:%d ", &TempTile.TileID, &TempTile.TypeID);
TileList.push_back(TempTile);
}
}
Now my questions is lets say I iterate through
int ID = 0;
for(int Y = 0; Y < MAP_HEIGHT; Y++)
{
for(int X = 0; X < MAP_WIDTH; X++)
{
TileList[ID].do stuff with it
//Check for the tile above this tile
// Find a way to calculate the ID of the tile above this tile
int IDoftilabove = ID - do something;
if(TileList[IDoftilabove].variable == TILE_SOMETHING)
{
do stuff
}
ID++;
}
How do I calculate the ID of an element above(well technically before this ID) inside the vector based on the current element I'm on.
Illustration:
say i have a matrix 5x5,
Lets say my current ID is 8. so I am on the second row number 3.
1 2 *3* 4 5
1 2 (3) 4 5
1 2 3 4 5
1 2 3 4 5
1 2 3 4 5
Now I want the ID of the element in vector that is directly above me which is the ID 3, first row number 3. and this is just assuming the the MAP_WIDTH = 5 and the MAP_HEIGHT = 5.
8 - 5 = 3
Current - MAP_WIDTH = Above
You can easily determine the (row,col) coordinates given the ID:
row = ID / MAP_WIDTH;
col = ID % MAP_WIDTH;
If you want to know what is the coordinate from the element above:
row--;
ID_above = row * MAP_WIDTH + col;
The same applies if you want to know what is the element below:
row++;
ID_below = row * MAP_WIDTH + col;
It seems like you want to map between linear and 2d indices. This is pretty straightforward.
int rect2lin(int w, int x, int y) { return y*w+x; }
void lin2rect(int w, int i, int * x, int * y) { *y = i/w; *x = i%w; }
So in your example, the ID of the element above (X,Y) would be rect2lin(MAP_WIDTH, X,Y-1), which is simply (Y-1)*MAP_WIDTH+X. This generalizes straightforwardly to higher numbers of dimension. For example, i=(z*h+y)*w+x for 3d, and so on.