Pannyx

devel

Request #08


~/devel/sleek
% cda
~/devel/proto/aej
% pp shuffle.c shuffle.h
#define SHUFFLE_C
#include <shuffle.h>

static void ruffle (int_t *);


static int_t m_items;
static int_t n_items;
static int_t n_takes;
static int_t * a_hands;
static int_t n_taken;

static int_t perms [] = {
   0, 1, 2, 3,  0, 1, 3, 2,  0, 2, 1, 3,  0, 2, 3, 1,  0, 3, 1, 2,  0, 3, 2, 1,
   1, 0, 2, 3,  1, 0, 3, 2,  1, 2, 0, 3,  1, 2, 3, 0,  1, 3, 0, 2,  1, 3, 2, 0,
   2, 0, 1, 3,  2, 0, 3, 1,  2, 1, 0, 3,  2, 1, 3, 0,  2, 3, 0, 1,  2, 3, 1, 0,
   3, 0, 1, 2,  3, 0, 2, 1,  3, 1, 0, 2,  3, 1, 2, 0,  3, 2, 0, 1,  3, 2, 1, 0,
};

void
open_shuffle (int_t n, int_t m)
{

   srand(rseed());
   if (!( n == 0)) { n_items = (n + 3) / 4 * 4; } else { n_items = 32; }
   if (!( m == 0)) { n_takes = m; } else { n_takes = 36; }
   m_items = n_items + 6;
   if (( a_hands = malloc(m_items * sizeof (int_t) * 5 )) == NULL) { ouch(); return; }

   wrap(n_takes);
   return;
}

void
close_shuffle (void) {
      free(a_hands); a_hands = NULL; n_taken = 0;
      return; }

void
wrap (int_t n)
{
   int_t k;

   if (a_hands == NULL) { n_taken = n_takes; return; }

   k = 1;
   while (k < 5) {
      ruffle(& a_hands[k * m_items]);
      k += 1;
   }
   n_takes = n;
   n_taken = 0;
   return;

}

static void
ruffle (int_t * a)
{
   int_t j; int_t k;
   int_t b [n_items];

   k = 0; while (k < n_items) { b[k] = k; k += 1; }
   k = 0;
   while (k < n_items) {
      j = rand() % n_items;
      while (n_items - 1 < b[j]) {
         j += 1; j %= n_items;
      }
      a[k] = b[j];
      b[j] = int_c( 0x800000000000);
      k += 1;
   }
   return;
}

int_t *
take (void)
{
   int_t * a; int_t k; int_t l;
   int_t * p;

   if (n_takes - 1 < n_taken) { return NULL; }

   a = & a_hands[(n_taken % 5) * m_items];
   if (n_taken % 7 == 0) { ruffle(a); }
   k = 0; while (k < 6) { a[n_items + k] = a[k]; k += 1; }
   l = 0;
   while (l < n_items / 4) {
      p = & perms [rand() % 24 * 4];
      k = 0;
      while (k < 4) {
         a[l * 4 + k] = a[2 + (l + 1) * 4 + p[k]];
         k += 1;
      }
      l += 1;
   }
   n_taken += 1;
   return a;
}

// shuffle.c
#ifndef SHUFFLE_H
#define SHUFFLE_H
#include <daejana.h>

#ifndef SHUFFLE_C
#endif

void open_shuffle (int_t, int_t);
void close_shuffle (void);

void wrap (int_t);
int_t * take (void);

#endif
// shuffle.h
% cdm
~/devel/sleek
% pp shuffle_m.c
#include <chars.h>
#include <shuffle.h>

#define S_ITEMS "n_items"
#define S_TAKES "n_takes"
#define N_PAD 8192
char s_pad [N_PAD];


