diff --git a/fillit/Makefile b/fillit/Makefile index 1953f9ca..e3c49053 100644 --- a/fillit/Makefile +++ b/fillit/Makefile @@ -1,7 +1,6 @@ NAME = fillit CC = gcc - D_SRC = src F_SRC := $(shell ls -1 $(D_SRC) | grep "\.c$$") @@ -13,7 +12,7 @@ D_INC = includes D_LIB = lib D_LIB := $(shell find $(D_LIB) -maxdepth 1 -mindepth 1 -type d) -D_LIB := $(addprefix -L,$(D_LIB)) +O_LIB := $(addprefix -L,$(D_LIB)) F_LIB = ft F_LIB := $(addprefix -l, $(F_LIB)) @@ -23,7 +22,7 @@ MKDIR = mkdir -p RM = /bin/rm -rf -.PHONY: all clean fclean re +.PHONY: all clean fclean re lib/libft all: $(NAME) @@ -32,8 +31,11 @@ $(D_OBJ)/%.o: $(D_SRC)/%.c $(D_INC) @$(CC) -I$(D_INC) $(W_FLAGS) -c $< -o $@ $(DEBUG) @echo "Compiling "$<"..." -$(NAME): $(F_OBJ) - $(CC) -I$(D_INC) $(D_LIB) $(F_LIB) $(W_FLAGS) $(F_OBJ) -o $@ $(DEBUG) +$(D_LIB): + @$(MAKE) -C $@ 2>/dev/null + +$(NAME): $(F_OBJ) $(D_LIB) + $(CC) -I$(D_INC) $(O_LIB) $(F_LIB) $(W_FLAGS) $(F_OBJ) -o $@ $(DEBUG) clean: $(RM) $(D_OBJ) diff --git a/fillit/includes/fillit.h b/fillit/includes/fillit.h index 54037caf..4adb4da9 100644 --- a/fillit/includes/fillit.h +++ b/fillit/includes/fillit.h @@ -5,17 +5,19 @@ # define FILLIT_H # define BUF_SIZE 32 -extern size_t g_target; -extern size_t g_ttmn; +extern int g_target; +extern int g_ttmn; extern char **g_sol; + typedef struct s_ttmn { char id; + int placed; int pos[4][2]; } t_ttmn; -t_ttmn *ft_get_ttmn(char *filename); +t_list *ft_get_ttmn(char *filename); char **ft_empty_board(size_t size); char **ft_copy_board(char **board); @@ -24,14 +26,15 @@ void ft_fill_board(char **dst, char **src); void ft_show_ttmn(t_ttmn ttmn); void ft_show_board(char **board); +void ft_ttmn_reset(t_list *ttmn); int ft_board_add(char **board, t_ttmn block, int i); void ft_board_remove(char **board, char c); -int ft_solver(char **board, t_ttmn *ttmn); +int ft_solver(char **board, t_list **amap, t_list *lttmn, int waste); -int ft_validate_waste(char **board, t_ttmn *ttmn); -int ft_waste_around(char **board, int size, int i); -int ft_waste_here(char **board, int size, int i); +/* int ft_check_blobs(char **board, t_list **amap, t_list *lblob, t_list *lttmn, int waste); */ +t_list *ft_waste_around(char **board, t_list **amap, int size, int i); +t_list *ft_waste_here(char **board, t_list **amap, int size, int i); #endif diff --git a/fillit/lib/libft b/fillit/lib/libft index c003567e..3b137f6f 160000 --- a/fillit/lib/libft +++ b/fillit/lib/libft @@ -1 +1 @@ -Subproject commit c003567e5584edb341161e6b924c328400ac7776 +Subproject commit 3b137f6f49a9b1025a3566272d3dfb7e7a44d316 diff --git a/fillit/src/fillit_lib.c b/fillit/src/board_lib.c similarity index 96% rename from fillit/src/fillit_lib.c rename to fillit/src/board_lib.c index 193ec552..81cbeb41 100644 --- a/fillit/src/fillit_lib.c +++ b/fillit/src/board_lib.c @@ -113,7 +113,7 @@ int ft_board_add(char **board, t_ttmn block, int i) /* fflush(stdout); */ if (x > size - 1 || y > size - 1 || x < 0 || y < 0) return (1); - if (board[y][x] != '.' && board[y][x] != '*' && board[y][x] != '^') + if (board[y][x] != '.' && board[y][x] != '*') return (1); k++; } diff --git a/fillit/src/fillit_blobs.c b/fillit/src/fillit_blobs.c new file mode 100644 index 00000000..170f1e90 --- /dev/null +++ b/fillit/src/fillit_blobs.c @@ -0,0 +1,150 @@ +#include "fillit.h" + +int ft_fit_blob(char **board, t_list **amap, t_list *lblob, t_list *lttmn, int waste) +{ + t_list *tmp; + t_list *list; + t_list *new_map; + t_list *blob; + t_ttmn *ttmn; + int size; + int i; + + size = ft_strlen(*board); + blob = *(t_list **)lblob->content; + /* ft_putendl("fitting blob :"); */ + /* ft_show_board(board); */ + /* ft_lst_print2(lblob, &ft_putnbr); */ + while (blob) + { + i = *(int*)blob->content; + /* printf("at i=%i\n", i); */ + /* fflush(stdout); */ + list = lttmn; + while (list) + { + ttmn = (t_ttmn *)list->content; + /* ft_show_ttmn(*ttmn); */ + if (ttmn->placed) + { + list = list->next; + continue ; + } + if (ft_board_add(board, *ttmn, i)) + { + list = list->next; + continue ; + } + ttmn->placed = 1; + new_map = ft_lstmap(*amap, &ft_id); + /* printf("just fitted ttmn %c\n", ttmn->id); */ + /* ft_show_ttmn(*ttmn); */ + if (ft_check_blobs(board, &new_map, lblob->next, lttmn, waste)) + return (1); + ttmn->placed = 0; + ft_board_remove(board, ttmn->id); + list = list->next; + } + blob = blob->next; + } + /* ft_putendl("failed to fit blob"); */ + return (0); +} + +int ft_get_blobs(char **board, t_list **amap, t_list *lttmn) +{ + t_list *lblob; + t_list *blob; + t_list *map; + int waste; + int size; + int i; + + if (!lttmn) + return (ft_solved(board)); + lblob = NULL; + waste = 0; + size = ft_strlen(*board); + map = *amap; + /* ft_putendl("getting blobs for"); */ + /* ft_lst_print(map, &ft_putnbr); */ + /* ft_show_board(board); */ + while (map) + { + i = *(int *)map->content; + blob = ft_waste_here(board, amap, size, i); + map = *amap; + if (ft_lstsize(blob) / 4 > 0) + ft_lsteadd(&lblob, ft_lstnew(&blob, sizeof(t_list *))); + /* ft_lst_print(blob, &ft_putnbr); */ + /* ft_lst_print(*(t_list **)ft_lstlast(lblob), &ft_putnbr); */ + waste += ft_lstsize(blob) % 4; + if (waste > size * size - 4 * g_ttmn) + { + ft_board_remove(board, '*'); + return (0); + } + } + ft_board_remove(board, '*'); + + /* ft_putendl("found blobs in map:"); */ + /* ft_show_board(board); */ + /* ft_lst_print2(lblob, &ft_putnbr); */ + return (ft_check_blobs(board, amap, lblob, lttmn, waste)); +} + +int ft_check_blobs(char **board, t_list **amap, t_list *lblob, t_list *lttmn, int waste) +{ + t_list *blob; + t_list *new_map; + int size; + + /* ft_putendl("at start of check_blobs"); */ + if (!lttmn) + return (ft_solved(board)); + if (((t_ttmn *)lttmn->content)->placed) + return (ft_check_blobs(board, amap, lblob, lttmn->next, waste)); + fflush(stdout); + if (!lblob) + { + /* printf("calling solver, no more blobs\n"); */ + /* fflush(stdout); */ + + return (ft_solver(board, amap, lttmn, waste)); + } + size = ft_strlen(*board); + blob = *(t_list **)lblob->content; + + /* ft_show_board(board); */ + /* ft_lst_print(*amap, &ft_putnbr); */ + /* ft_lst_print2(lblob, &ft_putnbr); */ + if (ft_lstsize(blob) / 4 == 1) + { + new_map = ft_lstmap(*amap, &ft_id); + if (ft_fit_blob(board, &new_map, lblob, lttmn, waste)) + { + lblob = lblob->next; + return (1); + } + else + { + waste += 4; + if (waste > size * size - 4 * g_ttmn) + { + /* ft_putendl("too much waste"); */ + return (0); + } + } + } + else + { + /* ft_lst_print(*amap, &ft_putnbr); */ + /* printf("blob too big, adding to map\n"); */ + /* fflush(stdout); */ + /* ft_lst_print(*amap, &ft_putnbr); */ + + ft_lst_sorted_merge(amap, blob, &ft_diff); + } + /* new_map = ft_lstmap(*amap, &ft_id); */ + return(ft_check_blobs(board, amap, lblob->next, lttmn, waste)); +} diff --git a/fillit/src/fillit_parser.c b/fillit/src/fillit_parser.c index 067b2d24..bc0cfebb 100644 --- a/fillit/src/fillit_parser.c +++ b/fillit/src/fillit_parser.c @@ -1,15 +1,15 @@ #include "fillit.h" -size_t g_target = 0; -size_t g_ttmn = 0; +int g_target = 0; +int g_ttmn = 0; -int ft_validate_ttmn(t_ttmn block) +int ft_validate_ttmn(t_ttmn ttmn) { size_t i; size_t j; int touch; - if (!(block.id >= 'A' && block.id <= 'Z')) + if (!(ttmn.id >= 'A' && ttmn.id <= 'Z')) return(0); i = -1; @@ -20,10 +20,10 @@ int ft_validate_ttmn(t_ttmn block) while (++j < 4) { if (i != j - && ((DIST(block.pos[i][0], block.pos[j][0]) == 0 - && DIST(block.pos[i][1], block.pos[j][1]) == 1) - || (DIST(block.pos[i][0], block.pos[j][0]) == 1 - && DIST(block.pos[i][1], block.pos[j][1]) == 0))) + && ((DIST(ttmn.pos[i][0], ttmn.pos[j][0]) == 0 + && DIST(ttmn.pos[i][1], ttmn.pos[j][1]) == 1) + || (DIST(ttmn.pos[i][0], ttmn.pos[j][0]) == 1 + && DIST(ttmn.pos[i][1], ttmn.pos[j][1]) == 0))) touch++; } } @@ -32,7 +32,7 @@ int ft_validate_ttmn(t_ttmn block) return (0); } -t_ttmn *ft_get_ttmn(char *filename) +t_list *ft_get_ttmn(char *filename) { int fd; char buf[BUF_SIZE + 1]; @@ -42,15 +42,16 @@ t_ttmn *ft_get_ttmn(char *filename) size_t k; size_t l; int ref[2]; - t_ttmn *ttmn; + t_ttmn ttmn; + t_list *list; + t_list *tmp; - ttmn = (t_ttmn *)ft_memalloc(sizeof(*ttmn) * 27); + list = NULL; fd = open(filename, O_RDONLY); if (fd == -1) return (0); k = 0; j = 0; - l = 0; while ((ret = read(fd, buf, BUF_SIZE))) { buf[ret] = '\0'; @@ -58,6 +59,7 @@ t_ttmn *ft_get_ttmn(char *filename) while (buf[i]) { /* printf("%i, %i, %i: '%c'\n", i, j, k, buf[i]); */ + /* fflush(stdout); */ if (buf[i] == '.') ; else if (buf[i] == '#') @@ -66,14 +68,14 @@ t_ttmn *ft_get_ttmn(char *filename) { ref[0] = j / 5; ref[1] = j % 5; - ttmn[l].pos[0][0] = 0; - ttmn[l].pos[0][1] = 0; - ttmn[l].id = 'A' + l; + ttmn.pos[0][0] = 0; + ttmn.pos[0][1] = 0; + ttmn.id = 'A' + ft_lstsize(list); } else if (k <= 3) { - ttmn[l].pos[k][0] = j / 5 - ref[0]; - ttmn[l].pos[k][1] = j % 5 - ref[1]; + ttmn.pos[k][0] = j / 5 - ref[0]; + ttmn.pos[k][1] = j % 5 - ref[1]; } else return (0); @@ -85,8 +87,19 @@ t_ttmn *ft_get_ttmn(char *filename) { if (j != 20) return (0); - if (!ft_validate_ttmn(ttmn[l])) + if (!ft_validate_ttmn(ttmn)) return (0); + tmp = ft_lstnew(&ttmn , sizeof(t_ttmn)); + /* printf("list: %p\n", list); */ + /* printf("new: %p\n", tmp); */ + /* printf("new->next: %p\n", tmp->next); */ + /* fflush(stdout); */ + ft_lsteadd(&list, tmp); + /* printf("list: %p\n", list); */ + /* printf("list->next: %p\n", list->next); */ + /* fflush(stdout); */ + /* ft_show_ttmn(*(t_ttmn*)list->content); */ + /* ft_show_ttmn(*(t_ttmn*)ft_lstlast(list)->content); */ l++; j = -1; k = 0; @@ -98,23 +111,21 @@ t_ttmn *ft_get_ttmn(char *filename) } } else - { return (0); - } i++; j++; } } if (j != 20) return (0); - if (!ft_validate_ttmn(ttmn[l])) + if (!ft_validate_ttmn(ttmn)) return (0); - l++; + ft_lsteadd(&list, ft_lstnew(&ttmn , sizeof(t_ttmn))); g_target = 2; - g_ttmn = l; - while ((l * 4) > (g_target) * (g_target)) + g_ttmn = ft_lstsize(list); + while ((g_ttmn * 4) > (g_target) * (g_target)) g_target++; - printf("n_ttmn=%zu, target=%zu\n", l, g_target); - ttmn[l].id = '\0'; - return (ttmn); + printf("n_ttmn=%zu, target=%zu\n", g_ttmn, g_target); + fflush(stdout); + return (list); } diff --git a/fillit/src/fillit_printer.c b/fillit/src/fillit_printer.c index 46a593d8..69c25be2 100644 --- a/fillit/src/fillit_printer.c +++ b/fillit/src/fillit_printer.c @@ -9,9 +9,10 @@ void ft_show_ttmn(t_ttmn ttmn) ft_putendl("end of ttmn\n"); return ; } - printf("%c",ttmn.id); + printf("%c,%i", ttmn.id, ttmn.placed); for (i=1; i < 4; i++) printf("\t%d,%d\n", ttmn.pos[i][0], ttmn.pos[i][1]); + fflush(stdout); ft_putendl(""); } diff --git a/fillit/src/fillit_solver.c b/fillit/src/fillit_solver.c index 689ef2c9..8bcca875 100644 --- a/fillit/src/fillit_solver.c +++ b/fillit/src/fillit_solver.c @@ -2,35 +2,64 @@ int ft_solved(char **board) { - printf("new solution : size %i\n", ft_strlen(*board)); - fflush(stdout); + /* printf("new solution : size %i\n", ft_strlen(*board)); */ + /* fflush(stdout); */ + /* ft_show_board(g_sol); */ g_sol = ft_copy_board(board); - ft_show_board(g_sol); return (1); } -int ft_solver(char **board, t_list *map, t_ttmn *ttmn) +int ft_solver(char **board, t_list **amap, t_list *lttmn, int waste) { - int j; int size; + int i; + t_ttmn *ttmn; + t_list *map; + t_list *valmap; - if (ttmn->id == '0') - return (ft_solver(board, ttmn + 1)); - if (!ttmn->id) + if (!lttmn) return (ft_solved(board)); - /* ft_show_board(board); */ + ttmn = (t_ttmn *)lttmn->content; + if (ttmn->placed) + return (ft_solver(board, amap, lttmn->next, waste)); size = ft_strlen(*board); + map = *amap; + + /* ft_putendl("before solver"); */ + /* ft_show_board(board); */ + /* ft_lst_print(map, &ft_putnbr); */ + /* ft_show_ttmn(*ttmn); */ while (map) { - /* ft_show_board(board); */ - if (ft_board_add(board, *ttmn, map->content)) + i = *(int *)map->content; + /* printf("looking at %i\n", i); */ + /* fflush(stdout); */ + if (ft_board_add(board, *ttmn, i)) + { + map = map->next; + /* printf("map=%p\n", map); */ + /* fflush(stdout); */ continue ; - ft_map_remove(map, i, *ttmn); - if (ft_validate_waste(board, map, ttmn + 1)) + } + /* printf("placed ttmn %c at %i\n", ttmn->id, i); */ + /* fflush(stdout); */ + + ft_map_delttmn(amap, i, ttmn->pos, size); + valmap = ft_lstmap(*amap, &ft_id); + if (ft_get_blobs(board, &valmap, lttmn->next)) return (1); - ft_map_add(map, i, *ttmn); - ft_board_remove_ttmn(&map, ttmn->id); - map = map->next; + + /* printf("after blob fail\n"); */ + /* fflush(stdout); */ + + ft_map_addttmn(amap, i, ttmn->pos, size); + ft_lst_remove_if(amap, i, &ft_diff); + map = *amap; + ft_board_remove(board, ttmn->id); + + /* ft_lst_print(*amap, &ft_putnbr); */ + /* ft_show_board(board); */ } + /* ft_putendl("failed solver"); */ return (0); } diff --git a/fillit/src/fillit_waste.c b/fillit/src/fillit_waste.c index d3e72273..629820d3 100644 --- a/fillit/src/fillit_waste.c +++ b/fillit/src/fillit_waste.c @@ -1,128 +1,35 @@ #include "fillit.h" -int ft_waste_here(char **board, int size, int i) +t_list *ft_waste_here(char **board, t_list **amap, int size, int i) { - int n; + t_list *blob; - n = 0; + blob = NULL; if (board[i / size][i % size] == '.') { board[i / size][i % size] = '*'; - n++; - n += ft_waste_around(board, size, i); + /* ft_lst_print(*amap, &ft_putnbr); */ + /* printf("removing %i from map\n", i); */ + /* ft_lst_print(*amap, &ft_putnbr); */ + ft_lst_remove_if(amap, i, &ft_diff); + blob = ft_waste_around(board, amap, size, i); + ft_lst_sorted_insert(&blob, ft_lstnew(&i, sizeof(int)), &ft_diff); } - return (n); -} - -int ft_waste_around(char **board, int size, int i) -{ - int n; - - n = 0; - n += i / size > 0 ? ft_waste_here(board, size, i - size) : 0; - n += i % size > 0 ? ft_waste_here(board, size, i - 1) : 0; - n += i / size < size - 1 ? ft_waste_here(board, size, i + size) : 0; - n += i % size < size - 1 ? ft_waste_here(board, size, i + 1) : 0; - return (n); -} - -int ft_fit_any(char **board, t_ttmn *ttmn, int i, int blob) -{ - int y; - int l; - int size; - char tmp; - int n; - - /* printf("going to fit any at %i,%i\n", i, j); */ + /* printf("list at %i: ", i); */ /* fflush(stdout); */ - /* ft_show_board(board); */ - y = i; - n = blob; - size = ft_strlen(*board); - while (y < size * size) - { - if (board[y / size][y % size] == '*') - { - n--; - l = -1; - /* printf("0 trying all at %i\n", y); */ - /* fflush(stdout); */ - while (ttmn[++l].id) - { - /* printf("1 trying %c at %i\n", ttmn[l].id, y); */ - /* fflush(stdout); */ - if (ttmn[l].id == '0') - continue ; - if (ft_board_add(board, ttmn[l], y)) - continue ; - /* printf("passed board add\n"); */ - /* fflush(stdout); */ - /* ft_show_board(board); */ - ft_board_remove(board, '*'); - ft_board_remove(board, '^'); - if (!ttmn[1].id) - return(ft_solved(board)); - tmp = ttmn[l].id; - ttmn[l].id = '0'; - if (ft_solver(board, ttmn)) - return (1); - ttmn[l].id = tmp; - ft_board_remove(board, ttmn[l].id); - ft_waste_here(board, size, y); - /* ft_show_board(board); */ - } - /* printf("failed at %i\n", y); */ - /* fflush(stdout); */ - } - y++; - } - return (0); + /* ft_lst_print(blob, &ft_putnbr); */ + return (blob); } -int ft_validate_waste(char **board, t_list *map, t_ttmn *ttmn) +t_list *ft_waste_around(char **board, t_list **amap, int size, int i) { - t_list *blob; - int waste; - int size; + t_list *add; - if (ttmn->id == '0') - return (ft_solver(board, ttmn + 1)); - if (!ttmn->id) - return (ft_solved(board)); - blob = NULL; - waste = 0; - size = ft_strlen(*board); - /* ft_show_board(board); */ - while (map) - { - ft_board_remove(board, '*'); - if (board[map->content / size][map->content % size] != '.') - { - map = map->next; - continue ; - } - ft_lstadd(&blob, ft_waste_here(board, size, map->content)); - waste += ft_lstsize(blob) % 4;; - ft_map_remove_blob(&map, blob); - if (waste > size * size - 4 * g_ttmn) - return (0); - map = map->next; - } - while (blob) - { - if (ft_lstsize(blob->content) / 4 == 1) - { - if (ft_fit_any(board, blob->content, ttmn, y, blob)) - return (1); - else - { - waste += (ft_lstsize(blob->content) / 4 == 1) ? 4 : 0; - if (waste > size * size - 4 * g_ttmn) - return (0); - } - } - blob = blob->next; - } - return (ft_solver(board, ttmn)); + add = NULL; + i % size < size - 1 ? ft_lst_sorted_merge(&add, ft_waste_here(board, amap, size, i + 1), &ft_diff) : 0; + i / size > 0 ? ft_lst_sorted_merge(&add, ft_waste_here(board, amap, size, i - size), &ft_diff) : 0; + i % size > 0 ? ft_lst_sorted_merge(&add, ft_waste_here(board, amap, size, i - 1), &ft_diff) : 0; + i / size < size - 1 ? ft_lst_sorted_merge(&add, ft_waste_here(board, amap, size, i + size), &ft_diff) : 0; + /* ft_lst_print(add, &ft_putnbr); */ + return (add); } diff --git a/fillit/src/main.c b/fillit/src/main.c index 75116c60..5496e1d8 100644 --- a/fillit/src/main.c +++ b/fillit/src/main.c @@ -9,20 +9,25 @@ void ft_usage(void) int main(int ac, char **av) { - t_ttmn *ttmn; + t_list *lttmn; + t_list *map; char **board; int size; - if (ac != 2 || !(ttmn = ft_get_ttmn(av[1]))) + if (ac != 2 || !(lttmn = ft_get_ttmn(av[1]))) { ft_usage(); return (1); } size = g_target + 2; - while (size >= (int)g_target) + /* ft_show_ttmn(*(t_ttmn *)lttmn->content); */ + /* ft_show_ttmn(*(t_ttmn *)ft_lstlast(lttmn)->content); */ + while (size >= g_target) { + map = ft_lstnew_range(0, size * size); board = ft_empty_board(size); - ft_solver(board, ttmn); + ft_lstiter(lttmn, &ft_ttmn_reset); + ft_solver(board, &map, lttmn, 0); ft_free_board(&board); size--; } diff --git a/fillit/src/ttmn_lib.c b/fillit/src/ttmn_lib.c new file mode 100644 index 00000000..425d12fd --- /dev/null +++ b/fillit/src/ttmn_lib.c @@ -0,0 +1,42 @@ +#include "fillit.h" + +int cmp_ttmn(t_ttmn a, t_ttmn b) +{ + return (ft_strcmp(a.id, b.id)); +} + +void ft_ttmn_reset(t_list *ttmn) +{ + ((t_ttmn *)ttmn->content)->placed = 0; +} + +void ft_map_delttmn(t_list **amap, int anchor, int pos[4][2], int size) +{ + int i; + + i = -1; + fflush(stdout); + while (++i < 4) + { + /* printf("deleting: %i\n", anchor + size * pos[i][0] + pos[i][1]); */ + /* fflush(stdout); */ + ft_lst_remove_if(amap, anchor + size * pos[i][0] + pos[i][1], &ft_diff); + } +} + +void ft_map_addttmn(t_list **amap, int anchor, int pos[4][2], int size) +{ + int i; + int j; + t_list *link; + + i = -1; + while (++i < 4) + { + j = (anchor + size * pos[i][0] + pos[i][1]); + /* printf("adding %i to map\n", j); */ + /* fflush(stdout); */ + link = ft_lstnew(&j, sizeof(int)); + ft_lst_sorted_insert(amap, link, &ft_diff); + } +}