--- /dev/null
+
+#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);
+}