3
\$\begingroup\$

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;
}
  1. How would you improve the syntax?
  2. Assume high-performance needs, how would you improve the code?
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.