From 0912e52a7ad924286b745d17f08113698de8d337 Mon Sep 17 00:00:00 2001 From: Hugo LAMY Date: Sat, 18 May 2019 15:34:47 +0200 Subject: [PATCH 1/2] clean les comments --- parse_input.c | 18 +++++++++--------- search_map.c | 40 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 47 insertions(+), 11 deletions(-) diff --git a/parse_input.c b/parse_input.c index b3ef28f..933983b 100644 --- a/parse_input.c +++ b/parse_input.c @@ -6,7 +6,7 @@ /* By: vmanzoni +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/04/15 14:48:14 by vmanzoni #+# #+# */ -/* Updated: 2019/05/17 18:40:30 by hulamy ### ########.fr */ +/* Updated: 2019/05/18 14:17:14 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -58,6 +58,14 @@ unsigned short reduce_tetri(unsigned short tetri, int width) /* ** Function that transforme a tetriminos char* into a short of 16 bites ** and then fills it and its reversed into the list +** +** 1) transforme la ligne de . et # en un short de 0 et 1 +** 2) cree un mask avec des 1 sur la colonne de droite (#...#...#...#...) +** 3) utilise le mask pour trouver la largeur que prend le tetriminos +** 4) deplace le tetriminos tout en haut a gauche +** (i - list->width = le nombre de colonne vide a gauche) +** 5) trouve la hauteur du tetri +** 6) fabrique la ligne pour le tetriminos de la bonne largeur */ void fill_list(char line[], t_fillist *list) @@ -65,12 +73,9 @@ void fill_list(char line[], t_fillist *list) unsigned int mask; int i; - // transforme la ligne de . et # en un short de 0 et 1 list->tetribit = tab_to_bin(line); list->memory = 0; - // cree un mask avec des 1 sur la colonne de droite (#...#...#...#...) mask = (1 << 15) | (1 << 11) | (1 << 7) | (1 << 3); - // utilise le mask pour trouver la largeur que prend le tetriminos i = 0; while (!(mask & list->tetribit) && i++ < 4) mask >>= 1; @@ -78,19 +83,14 @@ void fill_list(char line[], t_fillist *list) while (mask & list->tetribit && ++i < 4) mask >>= 1; list->width = i - list->width; - // deplace le tetriminos tout en haut a gauche - //(i - list->width = le nombre de colonne vide a gauche) list->tetribit <<= (i - list->width); while (!(list->tetribit & (~0u << 12))) list->tetribit <<= 4; - // trouve la hauteur du tetri i = 0; while (i < 4 && list->tetribit & (~0u << 28 >> (i * 4 + 16))) i++; list->height = i; - // fabrique la ligne pour le tetriminos de la bonne largeur list->tetribit = reduce_tetri(list->tetribit, list->width); - list->position = 0; list->test = 0; // DEBUG pour que print_final_map puisse imprimer correctement au fur et a mesure } diff --git a/search_map.c b/search_map.c index 457388d..e211921 100644 --- a/search_map.c +++ b/search_map.c @@ -6,12 +6,49 @@ /* By: hulamy +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/04/27 20:47:22 by hulamy #+# #+# */ -/* Updated: 2019/05/17 18:31:44 by hulamy ### ########.fr */ +/* Updated: 2019/05/18 15:16:26 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ #include "fillit.h" +/* +** OLD VERSION of find_place and fit_in_place all in one but with a lot of divisions and modulo +** +** int find_place(unsigned int *tab, t_fillist *list, int size, int pos) +** { +** int i; +** int j; +** unsigned int mask; +** unsigned int tmp; +** +** mask = ~0u << (32 - list->width); +** tmp = mask; +** i = pos; +** while (i < (size - list->height + 1) * size) +** { +** if (i % size == size - list->width + 1) +** i += list->width - 1; +** else +** { +** tmp = 0; +** j = (list->height - 1) * size + i; +** while (j >= i) +** { +** tmp >>= list->width; +** tmp |= (mask & (tab[j / 32] << j)); +** tmp |= (mask & (tab[(j + list->width) / 32] >> (32 - j))); +** j -= size; +** } +** if (!((tmp >> 16) & list->tetribit)) +** return (i + 1); +** i++; +** } +** } +** return (0); +** } +*/ + /* ** function that look if a tretri fit in a place */ @@ -91,7 +128,6 @@ void add_remove(unsigned int *map, t_fillist *list, int size) mask = ~0u << (32 - list->width); i = (list->height - 1) * list->width; j = (list->height - 1) * size + list->position; - // change les bits du tetri sur la map a la position donnee while (j >= list->position) { map[(j - 1) / 32] ^= (mask & tetri << (16 + i)) >> (j - 1); From c2e87b7303d631018a94093ed4d132626f9fbdc4 Mon Sep 17 00:00:00 2001 From: Hugo LAMY Date: Mon, 20 May 2019 15:42:30 +0200 Subject: [PATCH 2/2] opti fonctionne super bien et super mal --- fillit.h | 4 +- samples/map_hard | 40 +++++++++++ search_map.c | 184 +++++++++++++++++++++++++++++++++-------------- 3 files changed, 172 insertions(+), 56 deletions(-) diff --git a/fillit.h b/fillit.h index faf090b..15b7219 100644 --- a/fillit.h +++ b/fillit.h @@ -6,7 +6,7 @@ /* By: vmanzoni +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/03/01 13:34:46 by vmanzoni #+# #+# */ -/* Updated: 2019/05/17 18:37:47 by hulamy ### ########.fr */ +/* Updated: 2019/05/20 15:18:43 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -58,7 +58,7 @@ typedef struct s_fillist int num; int test; char letter; - uint64_t memory; + unsigned int *memory; struct s_fillist *same; struct s_fillist *next; } t_fillist; diff --git a/samples/map_hard b/samples/map_hard index 887429b..50fb7fa 100644 --- a/samples/map_hard +++ b/samples/map_hard @@ -47,3 +47,43 @@ .#.. ##.. .... + +.#.. +.#.. +##.. +.... + +...# +...# +..## +.... + +#... +###. +.... +.... + +.#.. +.#.. +##.. +.... + +.#.. +.#.. +##.. +.... + +...# +...# +..## +.... + +#... +###. +.... +.... + +.#.. +.#.. +##.. +.... diff --git a/search_map.c b/search_map.c index e211921..eb0cfba 100644 --- a/search_map.c +++ b/search_map.c @@ -6,7 +6,7 @@ /* By: hulamy +#+ +:+ +#+ */ /* +#+#+#+#+#+ +#+ */ /* Created: 2019/04/27 20:47:22 by hulamy #+# #+# */ -/* Updated: 2019/05/18 15:16:26 by hulamy ### ########.fr */ +/* Updated: 2019/05/20 15:41:59 by hulamy ### ########.fr */ /* */ /* ************************************************************************** */ @@ -49,6 +49,73 @@ ** } */ +/* +** function that try to optimize the speed +** SECOND ATTEMPT +** by finding the isolated dots whille fillling the map +** untill they get more numerous than the max amount available +** TOTAL FAILURE :p +** +** int check_others(unsigned int *map, t_fillist *list, int size, int num) +** { +** t_fillist *tmp; +** int dots; +** int total; +** int i; +** int j; +** +** dots = 0; +** i = -1; +** num *= 4; +** total = size * size; +** while (++i < total && dots <= total - num) +** { +** tmp = list->next; +** j = 1; +** // saute les position pas vides +** while (1 << (i % 32) & map[i % 32]) +** i++; +** // pour chaque position vide regarde si chaque tetri non encode places peuvent y rentrer +** while (j && tmp) +** { +** // si le tetri est trop a droite ou trop en bas il ne rentre pas ce n'est pas la peine de chercher donc on passe au tetri suivant +** if (tmp->width > (size - i % size) || (total - i) <= (tmp->height * size)) +** tmp = tmp->next; +** // sinon verifier si on peut le mettre a cette position et si on ne peut pas passer au tetri suivant +** else if (!fit_in_place(map, list, size, i)) +** tmp = tmp->next; +** // si le tetri peut rentrer on arrete la boucle en mettant j = 0 +** else +** j = 0; +** } +** // si j existe c que le tetri ne pouvait pas etre place donc on rajoute 1 au compteur de point isoles +** if (j) +** dots++; +** } +** return (dots > total - num); +** } +*/ + +/* +** function that try to optimize the speed +** FIRST ATTEMPT +** by verifying if the place left is enough to place at least +** one of each tetri left +** TOTAL FAILURE :p +** +** int check_others(unsigned int *map, t_fillist *list, int size, int num) +** { +** t_fillist *tmp; +** +** // verifie que les tetri restant puissent un par un se placer sur la map +** // ca n'optimise qu'en fin de map donc ca ralentit les grosses map en fait +** while ((tmp = tmp->next)) +** if (!find_place(map, tmp, size, 0)) +** return (0); +** return (1); +** } +*/ + /* ** function that look if a tretri fit in a place */ @@ -141,66 +208,26 @@ void add_remove(unsigned int *map, t_fillist *list, int size) ** Test optimisation for not testing wrong maps when tetri are identical */ -int compare_tetri(t_fillist *tetri_a, t_fillist *tetri_b) -{ - if (tetri_a->tetribit != tetri_b->tetribit) - return (0); - if (tetri_a->width != tetri_b->width) - return (0); - if (tetri_a->height != tetri_b->height) - return (0); - return (1); -} - -/* -** Test optimisation for not testing wrong maps when tetri are identical -*/ - -int check_same_tetri(t_fillist *list) -{ - t_fillist *curr_tetri; - t_fillist *next_tetri; - - curr_tetri = list; - - while (curr_tetri != NULL) - { - next_tetri = curr_tetri->next; - while (next_tetri != NULL) - { - if (compare_tetri(curr_tetri, next_tetri)) - { - if (next_tetri->same == NULL) - next_tetri->same = curr_tetri; - printf("%c->%c\n", next_tetri->letter, next_tetri->same->letter); - } - next_tetri = next_tetri->next; - } - curr_tetri = curr_tetri->next; - } - return (0); -} - -/* -** Test optimisation for not testing wrong maps when tetri are identical -*/ - int check_tetri_memory(t_fillist *list, int pos) { - t_fillist *tetri; - uint64_t mask; + t_fillist *tetri; + unsigned int mask; tetri = list; + mask = 1 << ((pos % 32) - 1); if (tetri->same != NULL) { - mask = 1 << (pos - 1); - print_bits(mask, 64); - if (tetri->same->memory & mask) + if (!(tetri->same->memory[pos / 32] & mask)) { - ft_putstr("test\n"); - return (pos + 1); + tetri->same->memory[pos / 32] |= mask; + return (1); } } + else + { + tetri->memory[pos / 32] |= mask; + return (1); + } return (0); } @@ -216,13 +243,61 @@ int fill_map(unsigned int *map, t_fillist *list, int size) while (find_place(map, list, size)) { add_remove(map, list, size); - if (fill_map(map, list->next, size)) - return (1); + if (check_tetri_memory(list, list->position)) + if (fill_map(map, list->next, size)) + return (1); add_remove(map, list, size); } return (0); } +/* +** Test optimisation for not testing wrong maps when tetri are identical +*/ + +int compare_tetri(t_fillist *tetri_a, t_fillist *tetri_b) +{ + if (tetri_a->tetribit != tetri_b->tetribit) + return (0); + if (tetri_a->width != tetri_b->width) + return (0); + if (tetri_a->height != tetri_b->height) + return (0); + return (1); +} + +/* +** Test optimisation for not testing wrong maps when tetri are identical +*/ + +int check_same_tetri(t_fillist *list, int num) +{ + t_fillist *curr_tetri; + t_fillist *next_tetri; + int i; + + curr_tetri = list; + while (curr_tetri != NULL) + { + curr_tetri->same = NULL; + i = 0; + if (!(curr_tetri->memory = (unsigned int *)malloc(sizeof(*curr_tetri->memory) * num))) + return (0); + while (i < num) + curr_tetri->memory[i++] = 0; + next_tetri = curr_tetri->next; + while (next_tetri != NULL) + { + if (compare_tetri(curr_tetri, next_tetri)) + if (next_tetri->same == NULL) + next_tetri->same = curr_tetri; + next_tetri = next_tetri->next; + } + curr_tetri = curr_tetri->next; + } + return (0); +} + /* ** function that send to "fill_map" a map of a certain size and increment its size untill it's solved */ @@ -262,6 +337,7 @@ int search_map(t_fillist *list) num = (size * size) / 32 + 1; if (!(map = (unsigned int *)malloc(sizeof(*map) * num))) return (0); + check_same_tetri(list, num); while (num) map[num--] = 0; i = fill_map(map, list, size++);