int
main (int argc, char * argv [])
{
   int_t k; char * s; char c;
   int_t n_items;
   int_t n_takes;
   int_t m_items;
   int_t * v;

   error_flag = false;
   printf("\n");
   if (argc < 2) {
      snprintf(s_pad, N_PAD, "%s : %s\x08", S_ITEMS, s_ellipsis); fputs(s_pad, stdout); fflush(stdout);
      while ((c = getchar()) == ' ' || c == '\t' || c == '\n') { if (c == '\n') { n_items = 0; fputs("\x1b[1A", stdout); goto L1; } }
      k = 0; while (!( c == '\n')) { s_pad[k] = c; c = getchar(); k += 1; } s_pad[k] = '\0';
      n_items = atoll(s_pad);
      fputs("\x1b[1A", stdout);
   }
   else {
      s = argv[1];
      k = 0; while ((c = s[k]) == ' ' || c == '\t') { k += 1; }
      if ('0' < c && c < '9' + 1) {
         n_items = atoll(&s[k]);
      }
      else if (c == '0') {
         if (s[k+1] == 'x' || s[k+1] == 'X') { n_items = strtoll(&s[k], NULL, 16); } else { n_items = 0; if (!( c == '\0' || c == ' ' || c ==
   ↪ '\t')) { ouch(); } }
      }
      else {
         n_items = 0; ouch();
      }
   }
L1:
   if (n_items == 0) { n_items = 32; }
   printf("%s %s %lld\n", S_ITEMS, s_left, n_items);
   if (argc < 3) {
      snprintf(s_pad, N_PAD, "%s : %s\x08", S_TAKES, s_ellipsis); fputs(s_pad, stdout); fflush(stdout);
      while ((c = getchar()) == ' ' || c == '\t' || c == '\n') { if (c == '\n') { n_takes = 0; fputs("\x1b[1A", stdout); goto L2; } }
      k = 0; while (!( c == '\n')) { s_pad[k] = c; c = getchar(); k += 1; } s_pad[k] = '\0';
      n_takes = atoll(s_pad);
      fputs("\x1b[1A", stdout);
   }
   else {
      s = argv[2];
      k = 0; while ((c = s[k]) == ' ' || c == '\t') { k += 1; }
      if ('0' < c && c < '9' + 1) {
         n_takes = atoll(&s[k]);
      }
      else if (c == '0') {
         if (s[k+1] == 'x' || s[k+1] == 'X') { n_takes = strtoll(&s[k], NULL, 16); } else { n_takes = 0; if (!( c == '\0' || c == ' ' || c ==
   ↪ '\t')) { ouch(); } }
      }
      else {
         n_takes = 0; ouch();
      }
   }
L2:
   if (n_takes == 0) { n_takes = 36; }
   printf("%s %s %lld\n", S_TAKES, s_left, n_takes);
   printf("\n");
   open_shuffle(n_items, n_takes, & m_items);
   assert(n_items == m_items);
   printf("(\n"); while (!( (v = take()) == NULL)) { printf("   ["); k = 0; while (k < n_items) { printf(" %2lld,", v[k]); k += 1; } printf(" ];\n"); }
   ↪ printf(")\n");
   close_shuffle();
   printf("\n");
   if (error_flag) { exit(EXIT_FAILURE); }

   return EXIT_SUCCESS;

}

// shuffle_m.c
% cmr shuffle_m chars shuffle

n_items ← 32
n_takes ← 36

(
   [ 10, 24, 14, 29, 28, 27, 11, 12, 31, 23,  3, 20,  5,  1, 19, 13, 25, 30, 15, 16,  6, 22,  2, 21,  8,  4, 17,  7, 26,  0, 18,  9, ];
   [ 19,  9,  3,  2, 20,  4,  1, 28, 21, 11,  5, 27, 30, 23, 22, 10,  8, 24, 31, 12, 25,  6, 15, 13, 18, 29,  7, 26, 17, 14, 16,  0, ];
   [ 23,  8, 22, 16, 30, 29, 31, 24,  1,  2,  3, 26,  5,  4,  6,  9, 11,  7, 17, 10, 12, 14, 13, 15, 28, 27, 18, 19, 20, 21,  0, 25, ];
   …
   [ 13, 24, 23, 25,  4,  0, 14, 26,  5, 30, 20, 27, 15, 19, 29,  1,  7, 16,  2, 17, 12, 10, 21,  9, 11,  3, 22,  6, 31, 28, 18,  8, ];
   [ 14, 18, 11, 16,  3, 31, 15, 27, 22, 26, 20, 25,  6, 17,  4, 10, 28, 29, 30, 23, 24,  2,  7,  0,  9,  1, 12,  5,  8, 21, 13, 19, ];
   [ 13, 15, 22,  8, 10, 16,  1, 14, 18, 30,  2,  5, 12, 20, 11,  3, 21,  7, 23, 17, 27, 28, 26, 19,  0, 24,  9, 31, 25,  4, 29,  6, ];
)

%