Moving through each element of a (potentially non square) 2d array, diagonally - arrays

I was playing around with 2d arrays in c, and I am wondering how to traverse a 2d array, fully and diagonally.
Horizontally, in the matrix of dimensions width,height
you can just move through each index i, and inspect elements at index j
Something like:
const int width = 10;
const int height = 10;
const int mat[width][height] = {0};
for (i = 0, i<width, i++){
for (j = 0; j<height; j++){
mat[i][0] = j;
}
}
I just added in something random so the loop did something..., however, the key is that I was traversing in the correct direction
vertically would be similar, with some flipped parameters
however diagonally...I am a bit lost; I cannot think of a way to traverse in a diagonal way. Conceptually I may want to hit the 4x3 matrix in the following order:
1 2 4 7
3 5 8 10
6 9 11 12
Or with indices i,j :
0,0 ->
1,0 -> 0,1 ->
2,0 -> 1,1 -> 0,2 ->
2,1 -> 1,2 -> 0,3 ->
2,2 -> 1,3 ->
2,3
Is there a straightforward way to hit these elements(not necessarily in that order per say, but I think it would be useful to increment diagonally)
Also, is it possible to check the diagonals in the opposite direction ?

For diagonal traverse, use only one for loop, as both i and j are identical:
for (i = 0, i < min(width, hight), i++){
// something to do with element[i][i]
}

This is a duplicate of Traverse Matrix in diagonal strips where is it suggested something like :
int main(void)
{
int m[3][4] = { 1, 2, 4, 7,
3, 5, 8,10,
6, 9,11,12 };
const int h = 3; /* height*/
const int w = 4; /* width */
for (int diag = 0; diag < (w + h - 1); ++diag)
{
printf("diag %d:",diag);
int i_start = diag < w ? 0 : diag - w + 1;
int i_end = diag < h ? diag + 1 : h;
for (int i = i_start; i < i_end; ++i)
{
printf("%d ",m[i][diag - i]);
}
printf("\n");
}
return 0;
}
Output:
diag 0:1
diag 1:2 3
diag 2:4 5 6
diag 3:7 8 9
diag 4:10 11
diag 5:12

Related

Splitting a 2D array size to a smaller 2D Array size in C

Disclaimer: I'm not very good with words, I have included a sample of how will it look like below.
So I'm trying to reduce this 4x4 array into a bunch of 2x2 arrays. (See sample below)
int disp[4][4] = {{12,4,32,9}, {19,24,3,4},{1,26,3,8},{3,24,7,5} };
/*
12 4 32 9 12 4 | 32 9
19 24 3 4 into something like 19 24 | 3 4
1 26 3 8 =============
3 24 7 5 1 26 | 3 8
3 24 | 7 5
*/
Take note: it is splitting it into smaller sizes (bunch of 2D arrays)
I have tried splitting it using a for loop code but only getting the 2nd quadrant.
code below:
int i,j;
for(i=0;i<2;i++)
for(j=0;j<2;j++)
printf("%d\n",disp[i][j]);
see that this only gives me 12,4,19 and 24.
Is there a way to get the other quadrants? How would this work for bigger sizes? (Lets say 28x28 to 14x14) I would really appreciate the help. Thank you.
Let's consider a NXN matrix where N and quadrant_size be the required size of sub_matrix to be printed.
We first traverse to find the starting element to be printed in each sub_matrix.
i.e: From 0 to N incrementing by quadrant_size for row and 0 to N incrementing by quadrant_size for column.(First two loops in the below given code)
Let's say (x,y) index at any position. Now we print the matrix elements from (x,y) to (x+2,y+2)
The below code is generalized for any size of matrix NxN of required quadrant_size where N should be divisible by quadrant_size.
int quadrant_size=2;
//outer loop to traverse the starting elements of the sub array
for(int x=0 ; x<N ; x+=quadrant_size){
for(int y=0 ; y<N ; y+=quadrant_size){
//inner loop to print matrix
for(int i=x ; i<x+quadrant_size ; i++){
for(int j=y ; j<y+quadrant_size ; j++){
printf("%d ",disp[i][j]);
}
printf("\n");
}
printf("\n");
}
}
You need to add an offset to i and j depending on which quadrant you want to print.
For your specific case it could be:
int main() {
int disp[4][4] = {{12,4,32,9},
{19,24,3,4},
{1,26,3,8},
{3,24,7,5} };
// calculate quadrant size (it will be 2 in this case)
int qsize = sizeof disp[0] /sizeof disp[0][0] / 2;
int q = 3; // <--- The quadrant to print
int offset_i = 0; // Extra offsets for
int offset_j = 0; // the loop that prints
if (q == 1)
{
offset_j = qsize;
}
else if (q == 3)
{
offset_i = qsize;
}
else if (q == 4)
{
offset_i = qsize;
offset_j = qsize;
}
for(int i=0; i<qsize; i++)
{
for(int j=0; j<qsize; j++)
{
printf("%d ",disp[i + offset_i][j + offset_j]);
// Notice: ^^^^^^^^^^ ^^^^^^^^^^
}
printf("\n");
}
return 0;
}

