From 5afa103769518b795d4b391f5e14d5be048a142f Mon Sep 17 00:00:00 2001 From: "Alexander \"Arav\" Andreev" Date: Wed, 6 Dec 2023 03:15:44 +0400 Subject: [PATCH] Day 5 part 2 complete! Heh, it takes around 91.217s +- 6s to run. :) So a test for day5 with my data is commented out. :) --- Makefile | 2 +- day5/p2.c | 127 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ test | 5 ++- 3 files changed, 132 insertions(+), 2 deletions(-) create mode 100644 day5/p2.c diff --git a/Makefile b/Makefile index 6e32d46..2da10eb 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ day4: day4/p1.c day4/p2.c day5: day5/p1.c day5/p2.c ${CC} ${CFLAGS} $@/p1.c -o bin/$@p1 -# ${CC} ${CFLAGS} $@/p2.c -o bin/$@p2 + ${CC} ${CFLAGS} -fopenmp $@/p2.c -o bin/$@p2 clean: rm -f bin/day*p* \ No newline at end of file diff --git a/day5/p2.c b/day5/p2.c new file mode 100644 index 0000000..c14fa2a --- /dev/null +++ b/day5/p2.c @@ -0,0 +1,127 @@ +#define _GNU_SOURCE +#include +#include +#include +#include +#include + + +#define ABS(n) ((n < 0) ? n * -1 : n) + + +uint64_t parse_number(char *end); + +#define MAPS_LEN 7 + +typedef struct { + uint64_t dst, src, rng; +} map_t; + + +int main(int argc, char **argv) { + FILE *input; + char *line = NULL; + size_t line_buf_length = 0; + + if (argc == 1 || argv[1][0] == '-') + input = stdin; + else if ((input = fopen(argv[1], "r")) == NULL) { + printf("Cannot open file %s\n", argv[1]); + return -1; + } + + uint64_t *seed_ranges = NULL; + + getline(&line, &line_buf_length, input); + + char *colon_pos = strchr(line, ':'); + + size_t seed_ranges_len = 0; + for (char *space_pos = colon_pos+1; space_pos != NULL; space_pos = strchr(space_pos, ' ')) { + seed_ranges_len++; + space_pos++; + } + + seed_ranges = (uint64_t *) calloc(seed_ranges_len, sizeof(uint64_t)); + + for (size_t i = 0, seeds_pos = (size_t) colon_pos+2;; seeds_pos++) { + while (*(char *)(seeds_pos)>>4 == 0x3) seeds_pos++; + seed_ranges[i++] = parse_number((char *)(seeds_pos-1)); + if (*(char *)seeds_pos == '\n') + break; + } + + map_t **maps = (map_t **) calloc(MAPS_LEN, sizeof(map_t *)); + for (size_t i = 0; i < MAPS_LEN; ++i) + maps[i] = (map_t *) calloc(1, sizeof(map_t)); + size_t map_lengths[MAPS_LEN] = {1}; + + int8_t maps_cur = -1; + while (getline(&line, &line_buf_length, input) != -1) { + if (maps_cur == MAPS_LEN) + break; + if (line[0] == '\n') { + maps_cur++; + continue; + } else if (line[0]>>4 != 0x3) { + continue; + } + + map_lengths[maps_cur]++; + maps[maps_cur] = (map_t *) realloc(maps[maps_cur], map_lengths[maps_cur] * sizeof(map_t)); + + map_t new_range_map = {0}; + sscanf(line, "%lu %lu %lu\n", &new_range_map.dst, &new_range_map.src, &new_range_map.rng); + + maps[maps_cur][map_lengths[maps_cur]-1] = new_range_map; + + memset(line, 0, line_buf_length); + } + + maps_cur = 0; + + uint64_t lowest_loc_n = UINT64_MAX; + + for (size_t i = 0; i < seed_ranges_len; i += 2) { + #pragma omp shared(lowest_loc_n) + #pragma omp parallel for + for (uint64_t r = seed_ranges[i]; r < seed_ranges[i] + seed_ranges[i+1]; ++r) { + uint64_t seed = r; + + for (size_t j = 0; j < MAPS_LEN; ++j) { + for (size_t n = 0; n < map_lengths[j]; ++n) { + if (seed >= maps[j][n].src && seed <= maps[j][n].src + maps[j][n].rng) { + seed = maps[j][n].dst + (seed - maps[j][n].src); + break; + } + } + } + + if (seed < lowest_loc_n) + lowest_loc_n = seed; + } + } + + + free(seed_ranges); + + for (size_t i = 0; i < MAPS_LEN; ++i) + free(maps[i]); + + printf("%lu\n", lowest_loc_n); + + return 0; +} + +uint64_t parse_number(char *end) { + uint64_t num = 0; + + for (size_t n = 1;; n *= 10) { + if (*end>>4 != 0x3) + break; + num += (*end&0xf) * n; + --end; + } + + return num; +} \ No newline at end of file diff --git a/test b/test index 2c68456..0e9d7c2 100755 --- a/test +++ b/test @@ -16,4 +16,7 @@ echo "Day 3 with test data part 1 $(test_case 3 1 "test" "4361"), and part 2 $(t echo "Day 3 with my data part 1 $(test_case 3 1 "my" "550934"), and part 2 $(test_case 3 2 "my" "81997870")."; echo "Day 4 with test data part 1 $(test_case 4 1 "test" "13"), and part 2 $(test_case 4 2 "test" "30")."; -echo "Day 4 with my data part 1 $(test_case 4 1 "my" "21959"), and part 2 $(test_case 4 2 "my" "5132675")."; \ No newline at end of file +echo "Day 4 with my data part 1 $(test_case 4 1 "my" "21959"), and part 2 $(test_case 4 2 "my" "5132675")."; + +echo "Day 5 with test data part 1 $(test_case 5 1 "test" "35"), and part 2 $(test_case 5 2 "test" "46")."; +# echo "Day 5 with my data part 1 $(test_case 5 1 "my" "379811651"), and part 2 $(test_case 5 2 "my" "27992443")."; \ No newline at end of file