Matrix multiplication by divide and conquer method - c

This is implementation of matrix multiplication by divide and conquer.
But this code works on only N <= 4.
when N is 8, segmentation fault occurs and i don't know why.
when debugging, i found that matrix index becomes minus but it's ridiculous that it works properly on N == 4. But why N not on N is 8?
Is it because of stack overflow?
Thanks.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define N 8
struct _matrix {
int row_st;
int row_en;
int col_st;
int col_en;
int mat[N][N];
};
typedef struct _matrix matrix;
void print_mat(matrix m) {
for (int i = m.row_st; i <= m.row_en; i++) {
for (int j = m.col_st; j <= m.col_en; j++) {
printf("%d ", m.mat[i][j]);
}
printf("\n");
}
printf("\n");
return;
}
matrix add(matrix a, matrix b) {
int n = a.row_en - a.row_st;
//set result matrix
matrix c;
c.row_st = 0; c.row_en = n; c.col_st = 0; c.col_en = n;
//create submatrices from original matrix by indexing caculation
int arow, acol, brow, bcol, crow, ccol;
for (arow = a.row_st, brow = b.row_st, crow = 0;
arow <= a.row_en; arow++, brow++, crow++) {
for (acol = a.col_st, bcol = b.col_st, ccol = 0;
acol <= a.col_en; acol++, bcol++, ccol++) {
c.mat[crow][ccol] = a.mat[arow][acol] + b.mat[brow][bcol];
}
}
return c;
}
matrix sub(matrix a, matrix b) {
int n = a.row_en - a.row_st;
//set result matrix
matrix c;
c.row_st = 0; c.row_en = n; c.col_st = 0; c.col_en = n;
//create submatrices from original matrix by indexing caculation
int arow, acol, brow, bcol, crow, ccol;
for (arow = a.row_st, brow = b.row_st, crow = 0;
arow <= a.row_en; arow++, brow++, crow++) {
for (acol = a.col_st, bcol = b.col_st, ccol = 0;
acol <= a.col_en; acol++, bcol++, ccol++) {
c.mat[crow][ccol] = a.mat[arow][acol] - b.mat[brow][bcol];
}
}
return c;
}
matrix dc(matrix input1, matrix input2) {
int n = input1.row_en - input1.row_st + 1;
if (n == 2) {
int a, b, c, d, e, f, g, h;
a = input1.mat[input1.row_st][input1.col_st];
b = input1.mat[input1.row_st][input1.col_st+1];
c = input1.mat[input1.row_st+1][input1.col_st];
d = input1.mat[input1.row_st+1][input1.col_st+1];
e = input2.mat[input2.row_st][input2.col_st];
f = input2.mat[input2.row_st][input2.col_st+1];
g = input2.mat[input2.row_st+1][input2.col_st];
h = input2.mat[input2.row_st+1][input2.col_st+1];
matrix output = input1;
output.mat[output.row_st][output.col_st] = a*e + b*g;
output.mat[output.row_st][output.col_st+1] = a*f + b*h;
output.mat[output.row_st+1][output.col_st] = c*e + d*g;
output.mat[output.row_st+1][output.col_st+1] = c*f + d*h;
print_mat(output);
return output;
}
//divide into submatrices using index calculation
matrix a11 = input1;
matrix a12 = input1;
matrix a21 = input1;
matrix a22 = input1;
matrix b11 = input2;
matrix b12 = input2;
matrix b21 = input2;
matrix b22 = input2;
a11.row_st = input1.row_st;
a11.row_en = input1.row_en/2;
a11.col_st = input1.col_st;
a11.col_en = input1.col_en/2;
a12.row_st = input1.row_st;
a12.row_en = input1.row_en/2;
a12.col_st = input1.col_en/2 + 1;
a12.col_en = input1.col_en;
a21.row_st = input1.row_en/2 + 1;
a21.row_en = input1.row_en;
a21.col_st = input1.col_st;
a21.col_en = input1.col_en/2;
a22.row_st = input1.row_en/2 + 1;
a22.row_en = input1.row_en;
a22.col_st = input1.col_en/2 + 1;
a22.col_en = input1.col_en;
b11.row_st = input2.row_st;
b11.row_en = input2.row_en/2;
b11.col_st = input2.col_st;
b11.col_en = input2.col_en/2;
b12.row_st = input2.row_st;
b12.row_en = input2.row_en/2;
b12.col_st = input2.col_en/2 + 1;
b12.col_en = input2.col_en;
b21.row_st = input2.row_en/2 + 1;
b21.row_en = input2.row_en;
b21.col_st = input2.col_st;
b21.col_en = input2.col_en/2;
b22.row_st = input2.row_en/2 + 1;
b22.row_en = input2.row_en;
b22.col_st = input2.col_en/2 + 1;
b22.col_en = input2.col_en;
matrix c;
c.row_st = 0;
c.row_en = n-1;
c.col_st = 0;
c.col_en = n-1;
matrix c11 = c;
matrix c12 = c;
matrix c21 = c;
matrix c22 = c;
c11.row_st = c.row_st;
c11.row_en = c.row_en/2;
c11.col_st = c.col_st;
c11.col_en = c.col_en/2;
c12.row_st = c.row_st;
c12.row_en = c.row_en/2;
c12.col_st = c.col_en/2 + 1;
c12.col_en = c.col_en;
c21.row_st = c.row_en/2 + 1;
c21.row_en = c.row_en;
c21.col_st = c.col_st;
c21.col_en = c.col_en/2;
c22.row_st = c.row_en/2 + 1;
c22.row_en = c.row_en;
c22.col_st = c.col_en/2 + 1;
c22.col_en = c.col_en;
c11 = add(dc(a11, b11), dc(a12, b21));
c12 = add(dc(a11, b12), dc(a12, b22));
c21 = add(dc(a21, b11), dc(a22, b21));
c22 = add(dc(a21, b12), dc(a22, b22));
int tmprow, tmpcol, row, col;
for (tmprow = c11.row_st, row = 0; tmprow <= c11.row_en; tmprow++, row++) {
for (tmpcol = c11.col_st, col = 0; tmpcol <= c11.col_en; tmpcol++, col++) {
c.mat[row][col] = c11.mat[tmprow][tmpcol];
}
}
for (tmprow = c12.row_st, row = 0; tmprow <= c12.row_en; tmprow++, row++) {
for (tmpcol = c12.col_st, col = n/2; tmpcol <= c12.col_en; tmpcol++, col++) {
c.mat[row][col] = c12.mat[tmprow][tmpcol];
}
}
for (tmprow = c21.row_st, row = n/2; tmprow <= c21.row_en; tmprow++, row++) {
for (tmpcol = c21.col_st, col = 0; tmpcol <= c21.col_en; tmpcol++, col++) {
c.mat[row][col] = c21.mat[tmprow][tmpcol];
}
}
for (tmprow = c22.row_st, row = n/2; tmprow <= c22.row_en; tmprow++, row++) {
for (tmpcol = c22.col_st, col = n/2; tmpcol <= c22.col_en; tmpcol++, col++) {
c.mat[row][col] = c22.mat[tmprow][tmpcol];
}
}
print_mat(c);
return c;
}

