Last active
November 6, 2018 17:36
-
-
Save polymorphm/2f362d2462a6390e718b9e4383ebcda1 to your computer and use it in GitHub Desktop.
simple bubble sorting of vectors (by their length). just for test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// to compile: | |
// gcc -Wall -Wextra -O3 -funsafe-math-optimizations -o bubble-lab bubble-lab.c | |
// or | |
// gcc -Wall -Wextra -O3 -funsafe-math-optimizations -DCANNOT_RANDOM -o bubble-lab bubble-lab.c | |
#include <stdlib.h> | |
#include <stdio.h> | |
#include <string.h> | |
#ifndef CANNOT_RANDOM | |
#include <sys/random.h> | |
#endif | |
#define VECTOR_SIZE 16 | |
#define RANDOM_FLOAT_QUALITY 10 | |
typedef float float_vector[VECTOR_SIZE]; | |
#ifndef CANNOT_RANDOM | |
static | |
float | |
getrandom_float () | |
{ | |
float frnd = 0; | |
for (int i = 0; i < RANDOM_FLOAT_QUALITY; ++i) | |
{ | |
unsigned short rnd[4]; | |
for (;;) | |
{ | |
int rnd_len = getrandom (rnd, sizeof (rnd), 0); | |
if (rnd_len != sizeof (rnd)) | |
{ | |
if (rnd_len == -1) | |
{ | |
fprintf(stderr, "failure getrandom()\n"); | |
abort(); | |
} | |
fprintf(stderr, "retrying getrandom()\n"); | |
continue; | |
} | |
break; | |
} | |
frnd += (float) rnd[0] / rnd[1]; | |
frnd -= (float) rnd[2] / rnd[3]; | |
} | |
return frnd; | |
} | |
static int | |
make_cmd (const char *out_path, const char *count_str) | |
{ | |
int count = atoi (count_str); | |
FILE *fout = fopen (out_path, "w"); | |
if (!fout) | |
{ | |
fprintf (stderr, "%s: failure opening file\n", out_path); | |
return 1; | |
} | |
for (int i = 0; i < count; ++i) | |
{ | |
for (int j = 0; j < VECTOR_SIZE; ++j) | |
{ | |
float item = getrandom_float (); | |
if (j) fputc (' ', fout); | |
fprintf (fout, "%f", item); | |
} | |
fputc ('\n', fout); | |
} | |
fclose (fout); | |
return 0; | |
} | |
#endif | |
static inline float | |
calculate_vec_len (float_vector vector) | |
{ | |
float len = 0; | |
for (int j = 0; j < VECTOR_SIZE; ++j) | |
{ | |
len += vector[j] * vector[j]; | |
} | |
return len; | |
} | |
static int | |
sort_cmd (const char *in_path, const char *out_path, const char *count_str, | |
int noop) | |
{ | |
int rv = 0; | |
int count = atoi (count_str); | |
float_vector *vectors = calloc (count, sizeof (float_vector)); | |
FILE *fin = fopen (in_path, "r"); | |
FILE *fout = fopen (out_path, "w"); | |
if (!vectors) | |
{ | |
fprintf (stderr, "%s: failure calloc()\n", in_path); | |
rv = 1; | |
goto out; | |
} | |
if (!fin) | |
{ | |
fprintf (stderr, "%s: failure opening file\n", in_path); | |
rv = 1; | |
goto out; | |
} | |
if (!fout) | |
{ | |
fprintf (stderr, "%s: failure opening file\n", out_path); | |
rv = 1; | |
goto out; | |
} | |
float_vector vector; | |
int real_count = 0; | |
for (int i = 0; i < count; ++i) | |
{ | |
memset (vector, 0, sizeof (vector)); | |
for (int j = 0; j < VECTOR_SIZE; ++j) | |
{ | |
int scan_res = fscanf (fin, "%f", vector + j); | |
if (scan_res == EOF) goto read_loop_out; | |
} | |
++real_count; | |
memcpy (vectors[i], vector, sizeof (vector)); | |
} | |
read_loop_out: | |
if (!noop) | |
{ | |
for (int i = 0; i < real_count - 1; ++i) | |
{ | |
for (int k = i + 1; k < real_count; ++k) | |
{ | |
float vec_i_len = calculate_vec_len (vectors[i]); | |
float vec_k_len = calculate_vec_len (vectors[k]); | |
if (vec_i_len > vec_k_len) | |
{ | |
memcpy (vector, vectors[k], sizeof (vectors[k])); | |
memcpy (vectors[k], vectors[i], sizeof (vectors[i])); | |
memcpy (vectors[i], vector, sizeof (vector)); | |
} | |
} | |
} | |
} | |
for (int i = 0; i < real_count; ++i) | |
{ | |
//float vec_len = calculate_vec_len (vectors[i]); | |
//fprintf (fout, "%f: ", vec_len); | |
for (int j = 0; j < VECTOR_SIZE; ++j) | |
{ | |
if (j) fputc (' ', fout); | |
fprintf (fout, "%f", vectors[i][j]); | |
} | |
fputc ('\n', fout); | |
} | |
out: | |
if (fout) fclose (fout); | |
if (fin) fclose (fin); | |
free (vectors); | |
return rv; | |
} | |
int | |
main (int argc, char *argv[]) | |
{ | |
#ifndef CANNOT_RANDOM | |
if (argc == 4 && !strcmp ("make", argv[1])) | |
{ | |
return make_cmd (argv[2], argv[3]); | |
} | |
#endif | |
if (argc == 5 && !strcmp ("sort", argv[1])) | |
{ | |
return sort_cmd (argv[2], argv[3], argv[4], 0); | |
} | |
if (argc == 5 && !strcmp ("sort-noop", argv[1])) | |
{ | |
return sort_cmd (argv[2], argv[3], argv[4], 1); | |
} | |
fprintf (stderr, "invalid args\n"); | |
return 1; | |
} | |
// vi:ts=4:sw=4:et |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment