+
+#include "libft.h"
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+struct s_matrix
+{
+ size_t rows;
+ size_t cols;
+ char *array;
+};
+typedef struct s_matrix t_matrix;
+
+char *get_element(t_matrix matrix, size_t i, size_t j)
+{
+ if (i >= matrix.rows || j >= matrix.cols)
+ return (NULL);
+ return (matrix.array + i * matrix.cols + j);
+}
+
+int fill_matrix_size(t_matrix *matrix, const char *file_name)
+{
+ int fd;
+ char c;
+ char *line;
+
+ matrix->rows = 1;
+ matrix->cols = 0;
+ fd = open(file_name, O_RDONLY);
+ if (fd < 0)
+ return (-1);
+ c = 'a';
+ while (c != '\n' && c != '\0')
+ {
+ read(fd, &c, 1);
+ ++matrix->cols;
+ }
+ --matrix->cols;
+ line = malloc(matrix->cols + 1);
+ while (read(fd, line, matrix->cols + 1))
+ ++matrix->rows;
+ close(fd);
+ free(line);
+ return (0);
+}
+
+t_matrix read_as_matrix(const char *file_name)
+{
+ int fd;
+ t_matrix matrix;
+ size_t i;
+ size_t j;
+ char *line;
+
+ fill_matrix_size(&matrix, file_name);
+ fd = open(file_name, O_RDONLY);
+ if (fd < 0)
+ return (matrix);
+ matrix.array = malloc(matrix.rows * matrix.cols * sizeof(*matrix.array));
+ if (!matrix.array)
+ return (matrix);
+ line = malloc(matrix.cols + 1);
+ i = 0;
+ while (i < matrix.rows)
+ {
+ read(fd, line, matrix.cols + 1);
+ j = 0;
+ while (j < matrix.cols)
+ {
+ *get_element(matrix, i, j) = line[j];
+ ++j;
+ }
+ ++i;
+ }
+ free(line);
+ return (matrix);
+}
+
+int to_single_on(int bits)
+{
+ size_t i;
+
+ i = 0;
+ while (bits != 0)
+ bits &= (1 << i++);
+ return (1 << (i - 1));
+}
+
+/* Connected_sides legend
+ * -2
+ * |
+ * |
+ * -1----- -----1
+ * |
+ * |
+ * 2
+ */
+void next_step(t_matrix sketch, size_t *i, size_t *j)
+{
+ static int previous = 0;
+ int connected_sides;
+ char *tile;
+ const char orig = *get_element(sketch, *i, *j);
+
+ connected_sides = 0;
+ tile = get_element(sketch, *i - 1, *j);
+ if (tile && ft_strchr("|F7S#", *tile) && ft_strchr("S|LJ", orig))
+ connected_sides += -2;
+ tile = get_element(sketch, *i + 1, *j);
+ if (tile && ft_strchr("|LJS#", *tile) && ft_strchr("S|F7", orig))
+ connected_sides += 2;
+ tile = get_element(sketch, *i, *j - 1);
+ if (tile && ft_strchr("-FLS#", *tile) && ft_strchr("S-7J", orig))
+ connected_sides += -1;
+ tile = get_element(sketch, *i, *j + 1);
+ if (tile && ft_strchr("-7JS#", *tile) && ft_strchr("S-FL", orig))
+ connected_sides += 1;
+ connected_sides += previous;
+ if (previous == 0)
+ connected_sides = to_single_on(connected_sides);
+ *i += connected_sides / 2;
+ *j += connected_sides % 2;
+ previous = connected_sides;
+ return ;
+}
+
+void color_loop(t_matrix sketch)
+{
+ size_t i;
+ size_t j;
+ size_t i_p;
+ size_t j_p;
+
+ i = 0;
+ j = 0;
+ while (*(get_element(sketch, i, j)) != 'S')
+ {
+ ++j;
+ i += j / sketch.cols;
+ j %= sketch.cols;
+ }
+ while (*(get_element(sketch, i, j)) != '#')
+ {
+ i_p = i;
+ j_p = j;
+ next_step(sketch, &i, &j);
+ *get_element(sketch, i_p, j_p) = '#';
+ }
+ return ;
+}
+
+int main(int argc, char **argv)
+{
+ t_matrix sketch;
+
+ if (argc != 2)
+ return (1);
+ sketch = read_as_matrix(argv[1]);
+ color_loop(sketch);
+ ft_printf("The loop encloses %i tiles.\n", enclosed_area(sketch));
+ free(sketch.array);
+ return (0);
+}