set of directions for an array to follow in C

So for my coding class (in C), we had to write a program that would fill a square of N >=4 elements in a certain manner (from left to right and then down and then right to left to go up and end at the origin).
After a while, and getting a solution with layers repeating the set of instructions for each circle we get this program:
#include <stdio.h>
#define N 4
int main(void){
int map[N][N];
int dirs[4][2] = {
{0, 1},
{1, 0},
{0, -1},
{-1, 0}
};
for (int layer=0; layer < (N+1)/2; layer++){
// for each layer the starting point is (layer, layer)
// for each layer and each direction the number of repeat is N - layer*2 -1
int x=layer, y=layer;
int number = 1;
map[x][y] = number; // in case of N is odd
for (int dir=0; dir < 4; dir ++){
for (int i=0; i<N-layer*2-1; i++){
map[x][y] = number;
number ++;
x = x + dirs[dir][0];
y = y + dirs[dir][1];
}
}
}
printf("Final map is: \n");
for (int i = 0; i < N; i++){
for (int j = 0; j < N; j++){
printf("%4d ", map[i][j]);
}
printf("\n");
}
return 0;
}
Output:
Final map is:
1 2 3 4
12 1 2 5
11 4 3 6
10 9 8 7
Process finished with exit code 0
But I don't understand why do we put the supposed last instruction {0,1} (meaning go up 1 element and stay on said column) as the first instruction, considering we start counting from 1 and end up at 4 by repeating the {0,1} instruction N-layer*2-1 times (3 if n=4 and in the first layer).
Shouldn't dirs be:
int dirs[4][2] = {
{1, 0},
{0, -1},
{-1, 0},
{0, 1}
};
(0,1) means moving from column y=0 to column y=1 thus moving rightwards (ryyker's comment enlightens this).

Subtracting a value from lines of a matrix

I have the following matrix:
1 4 5
5 7 6
5 8 8
I want to find the minimum value of line 1 and subtract from all values of the same line. The same thing for line 2 and 3. The minimum value of line 1 is 1, line 2 is 5 and line 3 is 5. So I subtract 1 from all values of line 1, subtract 5 from all values in line 2 and subtract 5 from all values in line 3.
0 3 4
0 2 1
0 3 3
My matrix is called "a":
min = a[0][0] \\\ min = minimum value
for (k = 0; k < 3; k++) {
for (l = 1; l < 3; l++) {
if (a[k][l] < min)
min = a[k][l - 1];
}
for (l = 0; l < 3; l++) {
a[k][l] = a[k][l] - min;
}
min = a[k+1][0];
}
For k = 0, the value a[k+1][0] = 5 is changing to 4. Why is that?
EDIT: I declared the array as:
a[0][0] = 1;
a[0][1] = 4;
a[0][2] = 5;
a[1][0] = 5;
a[1][1] = 7;
a[1][2] = 6;
a[2][0] = 5;
a[2][1] = 8;
a[2][2] = 8;
Following Kresimir I changed the code to:
for (k = 0; k < 3; k++) {
min = 10000;
for (l = 0; l < 3; l++) {
if (a[k][l] < min)
min = a[k][l];
}
for (l = 0; l < 3; l++) {
a[k][l] = a[k][l] - min;
}
}
To print the matrix:
for (i = 0; i < 3; i++) {
for (j = 0; j < 3; j++) {
printf("a[%d][%d] = %d\n", i, j, a[i][j]);
}
}
But the output is:
a[0][0] = 0
a[0][1] = 3
a[0][2] = 0
a[1][0] = 0
a[1][1] = 3
a[1][2] = 0
a[2][0] = 0
a[2][1] = 0
a[2][2] = 3
When k = 0, the first line is changed correctly and the rest is kept the same as they should, when k = 1, all lines are changed wrong to the above.
When approaching any bit of coding, it generally helps to break your coding tasks down into a series of individual steps -- that then provide a road-map to follow as you begin actual coding. You can type the steps out in a separate editor window, (or what I find just as helpful is an 8 1/2 x 11 sheet of paper and pencil).
Think through what your code must do and write it down, e.g.
loop over all rows in the matrix (a/k/a the 2D array of int);
loop over all column values to find the minimum in each row; and finally
loop over all column values (again) subtracting the minimum from each value.
You don't have to get it perfect the first time, now look again at the steps you have written and determine if there are any constraints you must impose.
(Here, yes, you must determine the minimum by examining each value in a row before you can begin subtracting the minimum from each value -- this necessitates at least two loops over the column values. Further, you must also reset or re-initialize your min variable so that it holds the minimum for the current row -- not the minimum from the last row that just happened to be less than this one. Use the re-initialization requirement to make a logical choice for the scope within which each variable should be declared)
Now with your steps refined with any constraints you must impose, you can logically lay out your code (keeping in mind that you must always protect against reading or writing beyond your array bounds, etc.) With the benefit of a good outline, you know you will need one outer loop that loops over all rows, and then two inner loops that (a) find the minimum, and (b) subtract that from all values in that row. You could do something similar to:
#include <stdio.h>
#include <limits.h> /* for INT_MAX, INT_MIN */
#define ASZ 3 /* if you need a constant, define one (or more), a size */
int main (void) {
int a[][ASZ] = {{ 1, 4, 5 }, { 5, 7, 6 }, { 5, 8, 8 }};
puts ("Original matrix:"); /* output original matrix */
for (int row = 0; row < ASZ; row++) {
for (int col = 0; col < ASZ; col++)
printf (" %2d", a[row][col]);
putchar ('\n');
}
puts ("\nModified matrix:"); /* subtract row-min from each element */
for (int row = 0; row < ASZ; row++) { /* loop over rows */
int min = INT_MAX; /* declare min = INT_MAX */
for (int col = 0; col < ASZ; col++) /* loop over column vals */
if (a[row][col] < min) /* find row-min value */
min = a[row][col];
for (int col = 0; col < ASZ; col++) { /* loop over column vals */
a[row][col] -= min; /* subtract row-min value */
printf (" %2d", a[row][col]); /* output new value */
}
putchar ('\n');
}
}
Example Use/Output
$ ./bin/mtrx_subtract_rowmin
Original matrix:
1 4 5
5 7 6
5 8 8
Modified matrix:
0 3 4
0 2 1
0 3 3
There is no magic to it, it just takes approaching each problem in a systematic way. Doing it often enough, it gets easier each time. Pay attention to where each variable was declared (or constant defined) and understand why. Let me know if you have any further questions.
If you want to find the minimum for each line, you need to initialise it for each line, not only once.
for (k = 0; k < 3; k++) {
min = a[k][0];
...
You were only searching for the minimum so far.
Whenever I'm looking for a minimum, I set min to positive infinity (nothing can be larger than that - you don't have to do it, but it makes for a nicer code, in my opinion).
Alternatively, you can use min = Math.min(...a[k]); instead of that entire first for loop (will not work on IE, though).
Also, keep in mind that indices go from 0 to 2. Also, check the order of k and l (depending on how you implement the rows and columns of the matrix).
let k, l, min;
let a=[[1, 4, 5],
[5, 7, 6],
[5, 8, 8]];
for (k = 0; k < 3; k++) {
min = +Infinity;
for (l = 0; l < 3; l++) {
if (a[k][l] < min)
min = a[k][l];
}
for (l = 0; l < 3; l++) {
a[k][l] = a[k][l] - min;
}
}
console.log(a);

A bug on bubble sorting

I want to sort a 2*n matrix, n is given in the input. Make a program to output a matrix. Here is the requirement:
the first column MUST be sorted in ASC, and
the second column in DESC if possible.
For example, let n = 5, and the matrix is
3 4
1 2
3 5
1 6
7 3
The result should be
1 6
1 2
3 5
3 4
7 3
So I write down the code like this. First line input the value n, and the following lines like above.
#include <stdio.h>
#define TWO_16 65536
#define TWO_15 32768
int v[100000][2];
int z[100000];
int vec[100000];
int n;
int main()
{
int i, j;
scanf ("%d", &n); // give the value of n;
for (i = 1; i <= n; i++) // filling the matrix;
{
scanf ("%d%d", &v[i][0], &v[i][1]);
z[i] = TWO_16 * v[i][0] + TWO_15 - v[i][1];
vec[i] = i;
}
for (i = 1; i <= n; i++)
for (j = 1; j <= i; j++)
{
if (z[j] > z[i])
{
int t = vec[i];
vec[i] = vec[j];
vec[j] = t;
}
}
for (i = 1; i <= n; i++) // output the matrix
printf("%d %d\n",v[vec[i]][0],v[vec[i]][1]);
return 0;
}
But in gcc, the output is
1 6
3 5
3 4
1 2
7 3
What's more, when the first line is changed to "1 2" and the second is changed to "3 4" in input, the result also changed.
What's the problem of my code?
Additional information:
I use z[] because I use a function that satisfy the requirement of this problem, so I can simply sort them. And vec[] stores the original index, because moving arrays may cost lots of time. So v[vec[i]][0] means the 'new' array's item i.
Note that v[0] is NOT used. n is less than 100000, not equal.
You are comparing values stored in z[], but swapping elements of vec.
So when in the begginig you have:
i vec z
------------------
1 1 z[1]
2 2 z[2]
3 3 z[3]
...
After for e.g. swapping 2 with 3
i vec z
------------------
1 1 z[1]
2 3 z[2]
3 2 z[3]
...
you will have improper mapping between vec and z.
So in another iteration you will again compare z[2] with z[3] and again you will have to swap elements of vec. That's why you should at least also swap elements of z or index elements of z using elements of vec
i vec z
------------------
1 1 z[vec[1]] = z[1]
2 3 z[vec[2]] = z[3]
3 2 z[vec[3]] = z[2]
...
Adding this should do the trick
...
int t = vec[i];
vec[i] = vec[j];
vec[j] = t;
//Add this also when swapping vec
t = z[i];
z[i] = z[j];
z[j] = t;
...
Array index start with 0, so your for cicles must start from 0
if (z[j] > z[i]): you want to sort v but you are comparing z and sorting vec. By sorting vec and comparing z bubble sort cannot work. You must use the same array.

How to rotate a matrix 90 degrees without using any extra space? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Algorithm to rotate an image 90 degrees in place? (No extra memory)
By saying 90 degrees i mean to say if:
A = {1,2,3,
4,5,6,
7,8,9}
then after 90 degree rotation A becomes:
A = {7,4,1,
8,5,2,
9,6,3}
Transpose and interchange rows or columns (depends whether you want to rotate left or right).
e. g.
1) original matrix
1 2 3
4 5 6
7 8 9
2) transpose
1 4 7
2 5 8
3 6 9
3-a) change rows to rotate left
3 6 9
2 5 8
1 4 7
3-b) or change columns to rotate right
7 4 1
8 5 2
9 6 3
All these operations can be done without allocating memory.
let a be an nxn array 0 based indexing
f = floor(n/2)
c = ceil(n/2)
for x = 0 to f - 1
for y = 0 to c - 1
temp = a[x,y]
a[x,y] = a[y,n-1-x]
a[y,n-1-x] = a[n-1-x,n-1-y]
a[n-1-x,n-1-y] = a[n-1-y,x]
a[n-1-y,x] = temp
Edit If you want to avoid using temp, this works (it also rotates in the correct direction) this time in python.
def rot2(a):
n = len(a)
c = (n+1) / 2
f = n / 2
for x in range(c):
for y in range(f):
a[x][y] = a[x][y] ^ a[n-1-y][x]
a[n-1-y][x] = a[x][y] ^ a[n-1-y][x]
a[x][y] = a[x][y] ^ a[n-1-y][x]
a[n-1-y][x] = a[n-1-y][x] ^ a[n-1-x][n-1-y]
a[n-1-x][n-1-y] = a[n-1-y][x] ^ a[n-1-x][n-1-y]
a[n-1-y][x] = a[n-1-y][x] ^ a[n-1-x][n-1-y]
a[n-1-x][n-1-y] = a[n-1-x][n-1-y]^a[y][n-1-x]
a[y][n-1-x] = a[n-1-x][n-1-y]^a[y][n-1-x]
a[n-1-x][n-1-y] = a[n-1-x][n-1-y]^a[y][n-1-x]
Note: This only works for matrices of integers.
The algorithm is to rotate each "ring", working from the outermost to the innermost.
AAAAA
ABBBA
ABCBA
ABBBA
AAAAA
The algorithm would rotate all the A's first, then B's then C's. Rotating a ring requires moving 4 values at once.
The index i ranges from 0..ring-width-1, e.g. for A the width is 5.
(i,0) -> temp
(0, N-i-1) -> (i, 0)
(N-i-1, N-1) -> (0, N-i-1)
(N-1, i) -> (N-i-1, N-1)
temp -> (N-1, i)
This is then repeated for each successive inner ring, offsetting the co-ordinates reducing the ring width by 2.
[Another answer has appeared with the code, so I'll not repeat that.]
Complete implementation in C using the method described by #Narek above
#include <stdio.h>
int n;
unsigned int arr[100][100];
void rotate() {
int i,j,temp;
for(i=0; i<n; i++) {
for(j=i; j<n; j++) {
if(i!=j) {
arr[i][j]^=arr[j][i];
arr[j][i]^=arr[i][j];
arr[i][j]^=arr[j][i];
}
}
}
for(i=0; i<n/2; i++) {
for(j=0; j<n; j++) {
arr[j][i]^=arr[j][n-1-i];
arr[j][n-1-i]^=arr[j][i];
arr[j][i]^=arr[j][n-1-i];
}
}
}
void display(){
int i,j;
for(i=0;i<n;i++) {
for(j=0;j<n;j++) {
printf("%d",arr[i][j]);}
printf("%s","\n");
}
}
int main(int argc, char *argv[]){
int i,j;
printf("%s","Enter size of matrix:");
scanf("%d",&n);
printf("%s","Enter matrix elements\n");
for(i=0;i<n;i++) {
for(j=0;j<n;j++) {
scanf("%d",&arr[i][j]);
}
}
rotate();
display();
return 0;
}
See this article for in-place matrix transposition; also google for "in-place matrix transposition". It can be easily adapted to perform rotation by 90 degrees. To transpose square matrices, you just interchange b[i][j] with b[j][i] where b[k][l] is a[n*k+l]. On nonsquare matrices, it's considerably more difficult. "Without any extra space" is a rather strong requirement, maybe you meant O(1) space? (assuming integers are fixed size) Implementation in C++: here.
You need one temp variable, then it is just to jump elements around.
temp = A[0];
A[0] = A[6];
A[6] = A[8];
A[8] = A[2];
A[2] = temp;
temp = A[1];
A[1] = A[3];
A[3] = A[7];
A[7] = A[5];
A[5] = temp;
I came across the following implementation:
For square matrices:
for n = 0 to N - 2
for m = n + 1 to N - 1
swap A(n,m) with A(m,n)
For rectangular matrices:
for each length>1 cycle C of the permutation
pick a starting address s in C
let D = data at s
let x = predecessor of s in the cycle
while x ≠ s
move data from x to successor of x
let x = predecessor of x
move data from D to successor of s
For more info, one can refer here: http://en.wikipedia.org/wiki/In-place_matrix_transposition

Resources