Related

cell overlap removal in vlsi placement

Below code is to remove overlap among cells residing inside grids.
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <time.h>
#define TRUE 1
#define FALSE 0
//coordinate representation
struct Point
{
double x;
double y;
};
//block representation with 4 coordinates
struct Block
{
unsigned int id;
struct Point bottomLeft, topLeft, bottomRight, topRight;
double width, height;
double whitespace;
};
struct Overlap
{
double overlapLength;
struct Block *b1, *b2;
} OL[1000];
struct Block *b;
struct Block ROW1, ROW2, ROW3;
int comparator(const void *p, const void *q)
{
return (((struct Overlap *)p)->overlapLength -
(((struct Overlap *)q)->overlapLength));
}
//intialise Blocks using bottom left x,y coordinate
void intialiseBlock(struct Block *B)
{
B->topLeft.x = B->bottomLeft.x;
B->topLeft.y = B->height + B->bottomLeft.y;
B->bottomRight.x = B->width + B->bottomLeft.x;
B->bottomRight.y = B->bottomLeft.y;
B->topRight.x = B->width + B->bottomLeft.x;
B->topRight.y = B->height + B->bottomLeft.y;
}
//update coordinate
void move(double xDelta, double yDelta, struct Point *p)
{
// Parameter values are increments to the current coordinates
p->x += xDelta;
p->y += yDelta;
}
//calculate and return distance between 2 points
double distance(const struct Point aPoint, const struct Point bPoint)
{
return sqrt((aPoint.x - bPoint.x) * (aPoint.x - bPoint.x) +
(aPoint.y - bPoint.y) * (aPoint.y - bPoint.y));
}
//generate width of cell using number of cells
double computeCellWidth(int ncell)
{
double width = (0.8 * 400) / ncell;
return width;
}
//create a
unsigned int rand_interval(unsigned int min, unsigned int max)
{
int r;
const unsigned int range = 1 + max - min;
const unsigned int buckets = RAND_MAX / range;
const unsigned int limit = buckets * range;
/* Create equal size buckets all in a row, then fire randomly towards
* the buckets until you land in one of them. All buckets are equally
* likely. If you land off the end of the line of buckets, try again. */
do
{
r = rand();
} while (r >= limit);
return min + (r / buckets);
}
//place blocks in appropriate rows
void placeVertical(struct Block *b, int n, struct Block ROW1, struct Block ROW2,
struct Block ROW3)
{
for (int i = 0; i < n; i++)
{
double distanceFromBottom = 0.0;
double distanceFromTop = 0.0;
// check if Inside Row1 and Row2
if ((b[i].bottomLeft.y < ROW1.topLeft.y) && (b[i].topLeft.y > ROW1.topLeft.y))
{
//printf("ROW1 and ROW2 Executed\n");
distanceFromBottom = ROW1.topLeft.y - b[i].bottomLeft.y;
distanceFromTop = b[i].height - distanceFromBottom;
if (distanceFromBottom > distanceFromTop)
{
move(0, -distanceFromTop, &b[i].bottomLeft);
move(0, -distanceFromTop, &b[i].topLeft);
move(0, -distanceFromTop, &b[i].bottomRight);
move(0, -distanceFromTop, &b[i].topRight);
}
else
{
move(0, distanceFromBottom, &b[i].bottomLeft);
move(0, distanceFromBottom, &b[i].topLeft);
move(0, distanceFromBottom, &b[i].bottomRight);
move(0, distanceFromBottom, &b[i].topRight);
}
}
// check if Inside Row2 and Row3
else if ((b[i].bottomLeft.y < ROW2.topLeft.y) && (b[i].topLeft.y > ROW2.topLeft.y))
{
//System.out.println("ROW2 and ROW3 Executed");
distanceFromBottom = ROW2.topLeft.y - b[i].bottomLeft.y;
distanceFromTop = b[i].height - distanceFromBottom;
if (distanceFromBottom > distanceFromTop)
{
move(0, -distanceFromTop, &b[i].bottomLeft);
move(0, -distanceFromTop, &b[i].topLeft);
move(0, -distanceFromTop, &b[i].bottomRight);
move(0, -distanceFromTop, &b[i].topRight);
}
else
{
move(0, distanceFromBottom, &b[i].bottomLeft);
move(0, distanceFromBottom, &b[i].topLeft);
move(0, distanceFromBottom, &b[i].bottomRight);
move(0, distanceFromBottom, &b[i].topRight);
}
}
else if ((b[i].bottomLeft.y >= ROW1.bottomLeft.y) && (b[i].topLeft.y <= ROW1.topLeft.y))
{
// do nothing in ROW1
}
else if ((b[i].bottomLeft.y >= ROW2.bottomLeft.y) && (b[i].topLeft.y <= ROW2.topLeft.y))
{
// do nothing in ROW2
}
else // ((b[i].bottomLeft.y >=
// ROW2.bottomLeft.y)&&(b[i].topLeft.y <=
// ROW2.topLeft.y))
{
// do nothing in ROW3
}
}
}
//use when floating point operations create run time problems
void linkfloat()
{
float a = 0.0, *x;
x = &a;
a = *x;
}
int findOverlaps(struct Block *b, int n)
{
int k, j, p = 0;
//struct Overlap OL[200];
//short flag = FALSE;
double overlapLength = 0.0;
for (int i = 0; i < n - 1; i++)
{
k = i;
for (j = i + 1; j < n; j++)
{
if (k == j)
continue;
overlapLength = 0.0;
//for ROW1
if (b[k].bottomLeft.y >= 0 && b[k].topLeft.y <= 100 && b[j].bottomLeft.y >= 0 && b[j].topLeft.y <= 100)
{
//if ((b[k].bottomRight.x > b[j].bottomLeft.x) && (b[k].bottomRight.y < b[j].topLeft.y || b[k].topRight.y > b[j].bottomLeft.y))
if ((b[k].bottomLeft.y == b[j].bottomLeft.y) && (b[k].bottomRight.x > b[j].bottomLeft.x))
{
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
OL[p].overlapLength = overlapLength;
OL[p].b1 = &b[k];
OL[p].b2 = &b[j];
p++;
}
else if (((b[k].topLeft.y > b[j].bottomLeft.y) && (b[k].topRight.x > b[j].bottomLeft.x)) || ((b[k].bottomLeft.y < b[j].topLeft.y) && (b[k].bottomRight.x > b[j].topLeft.x)))
{
//flag = TRUE;
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
OL[p].overlapLength = overlapLength;
OL[p].b1 = &b[k];
OL[p].b2 = &b[j];
p++;
}
else
{
}
overlapLength = 0.0;
}
//For Row2
else if (b[k].bottomLeft.y >= 100 && b[k].topLeft.y <= 200 && b[j].bottomLeft.y >= 100 && b[j].topLeft.y <= 200)
{
if ((b[k].bottomLeft.y == b[j].bottomLeft.y) && (b[k].bottomRight.x > b[j].bottomLeft.x))
{
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
OL[p].overlapLength = overlapLength;
OL[p].b1 = &b[k];
OL[p].b2 = &b[j];
p++;
}
else if (((b[k].topLeft.y > b[j].bottomLeft.y) && (b[k].topRight.x > b[j].bottomLeft.x)) || ((b[k].bottomLeft.y < b[j].topLeft.y) && (b[k].bottomRight.x > b[j].topLeft.x)))
{
//flag = TRUE;
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
OL[p].overlapLength = overlapLength;
OL[p].b1 = &b[k];
OL[p].b2 = &b[j];
p++;
}
else
{
}
overlapLength = 0.0;
}
//For Row3
else if (b[k].bottomLeft.y >= 200 && b[k].topLeft.y <= 300 && b[j].bottomLeft.y >= 200 && b[j].topLeft.y <= 300)
{
if ((b[k].bottomLeft.y == b[j].bottomLeft.y) && (b[k].bottomRight.x > b[j].bottomLeft.x))
{
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
OL[p].overlapLength = overlapLength;
OL[p].b1 = &b[k];
OL[p].b2 = &b[j];
p++;
}
else if (((b[k].topLeft.y > b[j].bottomLeft.y) && (b[k].topRight.x > b[j].bottomLeft.x)) || ((b[k].bottomLeft.y < b[j].topLeft.y) && (b[k].bottomRight.x > b[j].topLeft.x)))
{
//flag = TRUE;
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
OL[p].overlapLength = overlapLength;
OL[p].b1 = &b[k];
OL[p].b2 = &b[j];
p++;
}
else
{
}
overlapLength = 0.0;
}
else
{
//do nothing
}
}
}
return p;
}
struct Block *
getBlock(struct Block *b, int n, int id)
{
int i;
for (i = 0; i < n; i++)
{
if (id == b[i].id)
return (b + i);
}
return NULL;
}
void placeHorizontalGreedy(struct Block *b, int n)
{
struct Block *t = NULL;
int p = 0, k = 0;
p = findOverlaps(b, n);
qsort(OL, p, sizeof(struct Overlap), comparator);
while (TRUE)
{
t = getBlock(b, 12, OL[k].b2->id);
if (t != NULL)
{
//t->bottomLeft.x = t->bottomLeft.x+OL[0].overlapLength;
if ((t->bottomLeft.x + OL[0].overlapLength + t->width) <= ROW1.bottomRight.x)
{
move(OL[0].overlapLength, 0, &t->bottomLeft);
intialiseBlock(t);
}
}
p = findOverlaps(b, n);
if (p == 0)
break;
else
qsort(OL, p, sizeof(struct Overlap), comparator);
}
}
void placeHorizontalNonGreedy(struct Block *b, int n, struct Block ROW1,
struct Block ROW2, struct Block ROW3)
{
int k, j, p = 0;
double overlapLength = 0.0;
for (int i = 0; i < n - 1; i++)
{
k = i;
for (j = i + 1; j < n; j++)
{
if (k == j)
continue;
overlapLength = 0.0;
//check if in Row1
if (b[k].bottomLeft.y >= ROW1.bottomLeft.y && b[k].topLeft.y <= ROW1.topLeft.y && b[j].bottomLeft.y >= ROW1.bottomLeft.y && b[j].topLeft.y <= ROW1.topLeft.y)
{
if ((b[k].bottomRight.x > b[j].bottomLeft.x) && (b[k].bottomRight.y < b[j].topLeft.y || b[k].topRight.y > b[j].bottomLeft.y))
{
//flag = TRUE;
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
if (overlapLength != 0)
{
if (b[j].bottomLeft.x + overlapLength + b[j].width <=
ROW1.bottomRight.x)
{
b[j].bottomLeft.x += overlapLength;
intialiseBlock(&b[j]);
}
else
{
b[j].bottomLeft.x =
b[j].bottomLeft.x + (ROW1.bottomRight.x -
b[j].bottomRight.x);
}
}
}
}
//check if in Row2
else if (b[k].bottomLeft.y >= ROW2.bottomLeft.y && b[k].topLeft.y <= ROW2.topLeft.y && b[j].bottomLeft.y >= ROW2.bottomLeft.y && b[j].topLeft.y <= ROW2.topLeft.y)
{
if ((b[k].bottomRight.x > b[j].bottomLeft.x) && (b[k].bottomRight.y < b[j].topLeft.y || b[k].topRight.y > b[j].bottomLeft.y))
{
//flag = TRUE;
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
if (overlapLength != 0)
{
if (b[j].bottomLeft.x + overlapLength + b[j].width <=
400)
{
b[j].bottomLeft.x += overlapLength;
intialiseBlock(&b[j]);
}
}
}
}
//check if in Row3
else if (b[k].bottomLeft.y >= ROW3.bottomLeft.y && b[k].topLeft.y <= ROW3.topLeft.y && b[j].bottomLeft.y >= ROW3.bottomLeft.y && b[j].topLeft.y <= ROW3.topLeft.y)
{
if ((b[k].bottomRight.x > b[j].bottomLeft.x) && (b[k].bottomRight.y < b[j].topLeft.y || b[k].topRight.y > b[j].bottomLeft.y))
{
//flag = TRUE;
overlapLength = b[k].bottomRight.x - b[j].bottomLeft.x;
if (overlapLength != 0)
{
if (b[j].bottomLeft.x + overlapLength + b[j].width <=
400)
{
b[j].bottomLeft.x += overlapLength;
intialiseBlock(&b[j]);
}
}
}
}
else
{
//printf("Invalid input\n");
continue;
}
}
}
}
int main()
{
//struct Block b[16];
//struct Block b[4];
//struct Block *b;
//struct Block ROW1, ROW2, ROW3;
//FILE *fp = fopen("/home/jeetu/experimentprograms/recordcoord.txt", "w+");
//FILE *fp = fopen("/home/jeetu/experimentprograms/blockcoordinates.txt", "r");
int ncell = 0, width = 0, i = 0, totalncells = 0, id = 0;
double distanceFromBottom = 0.0;
double distanceFromTop = 0.0;
int x = 0, y = 0, temp = 0, d = 0;
printf("Enter number of cells: ");
scanf("%d", &ncell);
width = computeCellWidth(ncell);
//width = 40;
b = (struct Block *)malloc(3 * ncell * sizeof(struct Block));
//b = (struct Block *)malloc(12 * sizeof(struct Block));
srand(time(0));
ROW1.bottomLeft.x = 0;
ROW1.bottomLeft.y = 0;
ROW1.height = 100;
ROW1.width = 400;
ROW1.whitespace = 40000;
intialiseBlock(&ROW1);
ROW2.bottomLeft.x = 0;
ROW2.bottomLeft.y = 100;
ROW2.height = 100;
ROW2.width = 400;
ROW2.whitespace = 40000;
intialiseBlock(&ROW2);
ROW3.bottomLeft.x = 0;
ROW3.bottomLeft.y = 200;
ROW3.height = 100;
ROW3.width = 400;
ROW3.whitespace = 40000;
intialiseBlock(&ROW3);
for (i = 0; i < ncell; i++)
{
if (i == 0)
{
// x = rand_interval(0, width / 2);
x = rand() % (width / 2);
//y = rand_interval(0, 70);
y = rand() % 70;
temp = x;
}
//m = rand();
else
{
x = rand_interval((temp + (int)width / 2), temp + width);
//x = (rand()%((temp+width)-(temp+width/2)))+(temp+width/2);
//y = rand_interval(0, 70);
y = rand() % 70;
temp = x;
}
b[totalncells].bottomLeft.x = x;
b[totalncells].bottomLeft.y = y;
b[totalncells].width = width;
b[totalncells].height = 50;
b[totalncells].id = id;
//initial white space calculation for ROW1
if (b[totalncells].bottomLeft.y >= ROW1.bottomLeft.y && b[totalncells].topLeft.y <= ROW1.topLeft.y)
{
ROW1.whitespace =
ROW1.whitespace - b[totalncells].width * b[totalncells].height;
}
id++;
intialiseBlock(&b[totalncells]);
totalncells++;
//printf("x=%d\ty=%d\n", x, y);
}
temp = 0;
//Generate random coordinates For Row2
for (i = 0; i < ncell; i++)
{
//int x = 0, y = 0, m = 0, d = 0;
if (i == 0)
{
/*x = rand_interval(0, width / 2);
y = rand_interval(100, 170); */
//x = rand() % (width / 2);
x = rand() % (width / 2);
y = (rand() % (170 - 100)) + 100;
temp = x;
}
//m = rand();
else
{
/*x = rand_interval((temp + (int)width / 2), 400 - (int)width);
y = rand_interval(100, 170); */
//x = (rand()%((temp+width)-(temp+width/2)))+(temp+width/2);
x = rand_interval((temp + (int)width / 2), temp + width);
y = (rand() % (170 - 100)) + 100;
temp = x;
}
b[totalncells].bottomLeft.x = x;
b[totalncells].bottomLeft.y = y;
b[totalncells].width = width;
b[totalncells].height = 50;
b[totalncells].id = id;
//initial white space calculation for ROW2
if (b[totalncells].bottomLeft.y >= ROW2.bottomLeft.y && b[totalncells].topLeft.y <= ROW2.topLeft.y)
{
ROW2.whitespace =
ROW2.whitespace - b[totalncells].width * b[totalncells].height;
}
id++;
intialiseBlock(&b[totalncells]);
totalncells++;
//printf("x=%d\ty=%d\n", x, y);
}
temp = 0;
//Generate random coordinates For Row3
for (i = 0; i < ncell; i++)
{
//int x = rand_interval(0, 100 - (int)width);
//int y = rand_interval(20, 25); //cell height is 5 so max will reach 30
//int x = 0, y = 0, m = 0, d = 0;
if (i == 0)
{
/*x = rand_interval(0, width / 2);
y = rand_interval(200, 250); */
x = rand() % (width / 2);
y = (rand() % (250 - 200)) + 200;
temp = x;
}
//m = rand();
else
{
/*x = rand_interval((temp + (int)width / 2), 400 - (int)width);
y = rand_interval(200, 250); */
x = rand_interval((temp + (int)width / 2), temp + width);
//x = (rand()%((temp+width)-(temp+width/2)))+(temp+width/2);
y = (rand() % (250 - 200)) + 200;
temp = x;
}
b[totalncells].bottomLeft.x = x;
b[totalncells].bottomLeft.y = y;
b[totalncells].width = width;
b[totalncells].height = 50;
b[totalncells].id = id;
//initial white space calculation for ROW3
if (b[totalncells].bottomLeft.y >= ROW3.bottomLeft.y && b[totalncells].topLeft.y <= ROW3.topLeft.y)
{
ROW3.whitespace =
ROW3.whitespace - b[totalncells].width * b[totalncells].height;
}
id++;
intialiseBlock(&b[totalncells]);
totalncells++;
//printf("x=%d\ty=%d\n", x, y);
}
for (i = 0; i < totalncells; i++)
{
//printf("%f %f %f %f\n", b[i].bottomLeft.x, b[i].bottomLeft.y, b[i].width, b[i].height);
printf("%d\t%d\t%d\t%d\n", (int)b[i].bottomLeft.x,
(int)b[i].bottomLeft.y, (int)b[i].width, (int)b[i].height);
}
placeVertical(b, totalncells, ROW1, ROW2, ROW3);
//placeVerticalWithDensityConstraints(b,totalncells,ROW1,ROW2,ROW3);
printf("\nAfter vertical Updation\n");
for (i = 0; i < totalncells; i++)
{
printf("%d\t%d\t%d\t%d\n", (int)b[i].bottomLeft.x,
(int)b[i].bottomLeft.y, (int)b[i].width, (int)b[i].height);
}
/*placeHorizontalNonGreedy(b, 12, ROW1, ROW2, ROW3);
printf("\nAfter Horizontal Updation(Non greedy)\n");
for (i = 0; i < 12; i++)
{
printf("%d\t%d\t%d\t%d\n", (int)b[i].bottomLeft.x, (int)b[i].bottomLeft.y, (int)b[i].width, (int)b[i].height);
} */
placeHorizontalGreedy(b, totalncells);
printf("\nAfter Horizontal Updation(Greedy)\n");
for (i = 0; i < totalncells; i++)
{
printf("%d\t%d\t%d\t%d\n", (int)b[i].bottomLeft.x,
(int)b[i].bottomLeft.y, (int)b[i].width, (int)b[i].height);
}
return 0;
}
Explanation about the code
in this program I have defined three structures
one to represent a Point,one to represent rectangular block with 4 coordinates,one to represent overlap between pair of cells.
There is function(computeCellWidth) to dynamically compute width of cells according to a formula.
There are three rows ROW1,ROW2,ROW3 in which cells will reside.
This program will first ask for number of cells and this is numbers of cells per row.At first x,y coordinates for each cell is randomly generated.Then placeVertical() function will move cells to different rows which are spanning across two rows.Then there is a placeHorizontalGreedy() function which will remove overlap among cells by first finding overlaplength and then sorting them and removing the overlap between cells which has least overlap and this process will continue till either there will be no overlaps or overlap removal is not possible anymore.Here I would like to bring to the notice of everybody that cells will be moved towards the right of the grid to remove overlaps.In placeHorizontalGreedy() function I have used a variable p which will indicate number of overlaps after each iteration.for small number of cells testing for p to be zero works fine but not as I increase the numbers.Plus how can I make sure that overlaps exists but overlap removal is not possible anymore,so that I can stop the loop. Please help me out.

