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