AoC2023/day5/day5b.c

105 lines
2.9 KiB
C

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <math.h>
#include <ctype.h>
#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;
}