Yaw rotation: recalculate mins/maxs based on zero based mins/maxs

Edit by kriegaex: This question is about yaw rotation as opposed to pitch or roll.
So, X = y = z = 0 - mins {105.0, -75.0, 0.0}, maxs {225.0, -15.0, 50.0}
So, that's what im doing (it's wrong, or it's just AABB calculating instead needed stuff).
float fMins[3]; float fMaxs[3];
float yaw = angles2[1] * (3.14 / 180.0);
float xvector[3]; float yvector[3];
xvector[0] = floatcos(yaw);
xvector[1] = floatsin(yaw);
yvector[0] = -floatsin(yaw);
yvector[1] = floatcos(yaw);
float rmin[3] = { 9999.0, 9999.0, 9999.0 };
float rmax[3] = { -9999.0, -9999.0, -9999.0 };
float base[3];
float transformed[3];
for (int i = 0; i <= 1; i++) {
base[0] = i == 0 ? mins[0] : maxs[0];
for (int j = 0; j <= 1; j++) {
base[1] = j == 0 ? mins[1] : maxs[1];
for (int k = 0; k <= 1; k++) {
base[2] = k == 0 ? mins[2] : maxs[2];
transformed[0] = xvector[0]*base[0] + yvector[0]*base[1];
transformed[1] = xvector[1]*base[0] + yvector[1]*base[1];
transformed[2] = base[2];
/*
if (transformed[0] < rmin[0]) rmin[0] = transformed[0];
if (transformed[0] > rmax[0]) rmax[0] = transformed[0];
if (transformed[1] < rmin[1]) rmin[1] = transformed[1];
if (transformed[1] > rmax[1]) rmax[1] = transformed[1];
if (transformed[2] < rmin[2]) rmin[2] = transformed[2];
if (transformed[2] > rmax[2]) rmax[2] = transformed[2];
*/
for (int l = 0; l < 3; l++) {
if (transformed[l] < rmin[l]) rmin[l] = transformed[l];
if (transformed[l] > rmax[l]) rmax[l] = transformed[l];
}
}
}
}
fMins[0] = rmin[0]; fMaxs[0] = rmax[0];
fMins[1] = rmin[1]; fMaxs[1] = rmax[1];
fMins[2] = rmin[2]; fMaxs[2] = rmax[2];
fMins[0] += origin2[0];
fMins[1] += origin2[1];
fMins[2] += origin2[2];
fMaxs[0] += origin2[0];
fMaxs[1] += origin2[1];
fMaxs[2] += origin2[2];
So, on 0 0 0 angle's mins maxs are {105.0, -75.0, 0.0} and {225.0, -15.0, 50.0}.
How i can calculate same sizes on 0 53 0 angles?
I need same sized box, just equalent. Only mins/maxs based solutions.

