85 lines
2.3 KiB
C++
85 lines
2.3 KiB
C++
|
|
#include <lib/lib.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
unsigned
|
|
unsigned_pack (unsigned n, unsigned x, unsigned z)
|
|
{
|
|
assert (n <= 32);
|
|
assert ((x >> n) == 0);
|
|
|
|
static const unsigned pack4[256] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1, 3, 5, 7, 9, 11, 13, 15, 1, 3, 5, 7, 9, 11, 13, 15, 2, 3, 6, 7, 10, 11, 14, 15, 2, 3, 6, 7, 10, 11, 14, 15, 3, 7, 11, 15, 3, 7, 11, 15, 3, 7, 11, 15, 3, 7, 11, 15, 4, 5, 6, 7, 12, 13, 14, 15, 4, 5, 6, 7, 12, 13, 14, 15, 5, 7, 13, 15, 5, 7, 13, 15, 5, 7, 13, 15, 5, 7, 13, 15, 6, 7, 14, 15, 6, 7, 14, 15, 6, 7, 14, 15, 6, 7, 14, 15, 7, 15, 7, 15, 7, 15, 7, 15, 7, 15, 7, 15, 7, 15, 7, 15, 8, 9, 10, 11, 12, 13, 14, 15, 8, 9, 10, 11, 12, 13, 14, 15, 9, 11, 13, 15, 9, 11, 13, 15, 9, 11, 13, 15, 9, 11, 13, 15, 10, 11, 14, 15, 10, 11, 14, 15, 10, 11, 14, 15, 10, 11, 14, 15, 11, 15, 11, 15, 11, 15, 11, 15, 11, 15, 11, 15, 11, 15, 11, 15, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 12, 13, 14, 15, 13, 15, 13, 15, 13, 15, 13, 15, 13, 15, 13, 15, 13, 15, 13, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 14, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, };
|
|
static const unsigned zerocount4[16] = {4, 3, 3, 2, 3, 2, 2, 1, 3, 2, 2, 1, 2, 1, 1, 0, };
|
|
|
|
unsigned r = 0;
|
|
for (unsigned i = 0; i < n; i += 4)
|
|
{
|
|
unsigned xnib = ((x >> i) & 0xf);
|
|
r |= pack4[(xnib << 4) | (z & 0xf)] << i;
|
|
z >>= zerocount4[xnib];
|
|
}
|
|
assert (z == 0);
|
|
return r;
|
|
}
|
|
|
|
void
|
|
stderror (const char *fmt, ...)
|
|
{
|
|
va_list ap;
|
|
va_start (ap, fmt);
|
|
|
|
vfprintf (stderr, fmt, ap);
|
|
|
|
fprintf (stderr, ": ");
|
|
perror (0);
|
|
|
|
va_end (ap);
|
|
}
|
|
|
|
unsigned
|
|
fact (unsigned n)
|
|
{
|
|
unsigned r = 1;
|
|
for (unsigned i = n; i >= 2; i --)
|
|
r *= i;
|
|
return r;
|
|
}
|
|
|
|
unsigned
|
|
choose (unsigned n, unsigned k)
|
|
{
|
|
if (n < k)
|
|
return 0;
|
|
|
|
unsigned r = 1;
|
|
for (unsigned i = n; i >= k + 1; i --)
|
|
r *= i;
|
|
|
|
unsigned d = fact (n - k);
|
|
assert (r % d == 0);
|
|
return r / d;
|
|
}
|
|
|
|
int
|
|
alpha_to_int (char c)
|
|
{
|
|
if ('a' <= c && c <= 'z')
|
|
return c - 'a' + 1;
|
|
else
|
|
{
|
|
assert ('A' <= c && c <= 'Z');
|
|
return - (c - 'A' + 1);
|
|
}
|
|
}
|
|
|
|
hash_t
|
|
hash (const std::string &s)
|
|
{
|
|
size_t n = s.length ();
|
|
hash_t h = hash (n);
|
|
for (unsigned i = 0; i < n; i ++)
|
|
h = hash_combine (h, hash (s[i]));
|
|
return h;
|
|
}
|