#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; } }