148 lines
3.7 KiB
C
148 lines
3.7 KiB
C
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
|
|
#ifdef ZDEBUG
|
|
#define zprintf(fmt, ...) printf(fmt, ## __VA_ARGS__);
|
|
#else
|
|
#define zprintf(...) ;
|
|
#endif
|
|
|
|
#define N (256)
|
|
|
|
#define M (255)
|
|
|
|
struct boolist
|
|
{
|
|
int data[8][256];
|
|
};
|
|
|
|
void init(struct boolist* this)
|
|
{
|
|
memset(this, 0, sizeof(*this));
|
|
}
|
|
|
|
void add(struct boolist* this, int e)
|
|
{
|
|
zprintf("insert(e = %i);\n", e);
|
|
|
|
if (!this->data[0][e])
|
|
{
|
|
for (int k = 0; k < 8 && !this->data[k][e >> k]++; k++);
|
|
}
|
|
}
|
|
|
|
void search(
|
|
struct boolist* alist,
|
|
struct boolist* blist,
|
|
int k,
|
|
int ai, int bi,
|
|
int findme,
|
|
int calldepth)
|
|
{
|
|
zprintf("%*s" "search(k = %i, ai = %#b, bi = %#b, findme = %#b):" "\n", calldepth++, "", k, ai, bi, findme);
|
|
|
|
if (k >= 0)
|
|
{
|
|
// x | y | z
|
|
//-----------
|
|
// 0 | 0 | 0
|
|
// 0 | 1 | 1
|
|
// 1 | 0 | 1
|
|
// 1 | 1 | 1
|
|
|
|
if (findme & (1 << k))
|
|
{
|
|
// there are three cases that would make 'z' one:
|
|
zprintf("%*s" "one case" "\n", calldepth, "");
|
|
|
|
// x is 0 and y is 1:
|
|
if (alist->data[k][(ai >> k) + 0] && blist->data[k][(bi >> k) + 1])
|
|
{
|
|
search(alist, blist, k - 1, ai, bi + (1 << k), findme, calldepth);
|
|
}
|
|
|
|
// x is 1 and y is 0:
|
|
if (alist->data[k][(ai >> k) + 1] && blist->data[k][(bi >> k) + 0])
|
|
{
|
|
search(alist, blist, k - 1, ai + (1 << k), bi, findme, calldepth);
|
|
}
|
|
|
|
// x is 1 and y is 1:
|
|
if (alist->data[k][(ai >> k) + 1] && blist->data[k][(bi >> k) + 1])
|
|
{
|
|
search(alist, blist, k - 1, ai + (1 << k), bi + (1 << k), findme, calldepth);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
zprintf("%*s" "zero case" "\n", calldepth, "");
|
|
|
|
// there's only one case when 'z' is zero: 'x' and 'y' both
|
|
// must be zero.
|
|
|
|
// check that both corrasponding quadrants are not empty first.
|
|
if (alist->data[k][(ai >> k) + 0] && blist->data[k][(bi >> k) + 0])
|
|
{
|
|
search(alist, blist, k - 1, ai, bi, findme, calldepth);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
assert((ai | bi) == findme);
|
|
|
|
printf("%2i (0b%05b) | %2i (0b%05b) == %2i (0b%05b)" "\n",
|
|
ai, ai, bi, bi, findme, findme);
|
|
}
|
|
}
|
|
|
|
// 0 1 2 3 4 5 6 7 8 9
|
|
int a[10] = { 2, 4, 5, 7, 9, 11, 15, 17, 17, 19};
|
|
int b[10] = {10, 11, 11, 14, 14, 19, 20, 23, 26, 29};
|
|
|
|
// [ 0] [ 1] [ 2] [ 3] [ 4] [ 5] [ 6] [ 7] [ 8] [ 9]
|
|
// 2 4 5 7 9 11 15 17 17 19
|
|
// --------------------------------------------------
|
|
// [ 0] 10 | 10 14 15 15 11 11 15 27 27 27
|
|
|
|
// [ 1] 11 | 11 15 15 15 11 11 15 27 27 27
|
|
|
|
// [ 2] 11 | 11 15 15 15 11 11 15 27 27 27
|
|
|
|
// [ 3] 14 | 14 14 15 15 15 15 15 31 31 31
|
|
|
|
// [ 4] 14 | 14 14 15 15 15 15 15 31 31 31
|
|
|
|
// [ 5] 19 | 19 (23) (23) (23) 27 27 31 19 19 19
|
|
|
|
// [ 6] 20 | 22 20 21 (23) 29 31 31 21 21 (23)
|
|
|
|
// [ 7](23)|(23) (23) (23) (23) 31 31 31 (23) (23) (23)
|
|
|
|
// [ 8] 26 | 26 30 31 31 27 27 31 27 27 27
|
|
|
|
// [ 9] 29 | 31 29 29 31 29 31 31 29 29 31
|
|
|
|
int main()
|
|
{
|
|
struct boolist alist, blist;
|
|
|
|
init(&alist), init(&blist);
|
|
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
add(&alist, a[i]);
|
|
}
|
|
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
add(&blist, b[i]);
|
|
}
|
|
|
|
search(&alist, &blist, 7, 0, 0, 23, 0);
|
|
|
|
return 0;
|
|
}
|
|
|