Why is there segmentation fault(core dumped) in my multithreaded scheduling program in C

I have to write a multi-threaded program in C in which one thread displays working of FCFS Scheduling and the other shows SJF scheduling. Now if I run the two types of scheduling as separate C programs, I get no errors and the programs run smoothly. But when I put them in two different functions and use the concept of multi-threading, the terminal prints the error "Segmentation fault (core dumped)" Please help me out
#include <stdio.h>
#include <pthread.h>
void *fcfs(void *);
void *sjf(void *);
int pid[10],at[10],bt[10];
int pid1[10],at1[10],bt1[10];
void main()
{
pthread_t fcfsT,sjfT;
pthread_attr_t attr;
int lower = 0, upper = 20, count = 10;
int i;
for(i=0;i<10;i++)
{
pid[i]=i+1;
}
for (i = 0; i < count; i++) {
at[i] = (rand() % (upper - lower + 1)) + lower;
bt[i] = (rand() % (upper - lower + 1)) + lower;
}
for(i=0;i<10;i++)
{
pid1[i]=pid[i];
at1[i]=at[i];
bt1[i]=bt[i];
}
pthread_attr_init(&attr);
pthread_create(&fcfsT,&attr,fcfs, NULL);
pthread_create(&sjfT,&attr,sjf,NULL);
pthread_join(fcfsT,NULL);
pthread_join(sjfT,NULL);
}
void *fcfs(void *p)
{
int ct[10],a,wt[10],tat[10],i,j=0;
for (i = 0; i < 10; ++i)
{
for (j = i + 1; j < 10; ++j)
{
if (at[i] > at[j])
{
a = at[i];
at[i] = at[j];
at[j] = a;
a = bt[i];
bt[i] = bt[j];
bt[j] = a;
a = pid[i];
pid[i] = pid[j];
pid[j] = a;
}
}
}
ct[0]=at[0]+bt[0];
for(i=1;i<10;i++)
{
if(at[i]<ct[i-1])
ct[i]=ct[i-1]+bt[i];
else
ct[i]=at[i]+bt[i];
}
for (i = 0; i < 10; ++i)
{
for (j = i + 1; j < 10; ++j)
{
if (pid[i] > pid[j])
{
a = pid[i];
pid[i] = pid[j];
pid[j] = a;
a = at[i];
at[i] = at[j];
at[j] = a;
a = bt[i];
bt[i] = bt[j];
bt[j] = a;
a = ct[i];
ct[i] = ct[j];
ct[j] = a;
}
}
}
for(i=0;i<10;i++)
{
tat[i]=ct[i]-at[i];
wt[i]=tat[i]-bt[i];
}
printf("PID\tAT\tBT\tCT\tTAT\tRT:\n\n");
for(i=0;i<10;i++)
{
printf("P%d\t%d\t%d\t%d\t%d\t%d\n",pid[i],at[i],bt[i],ct[i],tat[i],wt[i]);
}
pthread_exit(0);
}
void *sjf(void *g)
{
int ct1[10],b,wt1[10],tat1[10],z,q=0,minimum,location,temp[3]={0,0,0};
for (z = 0; z < 10; ++z)
{
for (q = z + 1; q < 10; ++q)
{
if (bt1[z] > bt1[q])
{
b = bt1[z];
bt1[z] = bt1[q];
bt1[q] = b;
b = at1[z];
at1[z] = at1[q];
at1[q] = b;
b = pid1[z];
pid1[z] = pid1[q];
pid1[q] = b;
}
}
}
for (z = 0; z < 10; ++z)
{
for (q = z + 1; q < 10; ++q)
{
if (bt1[z] == bt1[q])
{
if(at1[q]<at1[z])
{
b = bt1[z];
bt1[z] = bt1[q];
bt1[q] = b;
b = at1[z];
at1[z] = at1[q];
at1[q] = b;
b = pid1[z];
pid1[z] = pid1[q];
pid1[q] = b;
}
}
}
}
minimum = at1[0];
for ( z = 1 ; z < 10 ; z++ )
{
if ( at1[z] < minimum )
{
minimum = at1[z];
location = z;
}
}
temp[0] = at1[location];
temp[1] = bt1[location];
temp[2] = pid1[location];
for(z=location;z>0;z--)
{
at1[z]=at1[z-1];
bt1[z]=bt1[z-1];
pid1[z]=pid1[z-1];
}
at1[0]=temp[0];
bt1[0]=temp[1];
pid1[0]=temp[2];
ct1[0]= at1[0]+bt1[0];
for(z=1;z<10;z++)
{
if(at1[z]>ct1[z-1])
ct1[z] = at1[z]+bt1[z];
else
ct1[z] = bt1[z]+ ct1[z-1];
}
for (z = 0; z < 10; ++z)
{
for (q = z + 1; q < 10; ++q)
{
if (pid1[z] > pid1[q])
{
b = pid1[z];
pid1[z] = pid1[q];
pid1[q] = b;
b = at1[z];
at1[z] = at1[q];
at1[q] = b;
b = bt1[z];
bt1[z] = bt1[q];
bt1[q] = b;
b = ct1[z];
ct1[z] = ct1[q];
ct1[q] = b;
}
}
}
for(z=0;z<10;z++)
{
tat1[z]=ct1[z]-at1[z];
wt1[z]=tat1[z]-bt1[z];
}
printf("pid1\tAT\tBT\tCT\tTAT\tRT:\n\n");
for(z=0;z<10;z++)
{
printf("P%d\t%d\t%d\t%d\t%d\t%d\n",pid1[z],at1[z],bt1[z],ct1[z],tat1[z],wt1[z]);
}
pthread_exit(0);
}
In sjf(), if at1[0] is the minimum, location will never be initialized, thus the loop below could readily generate invalid addresses.
for(z=location;z>0;z--)
{
at1[z]=at1[z-1];
bt1[z]=bt1[z-1];
pid1[z]=pid1[z-1];
}
When you run in “process mode”, it is very likely that your initial stack is zero-filled, thus the flaws in your program were hidden. The initial thread stack may have other stale data in it.
As the comments point out, you should try and use some level of compiler diagnostic (and initiative) before SO. Everybody is willing to help, but you are expected to develop the skills to help out too.

