Created
February 3, 2025 16:41
-
-
Save oriapp/9e42dc87154c6e6626dfb6a3b8331598 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| #include <limits.h> | |
| #ifdef _WIN32 | |
| #include <windows.h> | |
| #else | |
| #include <unistd.h> | |
| #endif | |
| #define ROWS 10 | |
| #define COLS 10 | |
| #define INF 1000000000 | |
| // A structure to represent a cell (point) in the grid. | |
| typedef struct { | |
| int x; | |
| int y; | |
| } Point; | |
| // Our grid: S = start, E = end, '#' = obstacle, ' ' = free cell. | |
| char grid[ROWS][COLS + 1] = { | |
| "S ", | |
| " ### ## ", | |
| " # ", | |
| " # ## ", | |
| " #### ", | |
| " ", | |
| " ## ## ", | |
| " ## ", | |
| " ## ", | |
| " E" | |
| }; | |
| // Function prototypes | |
| void clearScreen(void); | |
| void sleepMilliseconds(int ms); | |
| void printVisualization(const int visited[ROWS][COLS], const int dist[ROWS][COLS], | |
| Point current, Point start, Point end); | |
| void runDijkstra(void); | |
| int main(void) { | |
| runDijkstra(); | |
| return 0; | |
| } | |
| // Clears the terminal screen. | |
| void clearScreen(void) { | |
| #ifdef _WIN32 | |
| system("cls"); | |
| #else | |
| system("clear"); | |
| #endif | |
| } | |
| // Sleeps for the specified number of milliseconds. | |
| void sleepMilliseconds(int ms) { | |
| #ifdef _WIN32 | |
| Sleep(ms); | |
| #else | |
| usleep(ms * (1000 / 3)); | |
| #endif | |
| } | |
| // Prints the grid with a visualization overlay. | |
| // - '@' indicates the current cell being processed. | |
| // - 'S' and 'E' mark the start and end. | |
| // - '#' are obstacles. | |
| // - '.' marks visited cells. | |
| // - '+' marks cells that have been discovered (tentative distance updated). | |
| // - ' ' marks unreached cells. | |
| void printVisualization(const int visited[ROWS][COLS], const int dist[ROWS][COLS], | |
| Point current, Point start, Point end) { | |
| for (int i = 0; i < ROWS; i++) { | |
| for (int j = 0; j < COLS; j++) { | |
| if (i == current.x && j == current.y) { | |
| printf("@"); | |
| } else if (i == start.x && j == start.y) { | |
| printf("S"); | |
| } else if (i == end.x && j == end.y) { | |
| printf("E"); | |
| } else if (grid[i][j] == '#') { | |
| printf("#"); | |
| } else if (visited[i][j]) { | |
| printf("."); | |
| } else if (dist[i][j] < INF) { | |
| printf("+"); | |
| } else { | |
| printf(" "); | |
| } | |
| } | |
| printf("\n"); | |
| } | |
| } | |
| // Runs the Dijkstra's algorithm on our grid and visualizes each step. | |
| void runDijkstra(void) { | |
| int dist[ROWS][COLS]; | |
| int visited[ROWS][COLS]; | |
| Point prev[ROWS][COLS]; // To reconstruct the shortest path. | |
| // Initialization: set distances to INF, mark cells as unvisited, and reset previous pointers. | |
| for (int i = 0; i < ROWS; i++) { | |
| for (int j = 0; j < COLS; j++) { | |
| dist[i][j] = INF; | |
| visited[i][j] = 0; | |
| prev[i][j].x = -1; | |
| prev[i][j].y = -1; | |
| } | |
| } | |
| // Define start and end positions (S at top-left and E at bottom-right) | |
| Point start = {0, 0}; | |
| Point end = {ROWS - 1, COLS - 1}; | |
| dist[start.x][start.y] = 0; | |
| int iteration = 0; | |
| Point current = {-1, -1}; | |
| // Main loop: continue until there is no reachable unvisited cell. | |
| while (1) { | |
| // Find the unvisited cell with the smallest tentative distance. | |
| int minDist = INF; | |
| int found = 0; | |
| for (int i = 0; i < ROWS; i++) { | |
| for (int j = 0; j < COLS; j++) { | |
| if (!visited[i][j] && dist[i][j] < minDist) { | |
| minDist = dist[i][j]; | |
| current.x = i; | |
| current.y = j; | |
| found = 1; | |
| } | |
| } | |
| } | |
| // If no cell is found or the smallest distance is INF, then exit. | |
| if (!found || minDist == INF) { | |
| break; | |
| } | |
| // Mark the current cell as visited. | |
| visited[current.x][current.y] = 1; | |
| // Visualize this iteration. | |
| clearScreen(); | |
| printf("Iteration %d (Processing cell [%d, %d] with distance %d):\n", | |
| iteration++, current.x, current.y, dist[current.x][current.y]); | |
| printVisualization(visited, dist, current, start, end); | |
| sleepMilliseconds(500); | |
| // If we have reached the destination, stop. | |
| if (current.x == end.x && current.y == end.y) { | |
| break; | |
| } | |
| // Explore the four neighbors (up, down, left, right). | |
| int dx[4] = {-1, 1, 0, 0}; | |
| int dy[4] = {0, 0, -1, 1}; | |
| for (int k = 0; k < 4; k++) { | |
| int nx = current.x + dx[k]; | |
| int ny = current.y + dy[k]; | |
| // Skip out-of-bounds or obstacle cells. | |
| if (nx < 0 || nx >= ROWS || ny < 0 || ny >= COLS) | |
| continue; | |
| if (grid[nx][ny] == '#') | |
| continue; | |
| // If a shorter path to neighbor is found, update its distance and record the path. | |
| if (!visited[nx][ny] && dist[current.x][current.y] + 1 < dist[nx][ny]) { | |
| dist[nx][ny] = dist[current.x][current.y] + 1; | |
| prev[nx][ny] = current; | |
| } | |
| } | |
| } | |
| // Reconstruct the shortest path if one was found. | |
| if (dist[end.x][end.y] == INF) { | |
| printf("\nNo path found from S to E!\n"); | |
| } else { | |
| // Trace back from the end to the start. | |
| int pathLength = 0; | |
| Point path[ROWS * COLS]; | |
| Point trace = end; | |
| while (!(trace.x == start.x && trace.y == start.y)) { | |
| path[pathLength++] = trace; | |
| trace = prev[trace.x][trace.y]; | |
| } | |
| path[pathLength++] = start; // Add the start cell. | |
| // Create a copy of the grid and mark the found path with '*' (except for S and E). | |
| char finalGrid[ROWS][COLS + 1]; | |
| for (int i = 0; i < ROWS; i++) { | |
| strcpy(finalGrid[i], grid[i]); | |
| } | |
| for (int i = 0; i < pathLength; i++) { | |
| if ((path[i].x == start.x && path[i].y == start.y) || | |
| (path[i].x == end.x && path[i].y == end.y)) | |
| continue; | |
| finalGrid[path[i].x][path[i].y] = '*'; | |
| } | |
| clearScreen(); | |
| printf("Final path (length: %d):\n", dist[end.x][end.y]); | |
| for (int i = 0; i < ROWS; i++) { | |
| printf("%s\n", finalGrid[i]); | |
| } | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment