diff --git a/day1/day1a.c b/day1/day1a.c index bd098d6..c1893af 100644 --- a/day1/day1a.c +++ b/day1/day1a.c @@ -20,7 +20,6 @@ int main() } else if (inChar >= '0' && inChar <= '9' && numIndex == 1) { numbers[1] = inChar; } else if (inChar == EOF || inChar == '\n' || inChar == '\0') { - //fputs(numbers, output); sum += (numbers[0] - '0') * 10 + (numbers[1] - '0'); numIndex = 0; numbers[0] = '0'; @@ -30,5 +29,4 @@ int main() fclose(input); printf("%d\n", sum); - } diff --git a/day5/day5b.c b/day5/day5b.c new file mode 100644 index 0000000..e107582 --- /dev/null +++ b/day5/day5b.c @@ -0,0 +1,105 @@ +#include +#include +#include +#include +#include +#include + +#define SEEDS 20 + +unsigned int remap(FILE *input, char *row, unsigned int seed); + +// för varje seed: +// är den i rangen seed to soil? if so, = soil + i +// testa varje range så och reassigna on hit, sen spara i location array +// Lägsta i array är svaret + +// vi har: +// lista med seed +// 7 maps + +// lagra seeds i array +// array som säger om seed är omvandlat i current map +// för varje rad i map, kolla varje seed (om det ej omvandlat) +// vid nästa map, nolla omvandlatArray + +// 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. + + +int main() +{ + unsigned int minimum = UINT_MAX; + unsigned 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++; + } + // for (int i = 0; i < seed; i++) + // printf("Seed %d: %u\n", i + 1, seedArray[i]); + + // for each seed-range pair, run remap for each seed + for (int i = 16; i < 18; i += 2) { + printf("%d\n", i); + unsigned int new; + for ( int j = 0; j < seedRanges[i + 1]; j++) { + rewind(input); + new = remap(input, row, seedRanges[i] + j); + if (new < minimum) minimum = new; + } + printf("Range %u-%u done\n", seedRanges[i], seedRanges[i] + seedRanges[i + 1]); + printf("%u\n", minimum); + } + + printf("%u\n", minimum); +} + +// Change this function to take one seed, run through all remaps for it, then return value +unsigned int remap(FILE *input, char *row, unsigned int seed) +{ + while (fgets(row, 250, input) != NULL) { + if (strstr(row, "map") || strstr(row, "seeds:") || row[0] == '\n') continue; + fgets(row, 250, input); + unsigned int i = 0; + while (!isdigit(row[i])) i++; + + unsigned int dest = 0; + for (; isdigit(row[i]); i++) { + dest = dest * 10 + row[i] - '0'; + } + while (!isdigit(row[i])) i++; + unsigned int source = 0; + for (; isdigit(row[i]); i++) { + source = source * 10 + row[i] - '0'; + } + while (!isdigit(row[i])) i++; + unsigned int range = 0; + for (; isdigit(row[i]); i++) { + range = range * 10 + row[i] - '0'; + } + range -= 1; + + // printf("Dest: %u, Source: %u, range: %u\n", dest, source, range + 1); + // TODO: Edgecase här - om range 0 kan den false positives + if (seed >= source && seed <= source + range) { + // printf("Seed %d: %u is in range, moving to %u\n", i + 1, seedArray[i], dest + seedArray[i] - source); + seed = dest + seed - source; + // printf("Seed %d: %u\n", i + 1, seedArray[i]); + // printf("seed found! next map %u\n", seed); + while (fgets(row, 250, input) && !strstr(row, "map")); + continue; + } + } + rewind(input); + return seed; +} diff --git a/day5/optDay5b.c b/day5/optDay5b.c new file mode 100644 index 0000000..49dec25 --- /dev/null +++ b/day5/optDay5b.c @@ -0,0 +1,198 @@ +#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; + } +} diff --git a/day5/output b/day5/output deleted file mode 100644 index 803245a..0000000 --- a/day5/output +++ /dev/null @@ -1,20 +0,0 @@ -1663131502 -3701339508 -1591272448 -971042070 -3779692809 -1373066113 -3664261935 -2396801877 -2017638440 -3700090039 -642320287 -2197425575 -3037672564 -1931439146 -1241009111 -903350816 -3402116899 -3705255266 -535088217 -896607734 diff --git a/day5/output.2 b/day5/output.2 deleted file mode 100644 index 0a14ec6..0000000 --- a/day5/output.2 +++ /dev/null @@ -1,20 +0,0 @@ -1241009111 -1373066113 -1591272448 -1663131502 -1931439146 -2017638440 -2197425575 -2396801877 -3037672564 -3402116899 -3664261935 -3700090039 -3701339508 -3705255266 -3779692809 -535088217 -642320287 -896607734 -903350816 -971042070 diff --git a/day5/run b/day5/run index 5f9bf9a..65d0232 100755 Binary files a/day5/run and b/day5/run differ