how can I make my boxblur code work faster?

I have written a box blur code for gray image blur, but it turned out to work much slower than I expected. How can I improve its performance?
void boxfilter(int* const srcImg, int* const desImg, const int mask, const int nrows, const int ncols)
{
LL *buffer, *rowImg, *rowPtr;
int *srcPtr, *desPtr;
LL pre, sum;
int row, col, i, len, r;
const int MAX_ROW_COL = nrows > ncols ? nrows : ncols;
const int MASK_SIZE = mask*mask;
LL *headL, *tailL;
int *head, *tail;
r = mask / 2;
rowImg = (LL *)malloc(sizeof(LL)*nrows*ncols);
buffer = (LL *)malloc(sizeof(LL)*(MAX_ROW_COL + mask));
len = nrows + 2 * r;
srcPtr = srcImg;
rowPtr = rowImg;
for (col = 0; col < ncols; ++col)
{
srcPtr = srcImg + col;
head = srcPtr + r*ncols;
tail = srcPtr + (nrows - 2 - r)*ncols;
for (i = 0; i < r; ++i)
{
buffer[i] = *head;
buffer[len - 1 - i] = *tail;
head += ncols;
tail -= ncols;
}
for (i = r; i < len - r; ++i)
{
buffer[i] = *srcPtr;
srcPtr += ncols;
}
sum = buffer[0];
for (i = 1; i < mask; ++i)
{
sum += buffer[i];
}
rowPtr = rowImg + col;
*rowPtr = sum;
pre = sum;
headL = buffer;
tailL = buffer + mask;
for (i = mask; i < len; ++i, ++headL, ++tailL)
{
*rowPtr = pre;
rowPtr += ncols;
pre = pre - *headL + *tailL;
}
}
len = ncols + 2 * r;
rowPtr = rowImg;
desPtr = desImg;
for (row = 0; row < nrows; ++row)
{
headL = rowPtr + r;
tailL = rowPtr + (ncols - 2 - r);
for (i = 0; i < r; ++i)
{
buffer[i] = *headL;
buffer[len - 1 - i] = *tailL;
++headL;
--tailL;
}
for (i = r; i < len - r; ++i)
{
buffer[i] = *rowPtr;
++rowPtr;
}
sum = buffer[0];
for (i = 1; i < mask; ++i)
{
sum += buffer[i];
}
*desPtr = sum/MASK_SIZE;
++desPtr;
pre = sum;
headL = buffer;
tailL = buffer + mask;
for (i = mask; i < len; ++i, ++headL, ++tailL)
{
*desPtr = pre/MASK_SIZE;
++desPtr;
pre = pre - *headL + *tailL;
}
}
free(rowImg);
free(buffer);
return;
}

