189 lines
4.6 KiB
C
189 lines
4.6 KiB
C
|
|
#include <stdio.h>
|
|
#include <assert.h>
|
|
#include <string.h>
|
|
#include <stdbool.h>
|
|
|
|
#ifdef ZDEBUG
|
|
#define zprintf(fmt, ...) printf(fmt, ## __VA_ARGS__);
|
|
#else
|
|
#define zprintf(...) ;
|
|
#endif
|
|
|
|
#define TODO \
|
|
assert(!"TODO");
|
|
|
|
#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(
|
|
int a,
|
|
struct boolist* blist,
|
|
struct boolist* clist,
|
|
int k,
|
|
int bi, int ci,
|
|
int calldepth)
|
|
{
|
|
zprintf("%*s" "search(k = %i, bi = %#b, ci = %#b):" "\n",
|
|
calldepth++, "", k, bi, ci);
|
|
|
|
if (k >= 0)
|
|
{
|
|
// a | b | c
|
|
//-----------
|
|
// 0 | 0 | 0
|
|
// 0 | 1 | 1
|
|
// 1 | 0 | 1
|
|
// 1 | 1 | 1
|
|
|
|
if (a & (1 << k))
|
|
{
|
|
// there are three cases that would make 'z' one:
|
|
zprintf("%*s" "one case" "\n", calldepth, "");
|
|
|
|
// if the left operand is providing the one-ness, then the right
|
|
// operand can be whatever it wants, and the resultant must be one
|
|
|
|
// b == 0 and c == 1
|
|
if (blist->data[k][(bi >> k) + 0] && clist->data[k][(ci >> k) + 1])
|
|
{
|
|
search(a, blist, clist, k - 1, bi, ci + (1 << k), calldepth);
|
|
}
|
|
|
|
// b == 1 and c == 1
|
|
if (blist->data[k][(bi >> k) + 1] && clist->data[k][(ci >> k) + 1])
|
|
{
|
|
search(a, blist, clist, k - 1, bi + (1 << k), ci + (1 << k), calldepth);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
zprintf("%*s" "zero case" "\n", calldepth, "");
|
|
|
|
// there two cases to consider then. If the left operand
|
|
// is not providing the one-ness, then it's up to the right operand
|
|
// to provide it if it's needed.
|
|
|
|
// b == 0 and c == 0
|
|
if (blist->data[k][(bi >> k) + 0] && clist->data[k][(ci >> k) + 0])
|
|
{
|
|
search(a, blist, clist, k - 1, bi, ci, calldepth);
|
|
}
|
|
|
|
// b == 1 and c == 1
|
|
if (blist->data[k][(bi >> k) + 1] && clist->data[k][(ci >> k) + 1])
|
|
{
|
|
search(a, blist, clist, k - 1, bi + (1 << k), ci + (1 << k), calldepth);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
printf("%2i (0b%05b) | %2i (0b%05b) == %2i (0b%05b)" "\n",
|
|
a, a, bi, bi, ci, ci);
|
|
|
|
assert((a | bi) == ci);
|
|
}
|
|
}
|
|
|
|
|
|
int a = 17;
|
|
|
|
// 0 1 2 3 4 5 6 7 8 9
|
|
int b[10] = {10, 11, 11, 14, 14, 19, 20, 23, 26, 29};
|
|
|
|
int c[20] = {
|
|
// 0 1 2 3 4 5 6 7 8 9
|
|
15, 17, 19, 21, 22, 25, 26, 26, 27, 32,
|
|
|
|
// 10 11 12 13 14 15 16 17 18 19
|
|
33, 33, 36, 39, 42, 44, 48, 49, 49, 49
|
|
};
|
|
|
|
// [ 0] [ 1] [ 2] [ 3] [ 4] [ 5] [ 6] [ 7] [ 8] [ 9]
|
|
// 10 11 11 14 14 19 20 23 26 29
|
|
// --------------------------------------------------
|
|
// [ 0] 15 | 5 4 4 1 1 12 11 8 5 2
|
|
|
|
// [ 1] 17 | 17 16 16 17 17 0 1 0 1 0
|
|
|
|
// [ 2] 19 | 17 16 16 17 17 (0) 3 0 1 2
|
|
|
|
// [ 3] 21 | 21 20 20 17 17 4 (1) 0 5 0
|
|
|
|
// [ 4] 22 | 20 20 20 16 16 4 2 0 4 2
|
|
|
|
// [ 5] 25 | 17 16 16 17 17 8 9 8 1 0
|
|
|
|
// [ 6] 26 | 16 16 16 16 16 8 10 8 0 2
|
|
|
|
// [ 7] 26 | 16 16 16 16 16 8 10 8 0 2
|
|
|
|
// [ 8] 27 |(17) (16) (16) 17 17 8 11 8 ( 1) 2
|
|
|
|
// [ 9] 32 | 32 32 32 32 32 32 32 32 32 32
|
|
|
|
// [10] 33 | 33 32 32 33 33 32 33 32 33 32
|
|
|
|
// [11] 33 | 33 32 32 33 33 32 33 32 33 32
|
|
|
|
// [12] 36 | 36 36 36 32 32 36 32 32 36 32
|
|
|
|
// [13] 39 | 37 36 36 33 33 36 35 32 37 34
|
|
|
|
// [14] 42 | 32 32 32 32 32 40 42 40 32 34
|
|
|
|
// [15] 44 | 36 36 36 32 32 44 40 40 36 32
|
|
|
|
// [16] 48 | 48 48 48 48 48 32 32 32 32 32
|
|
|
|
// [17] 49 | 49 48 48 49 49 32 33 32 33 32
|
|
|
|
// [18] 49 | 49 48 48 49 49 32 33 32 33 32
|
|
|
|
// [19] 49 | 49 48 48 49 49 32 33 32 33 32
|
|
|
|
|
|
|
|
int main()
|
|
{
|
|
struct boolist blist, clist;
|
|
|
|
init(&blist), init(&clist);
|
|
|
|
for (int i = 0; i < 10; i++)
|
|
{
|
|
add(&blist, b[i]);
|
|
}
|
|
|
|
for (int i = 0; i < 20; i++)
|
|
{
|
|
add(&clist, c[i]);
|
|
}
|
|
|
|
search(a, &blist, &clist, 7, 0, 0, 0);
|
|
|
|
return 0;
|
|
}
|
|
|