diff --git a/.gitignore b/.gitignore index b85a2fa..620cfea 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,5 @@ !public/*.html http/client http/server +mygrep/mygrep +cpair/cpair diff --git a/README.md b/README.md index 820ee01..536c884 100644 --- a/README.md +++ b/README.md @@ -3,5 +3,6 @@ This project contains some basic UNIX command line tools I had to do for TU. Currently the toolset is ther following: * mygrep - a simplified version of grep * http - an implementation of HTTP 1.1 client and server +* cpair - a program that searches for the closest pair of points in a set of 2D-points Feel free to read the descriptions for each tool. \ No newline at end of file diff --git a/cpair/Makefile b/cpair/Makefile new file mode 100644 index 0000000..8bdf922 --- /dev/null +++ b/cpair/Makefile @@ -0,0 +1,18 @@ +CC = gcc +CFLAGS = -std=c99 -pedantic -Wall -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_SVID_SOURCE -D_POSIX_C_SOURCE=200809L -g -c +TARGET = cpair + +all: $(TARGET).c + $(CC) $(CFLAGS) $(TARGET).c + $(CC) $(TARGET).o -o $(TARGET) + +install: + cp $(TARGET) /usr/local/bin/$(TARGET) + +clean: + $(RM) $(TARGET).o + $(RM) $(TARGET) + $(RM) *.tgz + +package: + tar -cvzf mygrep.tgz $(TARGET).c Makefile diff --git a/cpair/README.md b/cpair/README.md new file mode 100644 index 0000000..bed857f --- /dev/null +++ b/cpair/README.md @@ -0,0 +1,32 @@ +# cpair + +A program that searches for the closest pair of points in a set of 2D-points + + SYNOPSIS + cpair + + EXAMPLE + $ cat 1.txt + 4.0 4.0 + -1.0 1.0 + 1.0 -1.0 + -4.0 -4.0 + $ ./cpair < 1.txt + -1.000000 1.000000 + 1.000000 -1.000000 + + +The program accepts an array of 2D-points as an input from `stdin`. The input ends at `EOF`. + +The program does the following: +* No output if the array has one point +* The points if the array has 2 points +* Otherwise, the array is split in 2 parts based on the mean of X and sent to 2 different paralell child processes. The parent watches for the return code of the children and terminates with an error if any of the children exit with anything other than success. + +Algorithm description when there are more than 2 points: +* P1 and P2 are the closest pairs for the first and the second part respectively. +* Go through all of the pairs between the points from the first half with the second half and save the shortest one in P3. +* Compare P1, P2 and P3 and return the shortest one to `stdout`. + + +**Note: The description and the example are from the task I got from TU.** \ No newline at end of file diff --git a/cpair/cpair.c b/cpair/cpair.c new file mode 100644 index 0000000..8921f1d --- /dev/null +++ b/cpair/cpair.c @@ -0,0 +1,98 @@ +/** + * @file cpair.c + * @author Ivaylo Ivanov 11777707 + * @date 08.12.2018 + * + * @brief Main program module. + * + * A program that searches for the closest pair of points in a set of 2D-points + * + * SYNOPSIS + * cpair + * + * EXAMPLE + * $ cat 1.txt + * 4.0 4.0 + * -1.0 1.0 + * 1.0 -1.0 + * -4.0 -4.0 + * $ ./cpair < 1.txt + * -1.000000 1.000000 + * 1.000000 -1.000000 + * + * + * The program accepts an array of 2D-points as an input from stdin. The input ends at EOF. + * + * The program does the following: + * - No output if the array has one point + * - The points if the array has 2 points + * - Otherwise, the array is split in 2 parts based on the mean of X and sent to 2 different paralell child processes. The parent watches for the return code of the children and terminates with an error if any of the children exit with anything other than success. + * + * Algorithm description when there are more than 2 points: + * - P1 and P2 are the closest pairs for the first and the second part respectively. + * - Go through all of the pairs between the points from the first half with the second half and save the shortest one in P3. + * - Compare P1, P2 and P3 and return the shortest one to stdout. + * + **/ +#include +#include +#include +#include + +float get_x_mean(float *points[2], int arr_len); + +int main () { + char input[__UINT8_MAX__] = ""; ///< An array to save the input to + float *points[2]; ///< A pointer to a two-valued array to save the points to + int point_num = 0; ///< Save the number of points + + while(fgets(input, __INT8_MAX__, stdin) != NULL) { ///< Read line by line + /// Split the input by whitespace as delimiter + char *x = strtok(input, " "); + char *y = strtok(NULL, " "); + + if(x != NULL && y != NULL) { + /// Convert to float and save to the array + points[point_num][0] = strtof(x, NULL); + points[point_num][1] = strtof(y, NULL); + point_num++; ///< Increase the array length + } else { + puts("ERROR: Ill-formed line found"); + exit(EXIT_FAILURE); + } + } + + if(feof(stdin) == 0) { + puts("ERROR: An error interrupted the read"); + exit(EXIT_FAILURE); + } + + if(point_num == 1) + exit(EXIT_SUCCESS); + + if(point_num == 2) { + printf("%f %f\n", points[0][0], points[0][1]); + printf("%f %f\n", points[1][0], points[1][1]); + exit(EXIT_SUCCESS); + } + + float x_mean = get_x_mean(points, point_num); + + exit(EXIT_SUCCESS); +} + +/** + * @brief Function to calculate the mean of the X coordinates from a points array + * @details Loops through the points array, gets the sum of X coordinates and returns the mean + * @param points - a pointer to an array with the points + * point_num - number of points in the array + * @return mean of all X coordinates + * + **/ +float get_x_mean(float *points[2], int point_num) { + float x_sum = 0; + for(int i = 0; i< point_num; i++) { + x_sum += points[i][0]; + } + return x_sum/point_num; +} \ No newline at end of file