Given a matrix you shall stripe the matrix, such that every number that has equal distance to the matrix border will be filled into an array.
For examples see code comments.
typedef int matrixOptimizationValue;
/*
Striping a matrix by packing numbers who have the same distance from matrix border.
Note that the packing is anti-clockwise.
E.g:
Example 1:
___ ___
. 1 1 1 1 . Field:
. 2 2 2 2 . [1,2,3,3,3,3,2,1,1,1]
. 3 3 3 3 . --> [2,2]
___ ___
Example 2:
___ ___ Field:
. 1 1 1 4 1 . [1,2,3,1,2,4,5,6,3,2,1,4,1,1,1]
. 2 2 2 3 2 . [2,3,3,3,2,3,2,3,2,2]
. 3 3 3 2 3 . -->
. 1 2 4 5 6 .
___ ___
returns:
return_value - Field of Arrays; unpacked Matrix
arr_lengths - Since fields arrays have a variable size, "*array_lengths" contains the following information.
{Amount of arrays in the field, sizes_of_array01, sizes_of_array03 ... }
Therefore "*array_lengths" size must be *array_lengths[0]+1.
in:
const int* matrix - Matrix to be unpacked
int rows - rows of the matrix
int columns - columns of the matrix
Possible Errors:
1. Matrix has no measurments.
*/
matrixOptimizationValue** strip(const matrixOptimizationValue* matrix, const int rows, const int columns, int** arr_lengths){
//Checking if Matrix has measurments.
int* lengths = *arr_lengths;
if(rows == 0 || columns == 0){
printf("\nMatrix has no measurments. Error. \n");
exit(0);
}
//Calculating maximal distance of an element to borders.
const int max_dis = (columns > rows) ? round((double)(rows)/2) : round((double)(columns)/2);
//Creating future return_value
matrixOptimizationValue** unstriped_matrix = malloc(max_dis*sizeof(int*));
(lengths) = malloc((max_dis+1) * sizeof(matrixOptimizationValue));
(lengths)[0] = max_dis;
//Packing...
int x_minborder = 0; //Borders
int y_minborder = 0;
int x_maxborder = columns;
int y_maxborder = rows;
for(int i = 0; i < max_dis; i++){
int elements_size=0; //Unfortunately, making "const" causes really bad syntax...
if(x_maxborder-x_minborder <= 1 || y_maxborder-y_minborder <=1){
if(x_maxborder-x_minborder <= 1 && y_maxborder-y_minborder <=1){
elements_size = 1;
} else {
elements_size = (x_maxborder-x_minborder == 1) ? y_maxborder-y_minborder : x_maxborder-x_minborder;
}
} else {
elements_size = 2*(x_maxborder-x_minborder + y_maxborder-y_minborder)-4;
}
matrixOptimizationValue* array = malloc(elements_size * sizeof(int));
(lengths)[i+1]=elements_size;
//Initializing coordinates
int x = i; //It is certain, that this coordinates will always belong to fields array_i;
int y = i;
int dir_x = 0; //Direction
int dir_y = 1;
for(int j = 0; j < elements_size; j++){
array[j] = matrix[y*columns + x];
if(x+dir_x >= x_maxborder || x+dir_x < x_minborder || y+dir_y >= y_maxborder || y+dir_y < y_minborder){
/*Rotate Direction-vector using Algebra
x
y
0 1 y
-1 0 -x
*/
const int clone = dir_x;
dir_x = dir_y;
dir_y = -clone;
}
x += dir_x;
y += dir_y;
}
x_minborder++;
y_minborder++;
x_maxborder--;
y_maxborder--;
unstriped_matrix[i]=array;
}
return unstriped_matrix;
}
- How would you improve the syntax?
- Assume high-performance needs, how would you improve the code?