From 615d2af9d1f31f10d9eaf448e6358c070129394d Mon Sep 17 00:00:00 2001 From: =?utf8?q?Luk=C3=A1=C5=A1=20Ji=C5=99i=C5=A1t=C4=9B?= Date: Tue, 5 Dec 2023 11:44:17 +0100 Subject: [PATCH] Add solution to first part of day 5 --- 5/5.c | 242 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 242 insertions(+) create mode 100644 5/5.c diff --git a/5/5.c b/5/5.c new file mode 100644 index 0000000..ba9d5f5 --- /dev/null +++ b/5/5.c @@ -0,0 +1,242 @@ + +#include +#include +#include +#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); +} -- 2.30.2