parent
d0135de39a
commit
73ddcce4ae
7 changed files with 405 additions and 0 deletions
@ -0,0 +1,16 @@ |
||||
solution-part%: solution-part%.c |
||||
gcc $< -o $@ -lm
|
||||
|
||||
test1-%: solution-% example1.txt |
||||
$< example1.txt
|
||||
|
||||
test2-%: solution-% example2.txt |
||||
$< example2.txt
|
||||
|
||||
test3-%: solution-% example3.txt |
||||
$< example3.txt
|
||||
|
||||
run-%: solution-% realinput.txt |
||||
$< realinput.txt
|
||||
|
||||
.PHONY: $(patsubst %,run-%, 1 2) $(patsubst %,test-%, 1 2) |
@ -0,0 +1,7 @@ |
||||
start-A |
||||
start-b |
||||
A-c |
||||
A-b |
||||
b-d |
||||
A-end |
||||
b-end |
@ -0,0 +1,10 @@ |
||||
dc-end |
||||
HN-start |
||||
start-kj |
||||
dc-start |
||||
dc-HN |
||||
LN-dc |
||||
HN-end |
||||
kj-sa |
||||
kj-HN |
||||
kj-dc |
@ -0,0 +1,18 @@ |
||||
fs-end |
||||
he-DX |
||||
fs-he |
||||
start-DX |
||||
pj-DX |
||||
end-zg |
||||
zg-sl |
||||
zg-pj |
||||
pj-he |
||||
RW-he |
||||
fs-DX |
||||
pj-RW |
||||
zg-RW |
||||
start-pj |
||||
he-WI |
||||
zg-he |
||||
pj-fs |
||||
start-RW |
@ -0,0 +1,24 @@ |
||||
LA-sn |
||||
LA-mo |
||||
LA-zs |
||||
end-RD |
||||
sn-mo |
||||
end-zs |
||||
vx-start |
||||
mh-mo |
||||
mh-start |
||||
zs-JI |
||||
JQ-mo |
||||
zs-mo |
||||
start-JQ |
||||
rk-zs |
||||
mh-sn |
||||
mh-JQ |
||||
RD-mo |
||||
zs-JQ |
||||
vx-sn |
||||
RD-sn |
||||
vx-mh |
||||
JQ-vx |
||||
LA-end |
||||
JQ-sn |
@ -0,0 +1,163 @@ |
||||
#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; |
||||
} |
||||
} |
@ -0,0 +1,167 @@ |
||||
#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; |
||||
} |
||||
} |
Loading…
Reference in new issue