<tb@panthema.net>
<http://www.gnu.org/licenses/>
class PermutationCheck
{
private:
mpz_class v;
size_t iter;
public:
PermutationCheck() : v(0), iter(0) {}
PermutationCheck(const membuffer<unsigned char*>& stringptr)
{
mpz_class p("18446744073709551557", 10);
for (iter = 1; iter < 100000; ++iter)
{
uint64_t z = (uint64_t)g_string_data + g_string_datasize + iter;
v = 1;
for (size_t i = 0; i < stringptr.size(); ++i)
{
assert(z >= (uint64_t)stringptr[i]);
v *= (z - (uint64_t)stringptr[i]);
v %= p;
}
if (v != 0) break;
std::cout << "PermutationCheck: evaluation returned zero, repeating.\n";
}
}
bool check(const membuffer<unsigned char*>& stringptr) const
{
mpz_class p("18446744073709551557", 10);
uint64_t z = (uint64_t)g_string_data + g_string_datasize + iter;
mpz_class w = 1;
for (size_t i = 0; i < stringptr.size(); ++i)
{
assert(z >= (uint64_t)stringptr[i]);
w *= (z - (uint64_t)stringptr[i]);
w %= p;
}
return (v == w);
}
};
class PermutationCheck64
{
private:
static const uint64_t p = 4294967291;
uint64_t v;
size_t iter;
public:
PermutationCheck64(const membuffer<unsigned char*>& stringptr)
{
for (iter = 1; iter < 100000; ++iter)
{
uint64_t z = (uint64_t)g_string_data + g_string_datasize + iter;
v = 1;
for (size_t i = 0; i < stringptr.size(); ++i)
{
assert(z >= (uint64_t)stringptr[i]);
v *= (z - (uint64_t)stringptr[i]);
v %= p;
}
if (v != 0) return;
std::cout << "PermutationCheck: evaluation returned zero, repeating.\n";
}
}
bool check(const membuffer<unsigned char*>& stringptr) const
{
uint64_t z = (uint64_t)g_string_data + g_string_datasize + iter;
uint64_t w = 1;
for (size_t i = 0; i < stringptr.size(); ++i)
{
assert(z >= (uint64_t)stringptr[i]);
w *= (z - (uint64_t)stringptr[i]);
w %= p;
}
return (v == w);
}
};
bool check_sorted_order(const membuffer<unsigned char*>& stringptr, const PermutationCheck& pc)
{
if (!pc.check(stringptr))
{
std::cout << "error: not a permutation\n";
}
for (size_t i = 1; i < stringptr.size(); ++i)
{
if (strcmp((const char*)stringptr[i-1], (const char*)stringptr[i]) > 0)
{
std::cout << "error: invalid order at pair " << i-1 << " and " << i << "\n";
return false;
}
}
return true;
}
size_t calc_distinguishing_prefix(const membuffer<unsigned char*>& stringptr, size_t& lcpsum)
{
size_t D = 0;
size_t pdepth = 0;
for (size_t i = 1; i < stringptr.size(); ++i)
{
size_t depth = 0;
while ( stringptr[i-1][depth] == stringptr[i][depth] &&
stringptr[i-1][depth] != 0 ) ++depth;
lcpsum += depth;
depth++;
if (pdepth < depth) {
D += depth - pdepth;
}
D += depth;
pdepth = depth;
}
return D;
}