Skip to content

Instantly share code, notes, and snippets.

@polymorphm
Last active November 6, 2018 17:36
Show Gist options
  • Save polymorphm/2f362d2462a6390e718b9e4383ebcda1 to your computer and use it in GitHub Desktop.
Save polymorphm/2f362d2462a6390e718b9e4383ebcda1 to your computer and use it in GitHub Desktop.
simple bubble sorting of vectors (by their length). just for test
// 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