Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <ctype.h>
- #include <stdbool.h>
- #include <stddef.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <time.h>
- typedef char object;
- typedef struct {
- object kind;
- } nut;
- typedef struct {
- object kind;
- } bolt;
- typedef enum {
- NUT, BOLT
- } screw;
- typedef struct {
- screw type;
- union {
- nut *n;
- bolt *b;
- } val;
- } nutbolt;
- typedef struct {
- size_t i, j, match;
- } sort_status;
- static nutbolt *new_nutbolt(screw, object);
- static size_t size_serial(const object, const object);
- static int random_int_range(int, int);
- static void shuffle_nutbolt(nutbolt **, size_t);
- static nutbolt **init_nutbolt(screw, object, object);
- static object next_object(object);
- static void sort_nutbolt(nutbolt **, nutbolt **, size_t, size_t);
- static sort_status *partition(nutbolt **, nutbolt *, size_t, size_t);
- static void swap_nutbolt(nutbolt **, nutbolt **);
- static int compare_nutbolt(nutbolt *, nutbolt *);
- static int compare_object(object, object);
- static void print_nutbolt(nutbolt **, size_t);
- static void free_nutbolt(nutbolt **, size_t);
- int main(void) {
- nutbolt **nuts = init_nutbolt(NUT, 'A', 'Z');
- nutbolt **bolts = init_nutbolt(BOLT, 'a', 'z');
- size_t size = size_serial('A', 'Z');
- print_nutbolt(nuts, size);
- print_nutbolt(bolts, size);
- sort_nutbolt(nuts, bolts, 0, size - 1);
- print_nutbolt(nuts, size);
- print_nutbolt(bolts, size);
- free_nutbolt(nuts, size);
- free_nutbolt(bolts, size);
- }
- static nutbolt *new_nutbolt(screw type, object o) {
- nutbolt *new = calloc(1, sizeof(new));
- new->type = type;
- if (type == NUT) {
- new->val.n = calloc(1, sizeof(new->val.n));
- new->val.n->kind = o;
- } else {
- new->val.b = calloc(1, sizeof(new->val.b));
- new->val.b->kind = o;
- }
- return new;
- }
- static size_t size_serial(const object start, const object end) {
- return (char) end - (char) start + 1;
- }
- static int random_int_range(int lower, int upper) {
- static bool first = true;
- if (first) {
- srand(time(NULL));
- first = false;
- }
- return lower + rand() % (upper - lower + 1);
- }
- static void shuffle_nutbolt(nutbolt **nb, size_t size) {
- for (size_t i = size - 1; i > 0; --i) {
- size_t j = random_int_range(0, i);
- nutbolt *temp = nb[i];
- nb[i] = nb[j];
- nb[j] = temp;
- }
- }
- static nutbolt **init_nutbolt(screw type, object begin, object end) {
- size_t size = size_serial(begin, end);
- nutbolt **new = calloc(size, sizeof(new));
- object o = begin;
- for (size_t i = 0; i < size; ++i, o = next_object(o)) {
- new[i] = new_nutbolt(type, o);
- }
- shuffle_nutbolt(new, size);
- return new;
- }
- static object next_object(object o) {
- return o + 1;
- }
- static void sort_nutbolt(nutbolt **nuts, nutbolt **bolts, size_t left, size_t right) {
- if (left >= right) {
- return;
- }
- nutbolt *pivot = bolts[random_int_range(left, right)];
- sort_status *st = partition(nuts, pivot, left, right);
- sort_status *dummy = partition(bolts, nuts[st->match], left, right);
- free(dummy);
- sort_nutbolt(nuts, bolts, left, st->i - 1);
- sort_nutbolt(nuts, bolts, st->j + 1, right);
- free(st);
- }
- static sort_status *partition(nutbolt **nb, nutbolt *p, size_t l, size_t r) {
- size_t i = l, j = r;
- int match = -1, cmp1, cmp2;
- while (true) {
- while (i <= r && (cmp1 = compare_nutbolt(nb[i], p)) <= 0) {
- if (cmp1 == 0) {
- match = i;
- }
- ++i;
- }
- while ((cmp2 = compare_nutbolt(nb[j], p)) > 0) {
- --j;
- }
- if (i >= j) {
- if (cmp2 == 0) {
- match = j;
- }
- break;
- }
- swap_nutbolt(&nb[i], &nb[j]);
- if (cmp2 == 0) {
- match = i;
- }
- ++i;
- --j;
- }
- sort_status *st = calloc(1, sizeof(st));
- st->i = i;
- st->j = j;
- st->match = match;
- return st;
- }
- static void swap_nutbolt(nutbolt **v1, nutbolt **v2) {
- nutbolt *t = *v1;
- *v1 = *v2;
- *v2 = t;
- }
- static int compare_nutbolt(nutbolt *v1, nutbolt *v2) {
- if (v1->type == NUT) {
- return compare_object(v1->val.n->kind, v2->val.b->kind);
- }
- return compare_object(v1->val.b->kind, v2->val.n->kind);
- }
- static int compare_object(object o1, object o2) {
- int diff = 'A' - 'a';
- if (isupper(o1)) {
- diff = -diff;
- }
- return o1 + diff - o2;
- }
- static void print_nutbolt(nutbolt **nb, size_t size) {
- if (nb[0]->type == NUT) {
- for (size_t i = 0; i < size; ++i) {
- printf("%c", nb[i]->val.n->kind);
- }
- } else {
- for (size_t i = 0; i < size; ++i) {
- printf("%c", nb[i]->val.b->kind);
- }
- }
- puts("");
- }
- static void free_nutbolt(nutbolt **nb, size_t size) {
- for (size_t i = 0; i < size; ++i) {
- free(nb[i]);
- }
- free(nb);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement