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, ];
)
%