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.
 
 
 

167 lines
4.0 KiB

#include <stdio.h>
#include <stdbool.h>
#include <string.h>
#include <stdlib.h>
#define ANSI_COLOR_RED "\x1b[31m"
#define ANSI_COLOR_YELLOW "\x1b[33m"
#define ANSI_COLOR_RESET "\x1b[0m"
typedef struct VertexList VertexList;
typedef struct Vertex Vertex;
struct Vertex{
char name[10];
VertexList *adjacent;
bool bigCave;
unsigned int visited;
};
struct VertexList{
Vertex *vertex;
//This next pointer is to create a linked list of verticies, it does not reperesent graph position or adjacency
VertexList *next;
};
void printVertexList(VertexList *start){
VertexList *next = start;
while (next != NULL){
if ( next->vertex->bigCave ) printf(ANSI_COLOR_RED);
printf("%s ",next->vertex->name);
if ( next->vertex->bigCave ) printf(ANSI_COLOR_RESET);
next=next->next;
}
printf("\n");
}
int indexOf(VertexList *first, char *name ){
VertexList *current = first;
for ( unsigned int count = 0; current != NULL; count++ ){
if ( strcmp(current->vertex->name, name) == 0 ) return count;
else current = current->next;
}
return -1;
}
Vertex* getVertex(VertexList *first, char name[20]){
VertexList *current = first;
while ( current != NULL ){
if ( strcmp(current->vertex->name, name) == 0 ) return current->vertex;
else current = current->next;
}
return NULL;
}
Vertex* newVertex(char name[20]){
Vertex *new = (Vertex*)malloc(sizeof(Vertex));
new->adjacent = NULL;
new->visited = 0;
new->bigCave = ( name[0] >= 'A' && name[0] <= 'Z' );
strcpy(new->name,name);
return new;
}
VertexList* newVertexListItem(Vertex *virtex){
VertexList *newList = (VertexList*)malloc(sizeof(VertexList));
newList->next = NULL;
newList->vertex = virtex;
return newList;
}
VertexList* getLast(VertexList *current){
if ( current == NULL ) return NULL;
while ( current->next != NULL ) current = current->next;
return current;
}
unsigned int countPaths(Vertex *current, bool smallVisitedTwice){
// This is the break for the recursion - when we reach the end
if ( strcmp( current->name, "end" ) == 0 ) return 1;
current->visited++;
unsigned int count = 0;
VertexList *toTry = current->adjacent;
while ( toTry != NULL ){
if ( toTry->vertex->bigCave || toTry->vertex->visited == 0 )
count += countPaths(toTry->vertex, smallVisitedTwice);
else if ( !smallVisitedTwice && toTry->vertex->visited < 2 && strcmp(toTry->vertex->name, "start") != 0 ) {
count += countPaths(toTry->vertex, true);
}
toTry = toTry->next;
}
current->visited--;
return count;
}
int main( int argc, char *argv[] ){
if( argc == 2 ) {
VertexList *firstVirtex = NULL;
VertexList *lastVertex = getLast(firstVirtex);
FILE *fp=fopen(argv[1], "r");
if ( fp == NULL ) {
return 1;
}
char vertex1[20];
char vertex2[20];
char vertexStart[20] = "start";
Vertex *v1, *v2;
while ( !feof(fp) && fscanf( fp, "%[^-]-%s\n", vertex1,vertex2 ) ){
//Ensures the first virtex exists
v1 = getVertex(firstVirtex, vertex1);
v2 = getVertex(firstVirtex, vertex2);
if ( v1 == NULL ){
v1 = newVertex(vertex1);
if ( firstVirtex == NULL ){
firstVirtex = newVertexListItem(v1);
lastVertex = firstVirtex;
} else {
lastVertex->next = newVertexListItem(v1);
lastVertex = lastVertex->next;
}
}
//Ensures the second vertex exists
if ( v2 == NULL ){
v2 = newVertex(vertex2);
lastVertex->next = newVertexListItem(v2);
lastVertex = lastVertex->next;
}
//Links v1 and v2
if ( v1->adjacent == NULL ){
v1->adjacent = newVertexListItem(v2);
} else if ( indexOf(v1->adjacent, v2->name) < 0 ) {
getLast(v1->adjacent)->next = newVertexListItem(v2);
}
if ( v2->adjacent == NULL ){
v2->adjacent = newVertexListItem(v1);
} else if ( indexOf(v2->adjacent, v1->name) < 0 ) {
getLast(v2->adjacent)->next = newVertexListItem(v1);
}
//break;
}
printVertexList(firstVirtex);
printf("\n\nThere are %i valid paths", countPaths(getVertex(firstVirtex, vertexStart), false));
fclose(fp);
return 0;
} else {
printf("You need to provide a file\n");
return 1;
}
}