Created
December 8, 2021 09:43
-
-
Save weirddan455/1bd9222b938f2919ebb86ada4a1b9aac to your computer and use it in GitHub Desktop.
Advent of Code Day 8 Part 2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <fcntl.h> | |
#include <unistd.h> | |
#include <stdbool.h> | |
#include <stdint.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <sys/stat.h> | |
typedef struct Digit | |
{ | |
int numOn; | |
bool segments[7]; | |
} Digit; | |
typedef struct Entry | |
{ | |
Digit digits[10]; | |
Digit display[4]; | |
} Entry; | |
// checks for lowercase only | |
bool isLetter(char c) | |
{ | |
return c > 96 && c < 123; | |
} | |
bool digitCompare(Digit *dig1, Digit *dig2) | |
{ | |
if (dig1->numOn != dig2->numOn) | |
{ | |
return false; | |
} | |
for (int i = 0; i < 7; i++) | |
{ | |
if (dig1->segments[i] != dig2->segments[i]) | |
{ | |
return false; | |
} | |
} | |
return true; | |
} | |
int main() | |
{ | |
int fd = open("input", O_RDONLY); | |
if (fd == -1) | |
{ | |
perror("open"); | |
return 1; | |
} | |
struct stat fileInfo; | |
if (fstat(fd, &fileInfo) != 0) | |
{ | |
perror("fstat"); | |
close(fd); | |
return 1; | |
} | |
char *data = malloc(fileInfo.st_size); | |
if (data == NULL) | |
{ | |
puts("malloc failed"); | |
close(fd); | |
return 1; | |
} | |
ssize_t bytesRead = read(fd, data, fileInfo.st_size); | |
if (bytesRead == -1) | |
{ | |
perror("read"); | |
close(fd); | |
free(data); | |
return 1; | |
} | |
if (bytesRead != fileInfo.st_size) | |
{ | |
printf("Error: read %d bytes. %d expected.\n", bytesRead, fileInfo.st_size); | |
close(fd); | |
free(data); | |
return 1; | |
} | |
close(fd); | |
int numEntries = 0; | |
for (ssize_t i = 0; i < bytesRead; i++) | |
{ | |
if (data[i] == '|') | |
{ | |
numEntries++; | |
} | |
} | |
Entry *entries = calloc(numEntries, sizeof(Entry)); | |
if (entries == NULL) | |
{ | |
puts("calloc failed"); | |
free(data); | |
return 1; | |
} | |
ssize_t dataIndex = 0; | |
for (int i = 0; i < numEntries; i++) | |
{ | |
for (int j = 0; j < 10; j++) | |
{ | |
while(isLetter(data[dataIndex])) | |
{ | |
switch(data[dataIndex]) | |
{ | |
case 'a': | |
entries[i].digits[j].segments[0] = true; | |
break; | |
case 'b': | |
entries[i].digits[j].segments[1] = true; | |
break; | |
case 'c': | |
entries[i].digits[j].segments[2] = true; | |
break; | |
case 'd': | |
entries[i].digits[j].segments[3] = true; | |
break; | |
case 'e': | |
entries[i].digits[j].segments[4] = true; | |
break; | |
case 'f': | |
entries[i].digits[j].segments[5] = true; | |
break; | |
case 'g': | |
entries[i].digits[j].segments[6] = true; | |
break; | |
} | |
entries[i].digits[j].numOn++; | |
dataIndex++; | |
} | |
dataIndex++; | |
} | |
dataIndex += 2; | |
for (int j = 0; j < 4; j++) | |
{ | |
while(isLetter(data[dataIndex])) | |
{ | |
switch(data[dataIndex]) | |
{ | |
case 'a': | |
entries[i].display[j].segments[0] = true; | |
break; | |
case 'b': | |
entries[i].display[j].segments[1] = true; | |
break; | |
case 'c': | |
entries[i].display[j].segments[2] = true; | |
break; | |
case 'd': | |
entries[i].display[j].segments[3] = true; | |
break; | |
case 'e': | |
entries[i].display[j].segments[4] = true; | |
break; | |
case 'f': | |
entries[i].display[j].segments[5] = true; | |
break; | |
case 'g': | |
entries[i].display[j].segments[6] = true; | |
break; | |
} | |
entries[i].display[j].numOn++; | |
dataIndex++; | |
} | |
dataIndex++; | |
} | |
} | |
free(data); | |
/* | |
0000 | |
1 2 | |
1 2 | |
3333 | |
4 5 | |
4 5 | |
6666 | |
*/ | |
uint64_t answer = 0; | |
for (int i = 0; i < numEntries; i++) | |
{ | |
Digit *solvedDigits[10]; | |
for (int j = 0; j < 10; j++) | |
{ | |
solvedDigits[j] = NULL; | |
} | |
for (int j = 0; j < 10; j++) | |
{ | |
switch(entries[i].digits[j].numOn) | |
{ | |
case 2: | |
solvedDigits[1] = &entries[i].digits[j]; | |
break; | |
case 3: | |
solvedDigits[7] = &entries[i].digits[j]; | |
break; | |
case 4: | |
solvedDigits[4] = &entries[i].digits[j]; | |
break; | |
case 7: | |
solvedDigits[8] = &entries[i].digits[j]; | |
break; | |
} | |
} | |
int oneSegments[2]; | |
int fourSegments[4]; | |
int sevenSegments[3]; | |
int segmentIndex = 0; | |
for (int j = 0; j < 7; j++) | |
{ | |
if (solvedDigits[1]->segments[j]) | |
{ | |
oneSegments[segmentIndex++] = j; | |
} | |
} | |
segmentIndex = 0; | |
for (int j = 0; j < 7; j++) | |
{ | |
if (solvedDigits[4]->segments[j]) | |
{ | |
fourSegments[segmentIndex++] = j; | |
} | |
} | |
segmentIndex = 0; | |
for (int j = 0; j < 7; j++) | |
{ | |
if (solvedDigits[7]->segments[j]) | |
{ | |
sevenSegments[segmentIndex++] = j; | |
} | |
} | |
int fSegment; | |
for (int j = 0; j < 10; j++) | |
{ | |
if (entries[i].digits[j].numOn == 6) | |
{ | |
if (!entries[i].digits[j].segments[oneSegments[0]] || !entries[i].digits[j].segments[oneSegments[1]]) | |
{ | |
solvedDigits[6] = &entries[i].digits[j]; | |
if (entries[i].digits[j].segments[oneSegments[0]]) | |
{ | |
fSegment = oneSegments[0]; | |
} | |
else | |
{ | |
fSegment = oneSegments[1]; | |
} | |
} | |
else if (!entries[i].digits[j].segments[fourSegments[0]] || !entries[i].digits[j].segments[fourSegments[1]] | |
|| !entries[i].digits[j].segments[fourSegments[2]] || !entries[i].digits[j].segments[fourSegments[3]]) | |
{ | |
solvedDigits[0] = &entries[i].digits[j]; | |
} | |
else | |
{ | |
solvedDigits[9] = &entries[i].digits[j]; | |
} | |
} | |
} | |
for (int j = 0; j < 10; j++) | |
{ | |
if (entries[i].digits[j].numOn == 5) | |
{ | |
if (!entries[i].digits[j].segments[fSegment]) | |
{ | |
solvedDigits[2] = &entries[i].digits[j]; | |
} | |
else if (!entries[i].digits[j].segments[sevenSegments[0]] || !entries[i].digits[j].segments[sevenSegments[1]] | |
|| !entries[i].digits[j].segments[sevenSegments[2]]) | |
{ | |
solvedDigits[5] = &entries[i].digits[j]; | |
} | |
else | |
{ | |
solvedDigits[3] = &entries[i].digits[j]; | |
} | |
} | |
} | |
uint64_t outputValue = 0; | |
for (int j = 0; j < 4; j++) | |
{ | |
int outputDigit = 9001; | |
for (int k = 0; k < 10; k++) | |
{ | |
if (solvedDigits[k] != NULL) | |
{ | |
if (digitCompare(solvedDigits[k], &entries[i].display[j])) | |
{ | |
outputDigit = k; | |
break; | |
} | |
} | |
} | |
if (outputDigit == 9001) | |
{ | |
puts("BEEP BEEP! WARNING WARNING!"); | |
} | |
else | |
{ | |
int mul = 1000; | |
for (int k = 0; k < j; k++) | |
{ | |
mul /= 10; | |
} | |
outputValue += outputDigit * mul; | |
} | |
} | |
answer += outputValue; | |
} | |
free(entries); | |
printf("Answer: %d\n", answer); | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment