#include #include #include #include #include #include #include #define SEEDS 20 typedef struct { unsigned long int len; unsigned long int *dest; unsigned long int *source; unsigned long int *range; } map; typedef struct { unsigned long int seed; unsigned long int range; unsigned long int *min; map **ruleList; } mt_args; unsigned long int remap(unsigned long int seed, map **remaps); map *storeRules(FILE *input, char *row, int n); void gotoMap(FILE *input, int n); void *threadedRange(mt_args *args); // del b: Lagra inte seeds. för varje seed, kör igenom alla maps. efter alla maps, // spara siffran om den är lägre än tidigare. // optimization ideas: // Store rules as *array[7] of remapArrays[rules * 3 ints] // ...and int len[7] that holds the length of each remap // spawn thread per range // ^ this is to avoid changing the logic to handle ranges lol // lagra 7 map-pekare // struct map: int len, dest[], source[], range[] // len antal rules // skapa gotoMap-funktion (rullar streamen till map n) // skapa funktion för att mappa och returnera _en map_ // ^ kalla dessa 7 gånger int main() { unsigned long int minimum = UINT_MAX; unsigned long int seedRanges[SEEDS] = {0}; char row[250]; char c; FILE *input; input = fopen("./input", "r"); int seed = 0; while (c = fgetc(input) != '\n') { while (isdigit(c = fgetc(input))) { seedRanges[seed] = seedRanges[seed] * 10 + (c - '0'); } fseek(input, -1L, SEEK_CUR); // currently stepping two steps forward so yeah if (seedRanges[seed] != 0) seed++; } map *ruleList[7]; // Get pointers to 7 populated ruleList for (int i = 0; i < 7; i++) ruleList[i] = storeRules(input, row, i); fclose(input); /* Debug, print rules for (int i = 0; i < 7; i++) { for (int j = 0; j < ruleList[i]->len; j++) { printf("%u %u %u\n", ruleList[i]->dest[j], ruleList[i]->source[j], ruleList[i]->range[j]); } } */ pthread_t *thread_id = malloc (sizeof(pthread_t) * 10); unsigned long int smallest[10] = {0}; // for each seed-range pair, run remap for each seed for (int i = 0; i < 19; i += 2) { printf("%d\n", i); // unsigned long int new; mt_args *args = malloc(sizeof(mt_args)); args->seed = seedRanges[i]; args->range = seedRanges[i + 1]; args->min = &smallest[i / 2]; args->ruleList = ruleList; pthread_create(&thread_id[i / 2], NULL, &threadedRange, args); /* for (int j = 0; j < seedRanges[i + 1]; j++) { new = remap(seedRanges[i] + j, ruleList); if (new < minimum) minimum = new; } */ // printf("Range %u-%u done\n", seedRanges[i], seedRanges[i] + seedRanges[i + 1]); // printf("min: %u\n", minimum); // printf("new: %u\n", new); } for (int i = 0; i < 10; i++) { printf("joining %d: \n", i); pthread_join(thread_id[i], NULL); printf("%u\n", smallest[i]); } for (int i = 0; i < 10; i++) { if (smallest[i] < minimum) minimum = smallest[i]; } printf("smallest: %u\n", minimum); } void *threadedRange(mt_args *args) { unsigned long int minimum = UINT_MAX; unsigned long int new = 0; // printf("seedstart: %u range: %u\n", args->seed, args->range); for (unsigned long int i = 0; i < args->range; i++) { new = remap(args->seed + i, args->ruleList); // if (new == 0) printf("wtf %u\n", args->seed + i); if (new < minimum) minimum = new; } args->min[0] = minimum; } // Change this function to take one seed, run through all remaps for it, then return value unsigned long int remap(unsigned long int seed, map **remaps) { unsigned long int oldSeed = seed; for (int i = 0; i < 7; i++) { // printf("Dest: %u, Source: %u, range: %u\n", dest, source, range + 1); for (int j = 0; j < remaps[i]->len; j++) { if (seed >= remaps[i]->source[j] && seed <= remaps[i]->source[j] + remaps[i]->range[j]) { //printf("Map %d: %u is in range, moving to %u\n", i + 1, seed, remaps[i]->dest[j] + seed - remaps[i]->source[j]); seed = remaps[i]->dest[j] + seed - remaps[i]->source[j]; // if (seed == 0) printf("Seed %u became 0 on map %d\n", oldSeed, i); break; // printf("Seed %d: %u\n", i + 1, seedArray[i]); // printf("seed found! next map %u\n", seed); } } } return seed; } map *storeRules(FILE *input, char *row, int n) { unsigned long int len = 0; gotoMap(input, n); while (fgets(row, 250, input) != NULL) { if (strstr(row, "seeds:") || row[0] == '\n') break; len++; } gotoMap(input, n); map *ruleList = malloc(sizeof(unsigned long int) + 3 * sizeof(unsigned long int*)); ruleList->dest = calloc(len, sizeof(unsigned long int)); ruleList->source = calloc(len, sizeof(unsigned long int)); ruleList->range = calloc(len, sizeof(unsigned long int)); int i = 0; while (fgets(row, 250, input) != NULL) { if (strstr(row, "seeds:") || row[0] == '\n') break; int j = 0; while (!isdigit(row[j])) j++; for (; isdigit(row[j]); j++) { ruleList->dest[i] = ruleList->dest[i] * 10 + row[j] - '0'; } while (!isdigit(row[j])) j++; for (; isdigit(row[j]); j++) { ruleList->source[i] = ruleList->source[i] * 10 + row[j] - '0'; } while (!isdigit(row[j])) j++; for (; isdigit(row[j]); j++) { ruleList->range[i] = ruleList->range[i] * 10 + row[j] - '0'; } i++; } ruleList->len = len; return ruleList; } void gotoMap(FILE *input, int n) { char row[250]; rewind(input); while (fgets(row, 250, input) != NULL) { if (strstr(row, "map")) n--; if (n < 0) break; } }