Add solution to second part of day 3
authorLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Mon, 4 Dec 2023 17:50:49 +0000 (18:50 +0100)
committerLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Wed, 6 Dec 2023 10:17:28 +0000 (11:17 +0100)
3/3b.c [new file with mode: 0644]

diff --git a/3/3b.c b/3/3b.c
new file mode 100644 (file)
index 0000000..8a675ea
--- /dev/null
+++ b/3/3b.c
@@ -0,0 +1,190 @@
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "libft.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);
+}
+
+size_t get_number_length(const char *number)
+{
+       size_t  result;
+
+       result = 0;
+       while (ft_isdigit(number[result]))
+               ++result;
+       return (result);
+}
+
+int    serial_to_int(t_matrix schematics, size_t i, size_t j)
+{
+       char    *serial;
+       int             result;
+       size_t  length;
+       char    *el;
+
+       while (1)
+       {
+               el = get_element(schematics, i, j);
+               if (!el)
+                       break;
+               if (!ft_isdigit(*el))
+                       break;
+               --j;
+       }
+       ++j;
+       el = get_element(schematics, i, j);
+       length = get_number_length(el);
+       serial = ft_strndup(el, length);
+       result = ft_atoi(serial);
+       free(serial);
+       return (result);
+}
+
+int    gear_ratio(t_matrix schematics, size_t i, size_t j)
+{
+       const size_t    i_0 = i;
+       const size_t    j_0 = j;
+       int                             part[2];
+       size_t                  k;
+       int                             adjacent_digit;
+
+       k = 0;
+       if (i > 0)
+               --i;
+       while (i <= i_0 + 1)
+       {
+               adjacent_digit = 0;
+               j = j_0;
+               if (j > 0)
+                       j = j_0 - 1;
+               while (j <= j_0 + 1)
+               {
+                       if (get_element(schematics, i, j))
+                       {
+                               if (ft_isdigit(*get_element(schematics, i, j)) && !adjacent_digit)
+                               {
+                                       if (k < 2)
+                                               part[k] = serial_to_int(schematics, i, j);
+                                       ++k;
+                                       adjacent_digit = 1;
+                               }
+                               else if (!ft_isdigit(*get_element(schematics, i, j)))
+                                       adjacent_digit = 0;
+                       }
+                       ++j;
+               }
+               ++i;
+       }
+       if (k == 2)
+       {
+               ft_printf("Found pair by cogs: %i * %i = %i.\n", part[0], part[1], part[0] * part[1]);
+               return (part[0] * part[1]);
+       }
+       return (0);
+}
+
+int    process(t_matrix schematics)
+{
+       int             result;
+       size_t  i;
+       size_t  j;
+
+       result = 0;
+       i = 0;
+       while (i < schematics.rows)
+       {
+               j = 0;
+               while (j < schematics.cols)
+               {
+                       if (*get_element(schematics, i, j) == '*')
+                               result += gear_ratio(schematics, i, j);
+                       ++j;
+               }
+               ++i;
+       }
+       return (result);
+}
+
+int    main(int argc, char **argv)
+{
+       t_matrix        schematics;
+
+       if (argc != 2)
+               return (1);
+       schematics = read_as_matrix(argv[1]);
+       ft_printf("The resulting sum is %i.\n", process(schematics));
+       return (0);
+}
+