diff --git a/day12/Makefile b/day12/Makefile new file mode 100644 index 0000000..576a209 --- /dev/null +++ b/day12/Makefile @@ -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) diff --git a/day12/example1.txt b/day12/example1.txt new file mode 100644 index 0000000..6fd8c41 --- /dev/null +++ b/day12/example1.txt @@ -0,0 +1,7 @@ +start-A +start-b +A-c +A-b +b-d +A-end +b-end diff --git a/day12/example2.txt b/day12/example2.txt new file mode 100644 index 0000000..62cc714 --- /dev/null +++ b/day12/example2.txt @@ -0,0 +1,10 @@ +dc-end +HN-start +start-kj +dc-start +dc-HN +LN-dc +HN-end +kj-sa +kj-HN +kj-dc diff --git a/day12/example3.txt b/day12/example3.txt new file mode 100644 index 0000000..65f3833 --- /dev/null +++ b/day12/example3.txt @@ -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 diff --git a/day12/realinput.txt b/day12/realinput.txt new file mode 100644 index 0000000..18dcc86 --- /dev/null +++ b/day12/realinput.txt @@ -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 diff --git a/day12/solution-part1.c b/day12/solution-part1.c new file mode 100644 index 0000000..1ce13e3 --- /dev/null +++ b/day12/solution-part1.c @@ -0,0 +1,163 @@ +#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; + 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; + } +} diff --git a/day12/solution-part2.c b/day12/solution-part2.c new file mode 100644 index 0000000..bb5ca1b --- /dev/null +++ b/day12/solution-part2.c @@ -0,0 +1,167 @@ +#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; + } +}