My solutions to the advent of code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

158 lines
3.5 KiB

#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
unsigned int countCommon( char larger[8], char smaller[8] ){
unsigned int common=0;
for ( unsigned int i = 0; i < strlen(smaller); i++ ){
if ( strchr( larger, smaller[i] ) != NULL ) common++;
}
return common;
}
// This will return true if the signals are the same length and contain the same letters
// Order doesn't matter though so ab if ab and ba are given, it will return true
bool sameSignals( char first[8], char second[8] ){
if ( strlen(first) == strlen(second) && countCommon(first, second) == strlen(first) ){
return true;
}
return false;
}
unsigned int decodeOutput( char signal[10][8], char output[4][8] ){
// This will hold the mappings.
// I.e. the string that should output 0 will be heald in mapping[0]
char mapping[10][8] = {0};
// 0 - Length 6
// 1 - Length 2
// 2 - Length 5
// 3 - Length 5
// 4 - Length 4
// 5 - Length 5
// 6 - Length 6
// 7 - Length 3
// 8 - Length 7
// 9 - Length 6
for ( int i = 0; i < 14; i++ ){
char *source = ( i < 10 ) ? signal[i] : output[i-10];
switch (strlen(source)) {
case 2:
strcpy(mapping[1],source);
break;
case 3:
strcpy(mapping[7],source);
break;
case 4:
strcpy(mapping[4],source);
break;
case 7:
strcpy(mapping[8],source);
break;
}
}
// When we get here, we know what 1, 7, 4 and 8 are
for ( int i = 0; i < 14; i++ ){
char *source = ( i < 10 ) ? signal[i] : output[i-10];
switch (strlen(source)) {
// We can determine what 2, 3 and 5 are by looking for numbers with a length of 5
// If it doesn shares all the same digits as 1, it's a 3
case 5:
if ( countCommon( source, mapping[1] ) == 2 ){
strcpy(mapping[3],source);
} else if (countCommon( source, mapping[4] ) == 3 ) {
strcpy(mapping[5],source);
} else {
strcpy(mapping[2],source);
}
break;
// We can determine what 0, 6 and 9 are by looking for numbers with a length of 6
// If it doesn't share the same digits as 1, it's a 6
// Otherwise, if it shares all 4 segments with 4, it's 9
// Otherwise it's 0
case 6:
if ( countCommon( source, mapping[1] ) != 2 ){
strcpy(mapping[6],source);
} else if (countCommon( source, mapping[4] ) == 4 ) {
strcpy(mapping[9],source);
} else {
strcpy(mapping[0],source);
}
break;
}
}
unsigned int decoded = 0;
for ( int i = 0; i < 4; i++ ){
unsigned int multiplyer = pow(10,(3-i));
for ( int j = 0; j < 10; j++ ){
if ( sameSignals(output[i], mapping[j] )){
decoded += (j * multiplyer);
break;
}
}
}
return decoded;
}
int main( int argc, char *argv[] ){
if( argc == 2 ) {
FILE *fp=fopen(argv[1], "r");
// This will hold the number of each count
unsigned int total=0;
while (!feof (fp)){
// each didget has a maximum length of 8 (7 + \0)
char signal[10][8] = {0};
char output[4][8] = {0};
char ch;
char str[8];
for(unsigned int i = 0; 1 ; i++ ){
if ( i < 10 ){
fscanf(fp, "%s%*c", signal[i]);
} else if (i == 10){
// This is the pipe character - we can discard it
char pipe;
fscanf(fp, "%c%*c", &pipe);
} else if ( i < 15 ){
fscanf(fp, "%s%*c", output[i-11]);
} else {
break;
}
}
unsigned int decoded = decodeOutput( signal, output );
printf("%i\n",decoded);
total += decoded;
}
printf("Total: %i\n", total);
fclose(fp);
return 0;
} else {
printf("You need to provide a file\n");
return 1;
}
}