task_01_05_2025/main.c

242 lines
5.1 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <sys/time.h>
#include <time.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#include <limits.h>
#include <stdarg.h>
#include <string.h>
int A = (float)(7 * 6 * 8);
// --------------------------
// Functions
// --------------------------
bool debug = false;
// Function for get out debug information if debug mode enabled
void debugPrint(const char *format, ...) {
if (debug) {
va_list args;
va_start(args, format);
vprintf(format, args);
va_end(args);
}
}
// Random float from min to max
float randFloat(int min, int max, unsigned int *seed) {
float scale = rand_r(seed) / (float) RAND_MAX;
return min + scale * (max - min);
}
void printNum(double *num) {
if (*num > 10000) {
debugPrint("%.3e ", *num);
// 0.000
}
else {
debugPrint("%.3f ", *num);
// 0.000e+0
}
}
void outM(double *M1_ptr, int M1_N, double *M2_ptr, int M2_N) {
debugPrint("M1:\n");
for (int i = 0; i < M1_N; i++) {
printNum(&M1_ptr[i]);
}
debugPrint("\nM2:\n");
for (int i = 0; i < M2_N; i++) {
printNum(&M2_ptr[i]);
}
}
// ---------- END------------
// --------------------------
// STEP 1 - Generation
// --------------------------
unsigned int seed;
void gen_M1(double *M_ptr, int N) {
float min = 1.0f;
float max = A;
for (int i = 0; i < N; i++) {
M_ptr[i] = randFloat(min, max, &seed);
}
}
void gen_M2(double *M_ptr, int N) {
float min = A;
float max = A*10;
for (int i = 0; i < N; i++) {
M_ptr[i] = randFloat(min, max, &seed);
}
}
// ---------- END------------
// --------------------------
// STEP 2 - Map
// --------------------------
void applyMapM1(double *M_ptr, int N) {
for (int i = 0; i < N; i++) {
M_ptr[i] = cosh(M_ptr[i]);
}
}
void applyMapM2(double *M_ptr, int N) {
bool first = true;
double M[N];
for (int i = 0; i < N; i++) {
if (first) {
M[i] = fabs(sin(M_ptr[i]));
}
else {
M[i] = fabs(sin(M_ptr[i] + M[i-1]));
}
}
// Write changes
for (int i = 0; i < N; i++) {
M_ptr[i] = M[i];
}
}
// ---------- END------------
// --------------------------
// STEP 3 - Merge
// --------------------------
void applyMerge(double *M1_ptr, double *M2_ptr, int M2_N) {
for (int i = 0; i < M2_N; i++) {
M2_ptr[i] = M1_ptr[i]*M2_ptr[i];
}
}
// ---------- END------------
// --------------------------
// STEP 4 - Sort
// --------------------------
void selectionSort(double *M_ptr, int N) {
double max = 0;
int max_it = 0;
int it = N;
for (int n = 0; n < N; n++) {
max = NAN;
for (int i = 0; i < it; i++) {
if (isnan(max) || M_ptr[i] > max) {
max = M_ptr[i];
max_it = i;
}
}
M_ptr[max_it] = M_ptr[it - 1];
M_ptr[it - 1] = max;
it--;
}
}
// ---------- END------------
// --------------------------
// STEP 5 - Reduce
// --------------------------
void applyReduce(double *M_ptr, int N) {
float sum = 0;
int min = INT_MIN;
// Find min non-zero
for (int i = 0; i < N; i++) {
if (min == INT_MIN || trunc(M_ptr[i]) < min) {
if (trunc(M_ptr[i]) != 0) {
min = (int)trunc(M_ptr[i]);
}
}
}
// Sum of all sin(i) where i%min == 0
for (int i = 0; i < N; i++) {
if ((int)trunc(M_ptr[i]) % min == 0) {
sum += sin( (int)trunc(M_ptr[i]) );
debugPrint("sum: %f\n", sum);
}
}
}
// ---------- END------------
int main(int argc, char* argv[]) {
if (argc < 2) {
debugPrint("Usage: %s <N> [debug]\n", argv[0]);
exit(1);
}
if (argc >= 3 && strcmp(argv[2], "debug") == 0) {
debug = true;
}
// Number of numbers
int N;
N = atoi(argv[1]);
// Set custom seed, because need to check different progs
//seed = time(0);
seed = 10;
// First array
double* M1_ptr;
M1_ptr = (double*)malloc(N * sizeof(double));
int M1_N = N;
// Second array
double* M2_ptr;
M2_ptr = (double*)malloc(N/2 * sizeof(double));
int M2_N = N/2;
// Remember start time
struct timeval T1, T2;
long delta_ms;
gettimeofday(&T1, NULL);
// STEP 1 - generate
gen_M1(M1_ptr, M1_N);
gen_M2(M2_ptr, M2_N);
debugPrint("---------- Generated arrays ----------\n");
outM(M1_ptr, M1_N, M2_ptr, M2_N);
debugPrint("\n---------------- END -----------------\n");
// STEP 2 - map
applyMapM1(M1_ptr, M1_N);
applyMapM2(M2_ptr, M2_N);
debugPrint("\n--------------- STEP 2 ---------------\n");
outM(M1_ptr, M1_N, M2_ptr, M2_N);
debugPrint("\n---------------- END -----------------\n");
// STEP 3 - merge
applyMerge(M1_ptr, M2_ptr, M2_N);
debugPrint("\n--------------- STEP 3 ---------------\n");
outM(M1_ptr, M1_N, M2_ptr, M2_N);
debugPrint("\n---------------- END -----------------\n");
// STEP 4 - sort
selectionSort(M1_ptr, M1_N);
selectionSort(M2_ptr, M2_N);
debugPrint("\n--------------- STEP 4 ---------------\n");
outM(M1_ptr, M1_N, M2_ptr, M2_N);
debugPrint("\n---------------- END -----------------\n");
// STEP 5 - reduce
debugPrint("\n--------------- STEP 5 ---------------\n");
applyReduce(M2_ptr, M2_N);
debugPrint("\n---------------- END -----------------\n");
// Remember time of end and get out it
gettimeofday(&T2, NULL);
delta_ms = (T2.tv_sec - T1.tv_sec) * 1000 + (T2.tv_usec - T1.tv_usec) / 1000;
printf("\nN=%d. Milliseconds passed: %ld\n", N, delta_ms);
free(M1_ptr);
free(M2_ptr);
return 0;
}