diff --git a/day14/Makefile b/day14/Makefile new file mode 100644 index 0000000..da2e708 --- /dev/null +++ b/day14/Makefile @@ -0,0 +1,10 @@ +solution-part%: solution-part%.c + gcc $< -o $@ + +test-%: solution-% example.txt + $< example.txt + +run-%: solution-% realinput.txt + $< realinput.txt + +.PHONY: $(patsubst %,run-%, 1 2) $(patsubst %,test-%, 1 2) diff --git a/day14/example.txt b/day14/example.txt new file mode 100644 index 0000000..b5594dd --- /dev/null +++ b/day14/example.txt @@ -0,0 +1,18 @@ +NNCB + +CH -> B +HH -> N +CB -> H +NH -> C +HB -> C +HC -> B +HN -> C +NN -> C +BH -> H +NC -> B +NB -> B +BN -> B +BB -> N +BC -> B +CC -> N +CN -> C diff --git a/day14/realinput.txt b/day14/realinput.txt new file mode 100644 index 0000000..ec9b021 --- /dev/null +++ b/day14/realinput.txt @@ -0,0 +1,102 @@ +CNBPHFBOPCSPKOFNHVKV + +CS -> S +FB -> F +VK -> V +HO -> F +SO -> K +FK -> B +VS -> C +PS -> H +HH -> P +KH -> V +PV -> V +CB -> N +BB -> N +HB -> B +HV -> O +NC -> H +NF -> B +HP -> B +HK -> S +SF -> O +ON -> K +VN -> V +SB -> H +SK -> H +VH -> N +KN -> C +CC -> N +BF -> H +SN -> N +KP -> B +FO -> N +KO -> V +BP -> O +OK -> F +HC -> B +NH -> O +SP -> O +OO -> S +VC -> O +PC -> F +VB -> O +FF -> S +BS -> F +KS -> F +OV -> P +NB -> O +CF -> F +SS -> V +KV -> K +FP -> F +KC -> C +PF -> C +OS -> C +PN -> B +OP -> C +FN -> F +OF -> C +NP -> C +CK -> N +BN -> K +BO -> K +OH -> S +BH -> O +SH -> N +CH -> K +PO -> V +CN -> N +BV -> F +FV -> B +VP -> V +FS -> O +NV -> P +PH -> C +HN -> P +VV -> C +NK -> K +CO -> N +NS -> P +VO -> P +CP -> V +OC -> S +PK -> V +NN -> F +SC -> P +BK -> F +BC -> P +FH -> B +OB -> O +FC -> N +PB -> N +VF -> N +PP -> S +HS -> O +HF -> N +KK -> C +KB -> N +SV -> N +KF -> K +CV -> N +NO -> P diff --git a/day14/solution-part1.c b/day14/solution-part1.c new file mode 100644 index 0000000..4c33408 --- /dev/null +++ b/day14/solution-part1.c @@ -0,0 +1,163 @@ +#include +#include +#include +#include + +#define ANSI_COLOR_RED "\x1b[31m" +#define ANSI_COLOR_YELLOW "\x1b[33m" +#define ANSI_COLOR_RESET "\x1b[0m" + +#define MAX(a, b) ((a) < (b) ? (b) : (a)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + + +typedef struct Element Element; +struct Element{ + char letter; + Element *next; +}; + +typedef struct Interaction Interaction; +struct Interaction{ + char letter1; + char letter2; + char result; + Interaction *next; +}; + +Element* newElement(char letter){ + Element *new = malloc(sizeof(Element)); + new->letter = letter; + new->next = NULL; + return new; +} + +Interaction* newInteraction(char letter1, char letter2, char result){ + Interaction *new = malloc(sizeof(Interaction)); + new->letter1 = letter1; + new->letter2 = letter2; + new->result = result; + new->next = NULL; + return new; +} + +void printElements(Element *current){ + while ( current != NULL ){ + printf("%c ",current->letter); + current = current->next; + } + printf("\n"); +} + +void printInteractions(Interaction *current){ + while ( current != NULL ){ + printf("Merging %c and %c will give you %c\n",current->letter1, current->letter2, current->result); + current = current->next; + } + printf("\n"); +} + + +unsigned int countElements(Element *current){ + unsigned int count = 0; + while ( current != NULL ){ + count++; + current = current->next; + } + return count; +} + +Element* interact(char firstCh, char secondCh, Interaction *interaction){ + while ( interaction != NULL ){ + if ( interaction->letter1 == firstCh && interaction->letter2 == secondCh ) + return newElement( interaction->result ); + interaction = interaction->next; + } + return NULL; +} + +unsigned int calculateScore(Element *current){ + unsigned int min = ~0; + unsigned int max = 0; + unsigned int counts[26] = {0}; + while ( current != NULL ){ + counts[current->letter - 'A']++; + current = current->next; + } + for(unsigned int i = 0; i < 26; i++){ + max = MAX( max, counts[i] ); + if ( counts[i] != 0 ) min = MIN( min, counts[i] ); + printf("%c: %i\n", i+'A' , counts[i]); + } + printf("Max: %i, Min: %i, Difference: %i\n", max, min, max-min); + return 0; +} + +void step(Element *element, Interaction *interaction){ + while ( element != NULL && element->next != NULL ){ + Element *toInsert = interact(element->letter, element->next->letter, interaction); + toInsert->next = element->next; + element->next = toInsert; + element = toInsert->next; + } +} + +int main( int argc, char *argv[] ){ + if( argc == 2 ) { + + + FILE *fp=fopen(argv[1], "r"); + + char ch; + Element *firstEl = NULL; + Element *previousEl = NULL; + while ( fscanf( fp, "%c",&ch )){ + if ( ch == '\n' ) break; + printf("%c\n",ch); + if ( firstEl == NULL ){ + firstEl = newElement(ch); + previousEl = firstEl; + } else { + previousEl->next = newElement(ch); + previousEl = previousEl->next; + } + } + + + //Skip over empty lines + while( !feof(fp) && fscanf(fp, "\n\n") ) continue; + + char firstCh, secondCh, resultCh; + Interaction *firstInt = NULL; + Interaction *previousInt = NULL; + while( !feof(fp) && fscanf(fp, "%c%c -> %c\n", &firstCh, &secondCh, &resultCh) ){ + if ( firstInt == NULL ){ + firstInt = newInteraction(firstCh, secondCh, resultCh); + previousInt = firstInt; + } else { + previousInt->next = newInteraction(firstCh, secondCh, resultCh); + previousInt = previousInt->next; + } + } + + + + printElements(firstEl); + for ( unsigned int i = 0; i < 10; i++ ){ + printf("\nStep %i:\n", i+1); + step(firstEl, firstInt); + printf("Length %i\n", countElements(firstEl)); + } + + calculateScore(firstEl); + + fclose(fp); + + + + return 0; + } else { + printf("You need to provide a file\n"); + return 1; + } +} diff --git a/day14/solution-part2.c b/day14/solution-part2.c new file mode 100644 index 0000000..cc8de3b --- /dev/null +++ b/day14/solution-part2.c @@ -0,0 +1,159 @@ +#include +#include +#include +#include + +#define ANSI_COLOR_RED "\x1b[31m" +#define ANSI_COLOR_YELLOW "\x1b[33m" +#define ANSI_COLOR_RESET "\x1b[0m" + +#define MAX(a, b) ((a) < (b) ? (b) : (a)) +#define MIN(a, b) ((a) < (b) ? (a) : (b)) + +#define pairId(a,b) ( (26 * ( a - 'A' )) + ( b - 'A' ) ) + +typedef struct Interaction Interaction; +struct Interaction{ + char letter1; + char letter2; + char result; + Interaction *next; +}; + + +Interaction* newInteraction(char letter1, char letter2, char result){ + Interaction *new = malloc(sizeof(Interaction)); + new->letter1 = letter1; + new->letter2 = letter2; + new->result = result; + new->next = NULL; + return new; +} + +void printElementPairs(unsigned long *pairs){ + for ( unsigned int i = 'A'; i <= 'Z'; i++ ) + for ( unsigned int j = 'A'; j <= 'Z'; j++ ){ + if ( pairs[pairId(i,j)] > 0 ) printf("%c%c: %lu\n", i, j, pairs[pairId(i,j)]); + } +} + +void printElements(unsigned long *letters){ + for ( unsigned int i = 'A'; i <= 'Z'; i++ ) + if ( letters[i-'A'] > 0 ) printf("%c: %lu\n", i, letters[i-'A']); +} + +void printInteractions(Interaction *current){ + while ( current != NULL ){ + printf("Merging %c and %c will give you %c\n",current->letter1, current->letter2, current->result); + current = current->next; + } + printf("\n"); +} + + +char interact(char firstCh, char secondCh, Interaction *interaction){ + while ( interaction != NULL ){ + if ( interaction->letter1 == firstCh && interaction->letter2 == secondCh ) + return interaction->result; + interaction = interaction->next; + } + return 0; +} + +unsigned long calculateScore(unsigned long *letters){ + unsigned long min = ~0; + unsigned long max = 0; + for ( unsigned int i = 0; i < 26; i++ ){ + unsigned long count = letters[i]; + if ( count > 0 ){ + min = MIN( min, count ); + max = MAX( max, count ); + } + } + printf("Max: %lu, Min: %lu, Difference: %lu\n", max, min, max-min); + return 0; +} + +unsigned long* step(unsigned long *oldPairsCount, unsigned long *letterCount, Interaction *interaction){ + unsigned long *newPairsCount = malloc( sizeof(long) * ( 1 + pairId('Z','Z') ) ); + memset(newPairsCount, 0, sizeof(long) * ( 1 + pairId('Z','Z') ) ); + for ( unsigned int i = 'A'; i <= 'Z'; i++ ) + for ( unsigned int j = 'A'; j <= 'Z'; j++ ){ + unsigned long count = oldPairsCount[pairId(i,j)]; + if ( count > 0 ){ + char newChar = interact(i,j,interaction); + newPairsCount[pairId(i,newChar)] += count; + newPairsCount[pairId(newChar,j)] += count; + letterCount[newChar - 'A'] += count; + } + } + free(oldPairsCount); + return newPairsCount; +} + +int main( int argc, char *argv[] ){ + if( argc == 2 ) { + + + FILE *fp=fopen(argv[1], "r"); + + char line[80]; + unsigned long *pairsCount = malloc( sizeof(long) * ( 1 + pairId('Z','Z') ) ); + memset(pairsCount, 0, sizeof(long) * ( 1 + pairId('Z','Z') ) ); + unsigned long *letterCount = malloc( sizeof(long) * 26 ); + memset(letterCount, 0, sizeof(long) * 26 ); + + //first line + fscanf( fp, "%s", line ); + for ( unsigned int i = 0; i < strlen(line); i++ ){ + if ( line[i+1] != '\0' ){ + printf("Pair: %c %c\n", line[i], line[i+1]); + pairsCount[pairId(line[i], line[i+1])]++; + } + letterCount[line[i] - 'A']++; + } + + + + //Skip over empty lines + while( !feof(fp) && fscanf(fp, "\n\n") ) continue; + + char firstCh, secondCh, resultCh; + Interaction *firstInt = NULL; + Interaction *previousInt = NULL; + while( !feof(fp) && fscanf(fp, "%c%c -> %c\n", &firstCh, &secondCh, &resultCh) ){ + if ( firstInt == NULL ){ + firstInt = newInteraction(firstCh, secondCh, resultCh); + previousInt = firstInt; + } else { + previousInt->next = newInteraction(firstCh, secondCh, resultCh); + previousInt = previousInt->next; + } + } + + //printInteractions(firstInt); + + + printElementPairs(pairsCount); + + printf("\n\n"); + + for ( unsigned int i = 0; i < 40; i++ ){ + printf("\nStep %i:\n", i+1); + pairsCount = step(pairsCount,letterCount,firstInt); + printElementPairs(pairsCount); + printElements(letterCount); + } + + calculateScore(letterCount); + + fclose(fp); + + + + return 0; + } else { + printf("You need to provide a file\n"); + return 1; + } +}