Add solution to first part of day 5
authorLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Tue, 5 Dec 2023 10:44:17 +0000 (11:44 +0100)
committerLukáš Jiřiště <gymnazium.jiriste@gmail.com>
Wed, 6 Dec 2023 10:17:28 +0000 (11:17 +0100)
5/5.c [new file with mode: 0644]

diff --git a/5/5.c b/5/5.c
new file mode 100644 (file)
index 0000000..ba9d5f5
--- /dev/null
+++ b/5/5.c
@@ -0,0 +1,242 @@
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "libft.h"
+
+#define MAP_TYPES 7
+
+typedef unsigned int t_myint;
+
+struct s_seeds
+{
+       size_t  size;
+       t_myint *seeds;
+};
+typedef struct s_seeds t_seeds;
+
+struct s_transform
+{
+       t_myint dest_start;
+       t_myint src_start;
+       t_myint range;
+};
+typedef struct s_transform     t_transform;
+
+struct s_map
+{
+       t_transform     *trans;
+       size_t          size;
+       size_t          capacity;
+};
+typedef struct s_map   t_map;
+
+struct s_almanac
+{
+       t_map   maps[MAP_TYPES];
+};
+typedef struct s_almanac       t_almanac;
+
+size_t count_char(const char *str, char c)
+{
+       size_t  counter;
+
+       counter = 0;
+       while (*str)
+       {
+               if (*str == c)
+                       ++counter;
+               ++str;
+       }
+       return (counter);
+}
+
+void   parse_seeds(const char *line, t_seeds *seeds)
+{
+       size_t  i;
+
+       seeds->size = count_char(line, ' ');
+       seeds->seeds = ft_calloc(seeds->size, sizeof(*(seeds->seeds)));
+       while (*line != ':')
+               ++line;
+       ++line;
+       i = 0;
+       while (i < seeds->size)
+       {
+               seeds->seeds[i] = ft_atoi(++line);
+               while (ft_isdigit(*line))
+                       ++line;
+               ++i;
+       }
+       return ;
+}
+
+t_transform    parse_transform(const char *str)
+{
+       t_transform     trans;
+
+       trans.dest_start = ft_atoi(str);
+       while (ft_isdigit(*str))
+               ++str;
+       trans.src_start = ft_atoi(++str);
+       while (ft_isdigit(*str))
+               ++str;
+       trans.range = ft_atoi(++str);
+       return (trans);
+}
+
+int    enlarge_map(t_map *map)
+{
+       t_transform     *tmp;
+
+       tmp = map->trans;
+       map->trans = ft_calloc(map->capacity * 2, sizeof(*map->trans));
+       if (!map->trans)
+       {
+               map->trans = tmp;
+               return (1);
+       }
+       map->capacity *= 2;
+       ft_memcpy(map->trans, tmp, map->size * sizeof(*map->trans));
+       free(tmp);
+       return (0);
+}
+
+void   add_transform(t_map *map, t_transform trans)
+{
+       if (map->size == map->capacity)
+               enlarge_map(map);
+       map->trans[map->size] = trans;
+       ++(map->size);
+       return ;
+}
+
+void   init_almanac(t_almanac *almanac)
+{
+       size_t  i;
+
+       i = 0;
+       while (i < MAP_TYPES)
+       {
+               almanac->maps[i].size = 0;
+               almanac->maps[i].capacity = 4;
+               almanac->maps[i].trans = ft_calloc(almanac->maps[i].capacity, sizeof(*almanac->maps[i].trans));
+               ++i;
+       }
+       return ;
+}
+
+int    parse(const char *file_name, t_almanac *almanac, t_seeds *seeds)
+{
+       int             fd;
+       char    *line;
+       size_t  i;
+
+       fd = open(file_name, O_RDONLY);
+       if (fd < 0)
+               return (2);
+       line = get_next_line(fd);
+       parse_seeds(line, seeds);
+       free(get_next_line(fd));
+       i = 0;
+       while (i < MAP_TYPES)
+       {
+               free(line);
+               free(get_next_line(fd));
+               line = get_next_line(fd);
+               while (line)
+               {
+                       if (*line == '\n')
+                               break;
+                       add_transform(&almanac->maps[i], parse_transform(line));
+                       free(line);
+                       line = get_next_line(fd);
+               }
+               ++i;
+       }
+       close(fd);
+       return (0);
+}
+
+t_myint        apply_map(t_myint input, const t_map map)
+{
+       size_t  i;
+       t_myint offset;
+
+       i = 0;
+       while (i < map.size)
+       {
+               if (map.trans[i].src_start <= input && input <= map.trans[i].src_start + map.trans[i].range - 1)
+               {
+                       offset = input - map.trans[i].src_start;
+                       ft_printf("Using transform on line %u, which looks like: %u %u %u\nIt transforms %u to %u.\n", i, map.trans[i].dest_start, map.trans[i].src_start, map.trans[i].range, input, map.trans[i].dest_start + offset);
+                       return (map.trans[i].dest_start + offset);
+               }
+               ++i;
+       }
+       ft_printf("No transform found, passing %u.\n", input);
+       return (input);
+}
+
+t_myint        find_location(t_myint seed, const t_almanac almanac)
+{
+       t_myint tmp;
+       size_t  i;
+
+       i = 0;
+       ft_printf("Finding location for seed %u.\n\n", seed);
+       while (i < MAP_TYPES)
+       {
+               seed = apply_map(seed, almanac.maps[i]);
+               ++i;
+       }
+       ft_printf("\nResulting location is %u.\n\n", seed);
+       return (seed);
+}
+
+void   free_almanac(t_almanac *almanac)
+{
+       size_t  i;
+
+       i = 0;
+       while (i < MAP_TYPES)
+       {
+               free(almanac->maps[i].trans);
+               ++i;
+       }
+       return ;
+}
+
+void   free_seeds(t_seeds *seeds)
+{
+       free(seeds->seeds);
+       return ;
+}
+
+int    main(int argc, char **argv)
+{
+       t_seeds         seeds;
+       t_almanac       almanac;
+       t_myint         min;
+       size_t          i;
+       t_myint         tmp;
+
+       if (argc != 2)
+               return (1);
+       init_almanac(&almanac);
+       if (parse(argv[1], &almanac, &seeds))
+               return (2);
+       min = -1;
+       i = 0;
+       while (i < seeds.size)
+       {
+               tmp = find_location(seeds.seeds[i], almanac); 
+               if (tmp < min)
+                       min = tmp;
+               ++i;
+       }
+       free_almanac(&almanac);
+       free_seeds(&seeds);
+       ft_printf("The closest location is %u.\n", min);
+       return (0);
+}