4-variable-simplifier/spikes/boolean-array-or-2.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;
}