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