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