Add initial cpair functionality
This commit is contained in:
parent
98015cb8b5
commit
ccfbf9e1ed
2
.gitignore
vendored
2
.gitignore
vendored
@ -6,3 +6,5 @@
|
||||
!public/*.html
|
||||
http/client
|
||||
http/server
|
||||
mygrep/mygrep
|
||||
cpair/cpair
|
||||
|
@ -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.
|
18
cpair/Makefile
Normal file
18
cpair/Makefile
Normal file
@ -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
|
32
cpair/README.md
Normal file
32
cpair/README.md
Normal file
@ -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.**
|
98
cpair/cpair.c
Normal file
98
cpair/cpair.c
Normal file
@ -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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
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;
|
||||
}
|
Reference in New Issue
Block a user