diff --git a/ex5/ex5.c b/ex5/ex5.c index 07a61c08cc6aa8ac5c11b48456e5f0f3d9345b73..b06d07c010aa9950509555aa73f8e9c715dd1f60 100644 --- a/ex5/ex5.c +++ b/ex5/ex5.c @@ -16,30 +16,258 @@ #include <stdlib.h> #include <string.h> +// Matrix.h + +typedef struct Matrix { + int32_t m; + int32_t n; + int32_t **data; +} Matrix; + +Matrix *matrix_init(int32_t m, int32_t n); +void matrix_destroy(Matrix **matrix); +int32_t matrix_get(Matrix *matrix, int32_t y, int32_t x); +void matrix_set(Matrix *matrix, int32_t y, int32_t x, int32_t value); + +// Matrix.c + +Matrix *matrix_init(int32_t m, int32_t n) { + Matrix *matrix = (Matrix *)malloc(sizeof(Matrix)); + matrix->m = m; + matrix->n = n; + matrix->data = (int32_t **)malloc(sizeof(int32_t *) * m); + + for (int32_t i = 0; i < matrix->m; i += 1) { + matrix->data[i] = (int32_t *)calloc(n, sizeof(int32_t)); + } + + return matrix; +} + +void matrix_destroy(Matrix **matrix) { + for (int32_t i = 0; i < (*matrix)->m; i += 1) { + free((*matrix)->data[i]); + } + + free((*matrix)->data); + free(*matrix); + *matrix = NULL; +} + +int32_t matrix_get(Matrix *matrix, int32_t y, int32_t x) { + return matrix->data[y][x]; +} + +void matrix_set(Matrix *matrix, int32_t y, int32_t x, int32_t value) { + matrix->data[y][x] = value; +} + +void matrix_print(Matrix *matrix) { + for (int i = 0; i < matrix->m; i += 1) { + for (int j = 0; j < matrix->n; j += 1) { + printf("%2d ", matrix->data[i][j]); + } + + printf("\n"); + } +} + +// Quadtree.h + +#define CHILDREN_COUNT 4 + +typedef struct Node { + int data; + struct Node *children[CHILDREN_COUNT]; +} Node; + +int32_t _max(int32_t a, int32_t b); +Node *node_init(); +Node *quadtree_init(int32_t depth); +void quadtree_destroy(Node **root); +int32_t quadtree_depth(Node *root); +bool quadtree_is_leaf(Node *root); +Node *quadtree_search(Node *root, int32_t depth, int32_t y, int32_t x); +Node *matrix_to_quadtree(Matrix *matrix); +Matrix *quadtree_to_matrix(Node *root); + +// Quadtree.c + +int32_t _max(int32_t a, int32_t b) { + return a > b ? a : b; +} + +Node *node_init() { + Node *node = (Node *)malloc(sizeof(Node)); + node->data = 0; + + for (int32_t i = 0; i < CHILDREN_COUNT; i += 1) { + node->children[i] = NULL; + } + + return node; +} + +Node *quadtree_init(int32_t depth) { + Node *root = node_init(); + + if (depth == 0) { + return root; + } + + for (int32_t i = 0; i < CHILDREN_COUNT; i += 1) { + root->children[i] = quadtree_init(depth - 1); + } + + return root; +} + +void quadtree_destroy(Node **root) { + if (!quadtree_is_leaf(*root)) { + for (int32_t i = 0; i < CHILDREN_COUNT; i += 1) { + quadtree_destroy(&(*root)->children[i]); + } + } + + free(*root); + *root = NULL; +} + +int32_t quadtree_depth(Node *root) { + if (root == NULL) { + return -1; + } + + if (quadtree_is_leaf(root)) { + return 0; + } + + int32_t biggest_depth = 0; + + for (int32_t i = 0; i < CHILDREN_COUNT; i += 1) { + biggest_depth = _max(biggest_depth, quadtree_depth(root->children[i])); + } + + return biggest_depth + 1; +} + +bool quadtree_is_leaf(Node *root) { + return root->children[0] == NULL; +} + +Node *quadtree_search(Node *root, int32_t depth, int32_t y, int32_t x) { + for (int32_t d = depth - 1; d >= 0; d -= 1) { + if (quadtree_is_leaf(root)) { + return root; + } + + int32_t i = (y >> d) & 1; + int32_t j = (x >> d) & 1; + root = root->children[2 * i + j]; + } + + return root; +} + +Node *matrix_to_quadtree(Matrix *matrix) { + int32_t depth = (int32_t)log2(matrix->m); + Node *root = quadtree_init(depth); + + for (int32_t i = 0; i < matrix->m; i += 1) { + for (int32_t j = 0; j < matrix->n; j += 1) { + Node *node = quadtree_search(root, depth, i, j); + node->data = matrix_get(matrix, i, j); + } + } + + return root; +} + +Matrix *quadtree_to_matrix(Node *root) { + int32_t depth = quadtree_depth(root); + int32_t size = (int32_t)pow(2, depth); + Matrix *matrix = matrix_init(size, size); + + for (int32_t i = 0; i < matrix->m; i++) { + for (int32_t j = 0; j < matrix->n; j++) { + Node *node = quadtree_search(root, depth, i, j); + int32_t value = node->data; + matrix_set(matrix, i, j, value); + } + } + + return matrix; +} + +// --- + +int quadtree_max(Node *root) { + if (quadtree_is_leaf(root)) { + return root->data; + } + + int max_value = 0; + for (int i = 0; i < 4; i += 1) { + max_value = _max(max_value, quadtree_max(root->children[i])); + } + + return max_value; +} + +void transform(Node *root, int *indices, int indices_length) { + for (int i = 0; i < indices_length; i += 1) { + root = root->children[indices[i]]; + } + + int max_value = quadtree_max(root); + for (int32_t i = 0; i < CHILDREN_COUNT; i += 1) { + quadtree_destroy(&root->children[i]); + } + root->data = max_value; +} + int main() { - // int32_t values_length = 5; - // double values[values_length]; - - // for (int32_t i = 0; i < values_length; i += 1) { - // double value; - // scanf("%lf", &value); - // values[i] = value; - // } - - // int32_t values_length = 5; - // int32_t values[values_length]; - - // for (int32_t i = 0; i < values_length; i += 1) { - // int32_t value; - // scanf("%d", &value); - // values[i] = value; - // } - - // char a[100]; - // int32_t b; - // scanf("%s %d", a, &b); - // printf("%s %d\n", a, b); - - printf("ex1\n"); + // !!! + int indices_length = 2; + int indices[] = {3, 1}; + + int n = 16; + int32_t input[16][16] = { + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 3, 3, 3, 3, 0, 0, 7, 7, 7, 7, 0, 0, 11, 11, 11}, + {0, 3, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 11, 0, 0}, + {0, 3, 3, 3, 0, 0, 0, 7, 7, 7, 0, 0, 0, 11, 11, 11}, + {0, 3, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 11, 0, 0}, + {0, 3, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 0, 11, 11, 11}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 3, 3, 3, 3, 0, 0, 7, 7, 7, 7, 0, 0, 11, 11, 11}, + {0, 3, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 11, 0, 0}, + {0, 3, 3, 3, 0, 0, 0, 7, 7, 7, 0, 0, 0, 11, 11, 11}, + {0, 3, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 11, 0, 0}, + {0, 3, 0, 0, 0, 0, 0, 7, 7, 7, 7, 0, 0, 11, 11, 11}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {0, 3, 3, 3, 3, 0, 0, 7, 7, 7, 7, 0, 0, 11, 11, 11}, + }; + + Matrix *matrix_input = matrix_init(n, n); + + for (int i = 0; i < n; i += 1) { + for (int j = 0; j < n; j += 1) { + matrix_set(matrix_input, i, j, input[i][j]); + } + } + + Node *tree = matrix_to_quadtree(matrix_input); + transform(tree, indices, indices_length); + Matrix *matrix_output = quadtree_to_matrix(tree); + quadtree_destroy(&tree); + + // matrix_print(matrix_input); + matrix_print(matrix_output); + + matrix_destroy(&matrix_input); + matrix_destroy(&matrix_output); return EXIT_SUCCESS; }