Skip to content

Instantly share code, notes, and snippets.

@weirddan455
Created December 8, 2021 09:43
Show Gist options
  • Save weirddan455/1bd9222b938f2919ebb86ada4a1b9aac to your computer and use it in GitHub Desktop.
Save weirddan455/1bd9222b938f2919ebb86ada4a1b9aac to your computer and use it in GitHub Desktop.
Advent of Code Day 8 Part 2
#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