Rotate a 2D NxN matrix in Concentric Circles

Given a 2D NxN matrix, visualize it as concentric circles. You have to find the rotated matrix where each element in the circle is rotated by 1 position layer by layer in an alternate clockwise and anticlockwise direction. All rotations should be in-place.
2 3 4 5
1 6 7 8
4 2 1 9
5 3 2 4
should get transformed to
1 2 3 4
4 7 1 5
5 6 2 8
3 2 4 9
I thought about the solution
1> For clockwise circle rotation, read elements in the order
i -> 0 to n-1 and j = 0
j -> 0 to n-1 and i = n-1
i -> n-1 to 0 and j = n-1
j -> n-1 to 0 and i = 0
2> For anti-clockwise circle rotation, read elements in the order
j -> 0 to n-1 and i = 0
i -> 0 to n-1 and j = n-1
j -> n-1 to 0 and i = n-1
i -> n-1 to 0 and j = 0
Code
for(int cnt = 0; cnt < n/2; cnt++)
{
if(cnt%2 == 0) // Clockwise
{
i = cnt; j = cnt;
// while loops for each case
}
else // anti-clockwise
{
i = cnt; j = cnt;
// while loops for each case
}
}
Is there any better approach to solve this problem in O(n2) or better ?
As your array is of size N*N and the desired computation demands each element to be visited atleast once, there cannot be a solution better than O(n^2) which uses 2 dimensional arrays.
I think that your solution will be fine if the operation has to be done single time on the same array.
If you have to do this operation multiple times on the same input array, better create circles from the input array. The data structure of circle should be a CLL (circular linked list). So doing the operation multiple times will be piece of cake as you have to change the root element of the CLL storing the circle info depending on the direction.
I think that this can be solved easily in-place in O(n) time.
(NOTE: O(N) where N is the total number of matrix elements)
The following solution doesn't use four consecutive loops, but uses a small table of [X, Y] deltas that describe the difference between the current coordinate and the next one, when the next coordinate is invalid (i.e outside of the current window) the index to the table itself is advanced and the look-up repeated. The algorithm starts with full window and decreases it by one element from each side every time the nested loop finishes. The whole process repeats until the window defined as [minX, minY, maxX, maxY] is valid (i.e. contains at least 2x2 elements).
This solution doesn't implement swapping cw and ccw, but this is the easiest part to add.
function pad(s, n) {
while(s.length < n)
s = " " + s;
return s;
}
// Create a matrix of [WxH] size.
function Matrix(w, h, data) {
if (Array.isArray(data)) {
if (data.length !== w * h)
throw new Error("Data.length has to match the size " + (w * h) + ".");
}
else {
var n = typeof data === "number" ? data : 0.0;
data = [];
for (var i = 0; i < w*h; i++) data.push(n);
}
this.w = w;
this.h = h;
this.data = data;
}
// Get value at [x, y]
Matrix.prototype.get = function(x, y) {
if (x < 0 || x >= this.w || y < 0 || y >= this.h)
throw new Error("Index [" + x + ", " + y + "] out of bounds");
return this.data[y * this.w + x];
}
// Set value at [x, y] and return the previous value.
Matrix.prototype.set = function(x, y, value) {
if (x < 0 || x >= this.w || y < 0 || y >= this.h)
throw new Error("Index [" + x + ", " + y + "] out of bounds");
var i = y * this.w + x;
var prev = this.data[i];
this.data[i] = value;
return prev;
}
// Log the matrix data.
Matrix.prototype.dump = function() {
var s = "["
var i = 0;
for (var y = 0; y < this.h; y++) {
for (var x = 0; x < this.w; x++, i++) {
s += pad("" + this.data[i], 2);
if (x !== this.w - 1)
s += ","
}
if (y !== this.h - 1)
s += ",\n ";
}
s += "]";
console.log(s);
}
// Shift, `dir` can be "cw" or "ccw".
Matrix.prototype.shift = function(dir) {
var instructions = {
cw : [1, 0, 0, 1,-1, 0, 0,-1],
ccw: [0, 1, 1, 0, 0,-1,-1, 0]
};
var inst = instructions[dir];
// A window, shrink by one from each side after the nested loop is done.
var minX = 0;
var minY = 0;
var maxX = this.w - 1;
var maxY = this.h - 1;
while (minX < maxX && minY < maxY) {
// Always start at the top-left corner and iterate.
var x0 = minX;
var y0 = minY;
var v0 = this.get(x0, y0);
var n = 0;
for (;;) {
var x1 = x0 + inst[n + 0];
var y1 = y0 + inst[n + 1];
if (x1 < minX || x1 > maxX || y1 < minY || y1 > maxY) {
n += 2;
x1 = x0 + inst[n + 0];
y1 = y0 + inst[n + 1];
}
v0 = this.set(x1, y1, v0);
// Last one.
if (x1 === minX && y1 === minY)
break;
x0 = x1;
y0 = y1;
}
minX++;
minY++;
maxX--;
maxY--;
}
}
var a = new Matrix(3, 3, [
1,2,3,
4,5,6,
7,8,9,
]);
a.dump();
a.shift("cw");
a.dump();
var b = new Matrix(4, 4, [
1 ,2 ,3 ,4 ,
5 ,6 ,7 ,8 ,
9 ,10,11,12,
13,14,15,16
]);
b.dump();
b.shift("ccw");
b.dump();
I faced this problem recently in a job interview and I failed to solve it in under one hour.
Then I got home and produced the code below in java. It is recursive and I believe it has O(n^2) complexity. You can also see the code here: https://github.com/lotif/rotateMatrix
You will have first to input the dimension of the (square) matrix and then the numbers of the matrix itself separated by spaces, line by line. For instance:
3
1 2 3
4 5 6
7 8 9
It will return you the matrix rotated clockwise in concentric circles.
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class RotateMatrix {
public static void main(String args[] ) throws Exception {
Scanner s = new Scanner(System.in);
int d = s.nextInt();
int[][] matrix = new int[d][d];
for(int i = 0; i < d; i++) {
for(int j = 0; j < d; j++) {
matrix[i][j] = Integer.parseInt(s.next());
}
}
matrix = rotate(matrix);
for(int i = 0; i < matrix.length; i++) {
for(int j = 0; j < matrix.length; j++) {
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
s.close();
}
public static int[][] rotate(int[][] matrix) {
if(matrix == null || matrix.length == 0 || matrix.length == 1) {
return matrix;
}
List<Integer> outerCircle = getOuterCircle(matrix);
matrix = removeOuterCircle(matrix);
//rotating outer circle
outerCircle.add(0, outerCircle.remove(outerCircle.size() - 1));
matrix = rotate(matrix);
matrix = addOuterCircle(outerCircle, matrix);
return matrix;
}
private static int[][] addOuterCircle(List<Integer> outerCircle, int[][] matrix) {
int d = matrix.length + 2;
int[][] newMatrix = new int[d][d];
//Adding the outer circle to the matrix
for(int j = 0; j < d; j++) {
newMatrix[0][j] = outerCircle.remove(0);
}
for(int i = 1; i < d; i++) {
newMatrix[i][d-1] = outerCircle.remove(0);
}
for(int j = d-2; j >= 0; j--) {
newMatrix[d-1][j] = outerCircle.remove(0);
}
for(int i = d-2; i >= 1; i--) {
newMatrix[i][0] = outerCircle.remove(0);
}
//Adding the inner matrix
for(int i = 0; i < matrix.length; i++) {
for(int j = 0; j < matrix[i].length; j++) {
newMatrix[i + 1][j + 1] = matrix[i][j];
}
}
return newMatrix;
}
private static List<Integer> getOuterCircle(int[][] matrix) {
int d = matrix.length;
List<Integer> outerCircle = new ArrayList<Integer>();
for(int j = 0; j < d; j++) {
outerCircle.add(matrix[0][j]);
}
for(int i = 1; i < d; i++) {
outerCircle.add(matrix[i][d-1]);
}
for(int j = d-2; j >= 0; j--) {
outerCircle.add(matrix[d-1][j]);
}
for(int i = d-2; i >= 1; i--) {
outerCircle.add(matrix[i][0]);
}
return outerCircle;
}
private static int[][] removeOuterCircle(int[][] matrix) {
int d = matrix.length;
int[][] newMatrix = new int[d-2][d-2];
for(int i = 1; i < d-1; i++) {
for(int j = 1; j < d-1; j++) {
newMatrix[i-1][j-1] = matrix[i][j];
}
}
return newMatrix;
}
}
public class ShiftArray {
static void shiftArray(int[][]a, int index, int n) {
if ((n%2 == 0) && (index >= n/2))
return;
if ((n%2 != 0) && (index > n/2))
return;
int tempRowTopLast = a[index][n-1-index];
int tempColRightLast = a[n-1-index][n-1-index];
int tempRowBottomLast = a[n-1-index][index];
int tempColLeftLast = a[index][index];
int temp, temp2;
temp = tempColLeftLast;
for (int k = index + 1; k < n-index; k++) {
temp2 = a[index][k];
a[index][k] = temp;
temp = temp2;
}
temp = tempRowTopLast;
for (int k = index + 1; k < n-index; k++) {
temp2 = a[k][n-1-index];
a[k][n-1-index] = temp;
temp = temp2;
}
temp = tempColRightLast;
for (int k = n-2-index; k >=index; k--) {
temp2 = a[n-1-index][k];
a[n-1-index][k] = temp;
temp = temp2;
}
temp = tempRowBottomLast;
for (int k = n-2-index; k >=index; k--) {
temp2 = a[k][index];
a[k][index] = temp;
temp = temp2;
}
shiftArray(a, index+1, n);
}
public static void main(String[] args) {
int a[][] = {{1, 2, 3}, {4, 5, 6}, {7, 8, 9}};
shiftArray(a, 0, 3);
System.out.println("Rotated array...");
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 3; j++) {
System.out.print(a[i][j] + ",");
}
System.out.println();
}
}
}
import java.util.Scanner;
public class RotateMatrix
{
static int rows = 0;
static int cols = 0;
public static void main(String[] args)
{
// TODO Auto-generated method stub
Scanner scan = new Scanner(System.in);
rows = scan.nextInt();
cols = scan.nextInt();
int rots = scan.nextInt();
int[][] matrix = new int[rows][cols];
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
matrix[i][j] = scan.nextInt();
}
}
for (int i = 0; i < rots; i++)
rotate(matrix, 0, rows - 1, 0, cols - 1);
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
System.out.print(matrix[i][j] + " ");
}
System.out.println();
}
scan.close();
}
public static int[][] rotate(int[][] arr, int rowStart, int rowEnd, int colStart, int colEnd)
{
if (rowStart == rowEnd && colStart == colEnd)
{
return arr;
}
if (rowStart > rowEnd || colStart > colEnd)
{
return arr;
}
int temp = arr[rowStart][colStart];
for (int j = colStart; j < colEnd; j++)
{
arr[colStart][j] = arr[colStart][j + 1];
}
for (int i = rowStart; i < rowEnd; i++)
{
arr[i][colEnd] = arr[i + 1][colEnd];
}
for (int i = colEnd; i > colStart; i--)
{
arr[rowEnd][i] = arr[rowEnd][i - 1];
}
for (int i = rowEnd; i > rowStart; i--)
{
arr[i][colStart] = arr[i - 1][colStart];
}
if (rows == 1)
{
arr[colEnd][rowStart] = temp;
}
else
arr[rowStart + 1][colStart] = temp;
System.out.println("-----------------------------------------\n");
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < cols; j++)
{
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
System.out.println("-----------------------------------------\n");
rotate(arr, rowStart + 1, rowEnd - 1, colStart + 1, colEnd - 1);
return arr;
}
}
Clockwise rotation by 90 degrees. O(n^2) time and O(1) memory in Python3:
# #param A : list of list of integers
# #return the same list modified
def rotate(A):
for row in range(len(A) // 2):
for col in range(row, len(A)-1 - row): # First col already takes care of last.
r = row
c = col
tmp1 = A[r][c]
while True:
next_r = c
next_c = len(A) - 1 - r
tmp2 = A[next_r][next_c]
A[next_r][next_c] = tmp1
if next_r == row and next_c == col:
break
tmp1 = tmp2
r = next_r
c = next_c
return A

Resources