diff --git a/DS-B/routeplanner/liviu.c b/DS-B/routeplanner/liviu.c new file mode 100644 index 0000000..c4708e2 --- /dev/null +++ b/DS-B/routeplanner/liviu.c @@ -0,0 +1,138 @@ +// +// Created by liviu on 3/27/25. +// +#include +#include +#include +#include + +typedef uint8_t u8; +typedef int8_t i8; +typedef uint16_t u16; +typedef int16_t i16; +typedef uint32_t u32; +typedef int32_t i32; +typedef uint64_t u64; +typedef int64_t i64; + +struct pos { + i32 row, col; +}; + +struct pos add(struct pos a, struct pos b) { return (struct pos){a.row + b.row, a.col + b.col}; } +struct pos sub(struct pos a, struct pos b) { return (struct pos){a.row - b.row, a.col - b.col}; } + +typedef struct pos data_type; +const u32 data_size = sizeof(data_type); + +struct darr { + u32 capacity; + u32 len; + data_type* data; + u32 head; +}; + +struct darr darr_ctor(const u32 capacity) { + data_type* ptr = malloc(capacity * data_size); + if (ptr == NULL) exit(1); + return (struct darr) {capacity, 0, ptr, 0}; +} + +void darr_dtor(const struct darr *_) { free(_->data); } + +void ensure_length(struct darr *dyn, const u32 len) { + if (dyn->capacity >= len) return; + + struct darr next = darr_ctor(len * 2); + memcpy(next.data, dyn->data, dyn->capacity * data_size); + + data_type* temp = next.data; + next.data = dyn->data; + dyn->data = temp; + dyn->capacity = next.capacity; + dyn->head = 0; + + darr_dtor(&next); +} + +data_type* queue_index(const struct darr* q, const u32 i) { return &q->data[(q->head + i) % q->capacity]; } + +void enqueue(struct darr* queue, const data_type value) { + ensure_length(queue, queue->len + 1); + *queue_index(queue, queue->len) = value; + queue->len++; +} + +void deque(struct darr* queue) { + if (queue->len == 0) exit(2); + queue->len--; + queue->head = (queue->head + 1) % queue->capacity; +} + +#define NMAX 13 +i32 maze[NMAX][NMAX] = { + {-1, -1, -1, -1, 0, -1, 0, -1, 0, -1, -1, -1, -1}, + {-1, -1, -1, -1, 0, -1, 0, -1, 0, -1, -1, -1, -1}, + {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1}, + {-1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {-1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {-1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1}, + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, + {-1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1}, + {-1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, -1}, + {-1, -1, -1, -1, 0, -1, 0, -1, 0, -1, -1, -1, -1}, + {-1, -1, -1, -1, 0, -1, 0, -1, 0, -1, -1, -1, -1} +}; + +u8 path[NMAX][NMAX]; +u8* path_at(const struct pos* loc) { return &path[loc->row][loc->col]; } +i32* maze_at(const struct pos* loc) { return &maze[loc->row][loc->col]; } + +struct pos directions[4] = { {0, 1}, {0, -1}, {1, 0}, {-1, 0}}; +u8 in_bounds(const struct pos* p) { return p->row >= 0 && p->col >= 0 && p->row < NMAX && p->col < NMAX; } + +i32 bfs(const struct pos start, const struct pos finish) { + struct darr queue = darr_ctor(100); + memset(path, -1, NMAX * NMAX * sizeof(u8)); + *path_at(&start) = 0; + enqueue(&queue, start); + + while (queue.len) { + const struct pos top = *queue_index(&queue, 0); + deque(&queue); + + const u8 count = *path_at(&top); + for (int i = 0; i < 4; i++) { + const struct pos next = add(top, directions[i]); + if (!in_bounds(&next)) continue; + if (*maze_at(&next) == -1) continue; /* path is blocked */ + if (*path_at(&next) <= count) continue; /* path was visited already */ + *path_at(&next) = count + 1; + enqueue(&queue, next); + + // print pos and status + // printf("%d,%d,%d\n", next.row, next.col, *path_at(&next)); + + // if (memcmp(&next, &finish, data_size) == 0) goto die; + } + } + +die: + darr_dtor(&queue); + return *path_at(&finish) - *path_at(&start) + 1; +} + +int main(int argc, char** argv) { + i32 dist = bfs((const struct pos){4, 0}, (const struct pos){8, 0}); + printf("Path length is %d\n", dist); + + for (u32 i = 0; i < NMAX; i++) { + for (u32 j = 0; j < NMAX; j++) { + printf("%d\t", path[i][j]); + } + printf("\n"); + } + return 0; +} \ No newline at end of file diff --git a/DS-B/routeplanner/main.c b/DS-B/routeplanner/main.c index 77a4e40..47c2b75 100644 --- a/DS-B/routeplanner/main.c +++ b/DS-B/routeplanner/main.c @@ -20,65 +20,53 @@ int assignmentMatrix[13][13] = { typedef struct cell { int x; int y; - } cell; -int isInBound(cell *c); -int isValidCrossing(cell *c); +int isInBound(const cell *c); +int isValidCrossing(const cell *c); int main(void) { /* read the nr of blocked stations and the stations*/ - int nrOfBlock = 0; + int nrOfBlock=0; scanf("%d", &nrOfBlock); - for (int i = 0; i < nrOfBlock; i++) { int x, y; readEdge(&x, &y); assignmentMatrix[x][y] = -1; } - - /* read the starting and end station*/ - cell startCell, targetCell,currentCell; - + /* read the starting and end station. Set current cell to be the starting cell.*/ + cell startCell, targetCell,currentCell; readStation(&startCell.x, &startCell.y); readStation(&targetCell.x, &targetCell.y); currentCell=startCell; - /* the **algorithm**, expand*/ + /* the **algorithm**, expand */ int v = 1; assignmentMatrix[targetCell.x][targetCell.y] = v; while (assignmentMatrix[startCell.x][startCell.y] == 0) { for (int i = 0; i < 13; i++) { for (int j = 0; j < 13; j++) { if (assignmentMatrix[i][j] == v) { - if (i!=12) { - if (assignmentMatrix[i+1][j] == 0) { + if (i!=12 && assignmentMatrix[i+1][j] == 0) { assignmentMatrix[i+1][j] = v+1; - } } - if (i!=0) { - if (assignmentMatrix[i-1][j] == 0) { + if (i!=0 && assignmentMatrix[i-1][j] == 0) { assignmentMatrix[i-1][j] = v+1; - } } - if (j!=12) { - if (assignmentMatrix[i][j+1] == 0) { + if (j!=12 && assignmentMatrix[i][j+1] == 0) { assignmentMatrix[i][j+1] = v+1; - } } - if (j!=0) { - if (assignmentMatrix[i][j-1] == 0) { + if (j!=0 && assignmentMatrix[i][j-1] == 0) { assignmentMatrix[i][j-1] = v+1; - } } } } } v+=1; } - - /* the **algorithm**, trace*/ + printMatrix(assignmentMatrix); + /* the **algorithm**, trace */ while (currentCell.x != targetCell.x || currentCell.y != targetCell.y) { const int neighbours[4][2]={{1,0},{0,1},{0,-1},{-1,0}}; @@ -86,7 +74,9 @@ int main(void) { cell neighbourCell; neighbourCell.x = currentCell.x + neighbours[i][0]; neighbourCell.y = currentCell.y + neighbours[i][1]; - if (isInBound(&neighbourCell) && assignmentMatrix[neighbourCell.x][neighbourCell.y] != -1 && assignmentMatrix[neighbourCell.x][neighbourCell.y] < assignmentMatrix[currentCell.x][currentCell.y] ) { + if (isInBound(&neighbourCell) && + assignmentMatrix[neighbourCell.x][neighbourCell.y] != -1 && + assignmentMatrix[neighbourCell.x][neighbourCell.y] < assignmentMatrix[currentCell.x][currentCell.y] ) { currentCell=neighbourCell; break; } @@ -98,13 +88,13 @@ int main(void) { return 0; } -int isInBound(cell *c) { +int isInBound(const cell *c) { if (c -> x >= 0 && c -> x <= 13 && c -> y >= 0 && c -> y <= 13) { return 1; } return 0; } -int isValidCrossing(cell *c) { +int isValidCrossing(const cell *c) { if (c -> x > 0 && c -> x <12 && c -> y > 0 && c -> y < 12) { return 1; } diff --git a/DS-B/routeplanner/readme.md b/DS-B/routeplanner/readme.md new file mode 100644 index 0000000..bba417a --- /dev/null +++ b/DS-B/routeplanner/readme.md @@ -0,0 +1 @@ +# Route Planner DS-B 24-25