Skip to content
Snippets Groups Projects
Commit 1aff883d authored by florian.burgener's avatar florian.burgener
Browse files

Exercice 4

parent 212a62b5
Branches
Tags
No related merge requests found
......@@ -9,37 +9,264 @@
*
*/
#include <assert.h>
#include <math.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#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;
}
// ---
Node *clone(Node *root) {
if (root == NULL) {
return NULL;
}
Node *output = node_init();
output->data = root->data;
for (int i = 0; i < 4; i += 1) {
output->children[i] = clone(root->children[i]);
}
return output;
}
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 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);
Node *tree_cloned = clone(tree);
quadtree_destroy(&tree);
Matrix *matrix_output = quadtree_to_matrix(tree_cloned);
quadtree_destroy(&tree_cloned);
// matrix_print(matrix_input);
matrix_print(matrix_output);
// Assert that the two matrices are not the same in memory and that they have the same data.
assert(matrix_input != matrix_output);
assert(matrix_input->data != matrix_output->data);
for (int i = 0; i < matrix_input->m; i += 1) {
assert(matrix_input->data[i] != matrix_output->data[i]);
for (int j = 0; j < matrix_input->n; j += 1) {
assert(matrix_input->data[i][j] == matrix_output->data[i][j]);
assert(matrix_input->data[i][j] == matrix_output->data[i][j]);
}
}
matrix_destroy(&matrix_input);
matrix_destroy(&matrix_output);
return EXIT_SUCCESS;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment