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.
164 lines
3.8 KiB
164 lines
3.8 KiB
3 years ago
|
#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;
|
||
|
bool 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 = false;
|
||
|
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){
|
||
|
// This is the break for the recursion - when we reach the end
|
||
|
if ( strcmp( current->name, "end" ) == 0 ) return 1;
|
||
|
|
||
|
current->visited = true;
|
||
|
|
||
|
unsigned int count = 0;
|
||
|
VertexList *toTry = current->adjacent;
|
||
|
while ( toTry != NULL ){
|
||
|
if ( toTry->vertex->bigCave || !toTry->vertex->visited )
|
||
|
count += countPaths(toTry->vertex);
|
||
|
toTry = toTry->next;
|
||
|
}
|
||
|
|
||
|
|
||
|
current->visited = false;
|
||
|
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)));
|
||
|
|
||
|
fclose(fp);
|
||
|
|
||
|
return 0;
|
||
|
} else {
|
||
|
printf("You need to provide a file\n");
|
||
|
return 1;
|
||
|
}
|
||
|
}
|