diff --git a/labs/recursion/checkpoint1 b/labs/recursion/checkpoint1 new file mode 100755 index 0000000..56e4507 Binary files /dev/null and b/labs/recursion/checkpoint1 differ diff --git a/labs/recursion/checkpoint1.cpp b/labs/recursion/checkpoint1.cpp new file mode 100644 index 0000000..0139eca --- /dev/null +++ b/labs/recursion/checkpoint1.cpp @@ -0,0 +1,27 @@ +#include +using namespace std; + +int countPaths(int x, int y) { + // if we are at the origin, there is 1 path + if (x == 0 && y == 0) return 1; + + int paths = 0; + + // Move left if x > 0 + if (x > 0) paths += countPaths(x - 1, y); + + // Move up if y > 0 + if (y > 0) paths += countPaths(x, y - 1); + + return paths; +} + +int main() { + int start_x, start_y; + cout << "Enter the starting coordinates (x, y): "; + cin >> start_x >> start_y; + + int result = countPaths(start_x, start_y); + cout << "Number of paths to the origin: " << result << endl; + return 0; +} diff --git a/labs/recursion/checkpoint2 b/labs/recursion/checkpoint2 new file mode 100755 index 0000000..63f0ee7 Binary files /dev/null and b/labs/recursion/checkpoint2 differ diff --git a/labs/recursion/checkpoint2.cpp b/labs/recursion/checkpoint2.cpp new file mode 100644 index 0000000..cd0cad3 --- /dev/null +++ b/labs/recursion/checkpoint2.cpp @@ -0,0 +1,89 @@ +#include +#include +#include +#include + +enum GRID_STATUS { GRID_CLEAR, GRID_BLOCKED }; + +class Point { +public: + Point(int x0, int y0) : x(x0), y(y0) {} + int x, y; +}; + +void read_grid(std::istream& istr, std::vector>& blocked_grid, int& start_x, int& start_y) { + int x, y; + int max_x = 0, max_y = 0; + std::list blocked_points; + while ((istr >> x >> y) && !(x == 0 && y == 0)) { + blocked_points.push_back(Point(x, y)); + if (x > max_x) max_x = x; + if (y > max_y) max_y = y; + } + + istr >> start_x >> start_y; + if (start_x > max_x) max_x = start_x; + if (start_y > max_y) max_y = start_y; + + std::vector one_row_of_ys(max_y + 1, GRID_CLEAR); + std::vector> empty_grid(max_x + 1, one_row_of_ys); + blocked_grid = empty_grid; + + for (Point& p : blocked_points) { + blocked_grid[p.x][p.y] = GRID_BLOCKED; + } +} + +void print_grid(const std::vector>& blocked_grid, unsigned int start_x, unsigned int start_y) { + std::cout << "Grid visualization:\n"; + for (unsigned int y = 0; y < blocked_grid[0].size(); ++y) { + for (unsigned int x = 0; x < blocked_grid.size(); ++x) { + if (x == start_x && y == start_y) + std::cout << " S"; + else if (blocked_grid[x][y] == GRID_BLOCKED) + std::cout << " X"; + else + std::cout << " ."; + } + std::cout << std::endl; + } +} + +int countPaths(int x, int y, const std::vector>& blocked_grid) { + // Base case: if we are at the origin, there is 1 path + if (x == 0 && y == 0) return 1; + + // If the current cell is blocked, return 0 + if (blocked_grid[x][y] == GRID_BLOCKED) return 0; + + int paths = 0; + + // Move left if x > 0 + if (x > 0) paths += countPaths(x - 1, y, blocked_grid); + + // Move up if y > 0 + if (y > 0) paths += countPaths(x, y - 1, blocked_grid); + + return paths; +} + +int main(int argc, char* argv[]) { + if (argc != 2) { + std::cerr << "Usage: " << argv[0] << " grid-file" << std::endl; + return 1; + } + std::ifstream istr(argv[1]); + if (!istr) { + std::cerr << "Could not open " << argv[1] << std::endl; + return 1; + } + + std::vector> blocked_grid; + int start_x, start_y; + read_grid(istr, blocked_grid, start_x, start_y); + print_grid(blocked_grid, start_x, start_y); + + int result = countPaths(start_x, start_y, blocked_grid); + std::cout << "Number of legal paths to the origin: " << result << std::endl; + return 0; +} diff --git a/labs/recursion/checkpoint3 b/labs/recursion/checkpoint3 new file mode 100755 index 0000000..d272deb Binary files /dev/null and b/labs/recursion/checkpoint3 differ diff --git a/labs/recursion/checkpoint3.cpp b/labs/recursion/checkpoint3.cpp new file mode 100644 index 0000000..056f9e7 --- /dev/null +++ b/labs/recursion/checkpoint3.cpp @@ -0,0 +1,122 @@ +#include +#include +#include +#include + +class Point { +public: + Point(int x0, int y0) : x(x0), y(y0) {} + int x, y; +}; + +enum GRID_STATUS { GRID_CLEAR, GRID_BLOCKED }; + +void read_grid(std::istream& istr, + std::vector>& blocked_grid, + int& start_x, int& start_y) { + int x, y; + int max_x = 0, max_y = 0; + std::list blocked_points; + while ((istr >> x >> y) && !(x == 0 && y == 0)) { + blocked_points.push_back(Point(x, y)); + if (x > max_x) max_x = x; + if (y > max_y) max_y = y; + } + istr >> start_x >> start_y; + if (start_x > max_x) max_x = start_x; + if (start_y > max_y) max_y = start_y; + std::vector one_row_of_ys(max_y + 1, GRID_CLEAR); + std::vector> empty_grid(max_x + 1, one_row_of_ys); + blocked_grid = empty_grid; + for (const auto& p : blocked_points) { + blocked_grid[p.x][p.y] = GRID_BLOCKED; + } +} + +// Modified print_grid to show the path with '$' symbols +void print_grid(const std::vector>& blocked_grid, + const std::vector>& path_grid) { + std::cout << "Grid with path marked (X = blocked, $ = path, . = clear):\n"; + for (unsigned int y = 0; y < blocked_grid[0].size(); ++y) { + for (unsigned int x = 0; x < blocked_grid.size(); ++x) { + if (path_grid[x][y]) { + std::cout << " $"; + } else if (blocked_grid[x][y] == GRID_BLOCKED) { + std::cout << " X"; + } else { + std::cout << " ."; + } + } + std::cout << std::endl; + } +} + +std::list find_path(const std::vector>& blocked_grid, int x, int y) { + // no path + if (x < 0 || y < 0 || blocked_grid[x][y] == GRID_BLOCKED) { + return std::list(); + } + // Base case + if (x == 0 && y == 0) { + std::list path; + path.push_back(Point(0, 0)); + return path; + } + // Try moving left first + if (x > 0) { + std::list path_left = find_path(blocked_grid, x - 1, y); + if (!path_left.empty()) { + path_left.push_front(Point(x, y)); + return path_left; + } + } + // If left fails, try moving up + if (y > 0) { + std::list path_up = find_path(blocked_grid, x, y - 1); + if (!path_up.empty()) { + path_up.push_front(Point(x, y)); + return path_up; + } + } + // No path found + return std::list(); +} + +int main(int argc, char* argv[]) { + if (argc != 2) { + std::cerr << "Usage: " << argv[0] << " grid-file" << std::endl; + return 1; + } + std::ifstream istr(argv[1]); + if (!istr) { + std::cerr << "Could not open " << argv[1] << std::endl; + return 1; + } + + std::vector> blocked_grid; + int start_x, start_y; + read_grid(istr, blocked_grid, start_x, start_y); + + // Find one path + std::list path = find_path(blocked_grid, start_x, start_y); + if (path.empty()) { + std::cout << "No legal path exists.\n"; + } else { + std::cout << "Path found:\n"; + for (const auto& p : path) { + std::cout << "(" << p.x << ", " << p.y << ") "; + } + std::cout << "\n"; + + // Create path grid for marking + std::vector> path_grid(blocked_grid.size(), + std::vector(blocked_grid[0].size(), false)); + for (const auto& p : path) { + path_grid[p.x][p.y] = true; + } + // Print grid with path + print_grid(blocked_grid, path_grid); + } + + return 0; +} \ No newline at end of file