diff --git a/misc/cartesian_to_polar.c b/misc/cartesian_to_polar.c index e7b02128..bac24632 100644 --- a/misc/cartesian_to_polar.c +++ b/misc/cartesian_to_polar.c @@ -1,50 +1,66 @@ +/** + * @file + * @brief Function to convert a Cartesian co-ordinate to polar form. + */ +#define _USE_MATH_DEFINES /**< required for MS Visual C */ +#include #include #include - -const double pi = 3.141592653589793238462643383279502884; +#include /** -give as arguments to the executable two x and y coordinates -outputs a polar coordinate -*/ -int main() + * @brief Function to convert cartesian coordinates to polar. + *\f{eqnarray*}{ + r &=& \sqrt{x^2+y^2}\\ + \theta &=& \atan\frac{y}{x} + \f} + * @param [in] x absicca value + * @param [in] y ordinate value + * @param [out] r pointer to store polar radius + * @param [out] theta pointer to store polar angle (in radian) + */ +void to_polar(double x, double y, double *r, double *theta) { - double x, y; - double r, theta, thetaFinal; - scanf("%lf %lf", &x, &y); - r = hypot(x, y); + double thetaFinal = 0.f; + + *r = sqrt(x * x + y * y); + if (x != 0) { if (y != 0) { - theta = atan(y / x); + *theta = atan(y / x); if ((x > 0 && y > 0) || (x == -y)) { // Q1 - thetaFinal = theta; + thetaFinal = *theta; } else if (x < 0 && y > 0) { // Q2 - thetaFinal = theta + pi; + thetaFinal = *theta + M_PI; } else if (x < 0 && y < 0) { // Q3 - thetaFinal = theta - pi; + thetaFinal = *theta - M_PI; } else if (x > 0 && y < 0) { // Q4 - thetaFinal = 2 * pi - theta; + thetaFinal = 2 * M_PI - *theta; + } + else + { + fprintf(stderr, "Should not reach here!\n"); } } } - if (x == 0) + else { // exceptions when no actual angle is present if (y > 0) { - thetaFinal = pi / 2; + thetaFinal = M_PI / 2; } else { - thetaFinal = -(pi / 2); + thetaFinal = -(M_PI / 2); } } if (y == 0) @@ -55,8 +71,53 @@ int main() } else { - thetaFinal = -pi; + thetaFinal = -M_PI; } } - printf("%.2f %.2f\n", r, atan2(y, x)); + + *theta = thetaFinal; +} + +/** + * @brief Generate a random number in the given limits + * + * @param lim1 lower limit + * @param lim2 upper limit + * @return random number in the given range + */ +double get_rand(double lim1, double lim2) +{ + double r = (double)rand() / RAND_MAX; // value in [0,1) + return (lim2 - lim1) * r + lim1; // scale to range +} + +/** + * @brief Test implementation + * + */ +void test() +{ + srand(10); + int NUM_TESTS = 5; + + for (int i = 0; i < NUM_TESTS; i++) + { + double r, theta; + printf("Test %d.... ", i); + double x = get_rand(-5, 5); + double y = get_rand(-5, 5); + printf("(%.2g, %.2g).... ", x, y); + to_polar(x, y, &r, &theta); + assert(fabs(r - hypot(x, y)) < 0.01); + assert(fabs(theta - atan2(y, x)) < 0.01); + printf("passed\n"); + } +} + +/** Main function */ +int main() +{ + test(); + + return 0; } diff --git a/misc/union_find.c b/misc/union_find.c index 8cd11aab..a2bf3f27 100644 --- a/misc/union_find.c +++ b/misc/union_find.c @@ -1,46 +1,89 @@ +/** + * @file union_find.c + * @brief [Union + * find](https://en.wikipedia.org/wiki/Disjoint-set_data_structure) algorithm. + */ #include +#include +#define MAX_SIZE 1000 /**< maximum number of elements in the set */ -int p[1000000]; -int find(int x) +/** + * @brief Find index of or value in an array + * + * @param [in,out] p array to search and update + * @param x value to search + * @return value at the index `x` + */ +int find(int *p, int x) { + if (x >= MAX_SIZE) + { + fprintf(stderr, "Out-of bounds value\n"); + exit(EXIT_FAILURE); + } + if (p[x] == x) { return x; } else { - p[x] = find(p[x]); + p[x] = find(p, p[x]); return p[x]; } } -// Call to function join(int x, int y) to join PARAM x and y -void join(int x, int y) { p[find(x)] = find(y); } +/** + * @brief Function to join + * @param [in,out] p array to join in + * @param x value or index to join to + * @param y value or index to join from + */ +void join(int *p, int x, int y) { p[find(p, x)] = find(p, y); } + +/** Main function */ int main() { - // Have all array indexes that you need to use refrence themselves + int union_set[MAX_SIZE]; + + // Have all array indexes that you need to use reference themselves for (int i = 0; i < 10; i++) { - p[i] = i; + union_set[i] = i; } // p = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} - join(3, 5); + + join(union_set, 3, 5); + printf("The array is now: "); + for (int i = 0; i < 10; i++) + { + printf("%d ", union_set[i]); + } + printf("\n"); // Now 3 and 5 are groupped together, that is find(3) = find(5) // p = {0, 1, 2, 5, 4, 5, 6, 7, 8, 9} - join(3, 8); + + join(union_set, 3, 8); + printf("The array is now: "); + for (int i = 0; i < 10; i++) + { + printf("%d ", union_set[i]); + } + printf("\n"); + // Now 3, 5 and are groupped together, find(3) = find(5) = find(8) // p = {0, 1, 2, 5, 4, 8, 6, 7, 8, 9} - join(0, 5); - if (find(0) == find(3)) + join(union_set, 0, 5); + if (find(union_set, 0) == find(union_set, 3)) { printf("0 and 3 are groupped together\n"); } printf("The array is now: "); for (int i = 0; i < 10; i++) { - printf("%d ", p[i]); + printf("%d ", union_set[i]); } printf("\n"); return 0; -} \ No newline at end of file +} diff --git a/searching/jump_search.c b/searching/jump_search.c index 80c9ab9c..73596554 100644 --- a/searching/jump_search.c +++ b/searching/jump_search.c @@ -1,37 +1,85 @@ +/** + * @file jump_search.c + * @brief Implementation of [jump + * search](https://en.wikipedia.org/wiki/Jump_search) algorithm. + */ +#include #include #include + +/** + * @brief Macro to return the minimum of two values + */ #define min(X, Y) ((X) < (Y) ? (X) : (Y)) -int jump_search(int *arr, int x); -int n; -int main() -{ - int arr[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610}; - n = sizeof(arr) / sizeof(int); - int x = 55; - int index = jump_search(arr, x); - printf("\nNumber %d is at index %d\n", x, index); -} - -int jump_search(int *arr, int x) +/** + * @brief Implement Jump-search algorithm + * + * @param [in] arr Array to search within + * @param x value to search for + * @param n length of array + * @return index where the value was found + * @return -1 if value not found + */ +int jump_search(const int *arr, int x, size_t n) { int step = floor(sqrt(n)); int prev = 0; - while (*(arr + (min(step, n) - 1)) < x) + + while (arr[min(step, n) - 1] < x) { prev = step; step += floor(sqrt(n)); if (prev >= n) + { return -1; + } } - while (*(arr + prev) < x) + while (arr[prev] < x) { prev = prev + 1; - if (prev == fmin(step, n)) + if (prev == min(step, n)) + { return -1; + } } - if (*(arr + prev) == x) + if (arr[prev] == x) + { return prev; + } return -1; } + +/** + * @brief Test implementation of the function + * + */ +void test() +{ + int arr[] = {0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610}; + size_t n = sizeof(arr) / sizeof(int); + + int x = 55; + printf("Test 1.... "); + int index = jump_search(arr, x, n); + assert(index == 10); + printf("passed\nTest 2.... "); + x = 56; + index = jump_search(arr, x, n); + assert(index == -1); + printf("passed\nTest 3.... "); + x = 13; + index = jump_search(arr, x, n); + assert(index == 7); + printf("passed\n"); +} + +/** + * @brief Main function + */ +int main() +{ + test(); + return 0; +}