switched main over to using boolsets.
This commit is contained in:
parent
1097f2c2d8
commit
105e9306a4
7 changed files with 1635 additions and 456 deletions
5
.gitignore
vendored
5
.gitignore
vendored
|
|
@ -4,4 +4,9 @@ simplifications.bin
|
|||
.simplifier-*.bin
|
||||
|
||||
.direnv/
|
||||
|
||||
typescript
|
||||
|
||||
vgcore.*
|
||||
|
||||
*~
|
||||
|
|
|
|||
|
|
@ -0,0 +1,148 @@
|
|||
|
||||
#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;
|
||||
}
|
||||
|
||||
189
spikes/boolean-array-reverse-or.c
Normal file
189
spikes/boolean-array-reverse-or.c
Normal file
|
|
@ -0,0 +1,189 @@
|
|||
|
||||
#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;
|
||||
}
|
||||
|
||||
|
|
@ -11,36 +11,36 @@ struct boolist {
|
|||
int data[8][256];
|
||||
} list = {};
|
||||
|
||||
void insert(int e)
|
||||
void add(int e)
|
||||
{
|
||||
printf("insert(e = %i);\n", e);
|
||||
|
||||
|
||||
assert(!list.data[0][e]);
|
||||
|
||||
|
||||
for (int k = 0; k < 8 && !list.data[k][e >> k]++; k++);
|
||||
}
|
||||
|
||||
void delete(int e)
|
||||
void discard(int e)
|
||||
{
|
||||
printf("delete(e = %i);\n", e);
|
||||
|
||||
printf("discard(e = %i);\n", e);
|
||||
|
||||
assert(list.data[0][e]);
|
||||
|
||||
|
||||
for (int k = 0; k < 8 && !--list.data[k][e >> k]; k++);
|
||||
}
|
||||
|
||||
void print()
|
||||
{
|
||||
puts("print():");
|
||||
|
||||
|
||||
void walk(int k, int i)
|
||||
{
|
||||
if (k >= 0)
|
||||
{
|
||||
int* a = &list.data[k][i >> k];
|
||||
|
||||
|
||||
if (a[0]) walk(k - 1, i);
|
||||
|
||||
|
||||
if (a[1]) walk(k - 1, i + (1 << k));
|
||||
}
|
||||
else
|
||||
|
|
@ -48,42 +48,42 @@ void print()
|
|||
printf(" " "%i\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
walk(7, 0);
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
print();
|
||||
|
||||
insert(42);
|
||||
|
||||
|
||||
add(42);
|
||||
|
||||
print();
|
||||
|
||||
insert(101);
|
||||
|
||||
|
||||
add(101);
|
||||
|
||||
print();
|
||||
|
||||
delete(42);
|
||||
|
||||
|
||||
discard(42);
|
||||
|
||||
print();
|
||||
|
||||
insert(34);
|
||||
|
||||
|
||||
add(34);
|
||||
|
||||
print();
|
||||
|
||||
insert(35);
|
||||
|
||||
|
||||
add(35);
|
||||
|
||||
print();
|
||||
|
||||
insert(36);
|
||||
|
||||
|
||||
add(36);
|
||||
|
||||
print();
|
||||
|
||||
delete(35);
|
||||
|
||||
|
||||
discard(35);
|
||||
|
||||
print();
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ void search(
|
|||
else
|
||||
{
|
||||
assert((ai | bi) == findme);
|
||||
|
||||
|
||||
printf("0b%04b | 0b%04b == 0b%04b "
|
||||
"(%2i | %2i == %2i)\n", ai, bi, findme, ai, bi, findme);
|
||||
}
|
||||
|
|
@ -32,6 +32,6 @@ void search(
|
|||
int main()
|
||||
{
|
||||
search(0b1000, 0, 0, 11);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,13 +43,13 @@ int binary(
|
|||
while (n > 1)
|
||||
{
|
||||
int m = n / 2;
|
||||
|
||||
|
||||
if (array[i + m] & mask)
|
||||
n = m;
|
||||
else
|
||||
i += m, n = n - m;
|
||||
}
|
||||
|
||||
|
||||
return (array[i] & mask) ? i : i + 1;
|
||||
}
|
||||
|
||||
|
|
@ -61,32 +61,32 @@ void search(
|
|||
int calldepth)
|
||||
{
|
||||
zprintf("%*s" "search():" "\n", calldepth++, "");
|
||||
|
||||
|
||||
zprintf("%*s" "mask = 0b%05b" "\n", calldepth, "", mask);
|
||||
|
||||
|
||||
zprintf("%*s" "findme = 0b%05b" "\n", calldepth, "", findme);
|
||||
|
||||
|
||||
zprintf("%*s" "ai = %i" "\n", calldepth, "", ai);
|
||||
zprintf("%*s" "an = %i" "\n", calldepth, "", an);
|
||||
|
||||
|
||||
zprintf("%*s" "bi = %i" "\n", calldepth, "", bi);
|
||||
zprintf("%*s" "bn = %i" "\n", calldepth, "", bn);
|
||||
|
||||
|
||||
if (mask)
|
||||
{
|
||||
int asplit = binary(mask, a + ai, 0, an);
|
||||
int bsplit = binary(mask, b + bi, 0, bn);
|
||||
|
||||
|
||||
zprintf("%*s" "asplit = %i" "\n", calldepth, "", asplit);
|
||||
zprintf("%*s" "bsplit = %i" "\n", calldepth, "", bsplit);
|
||||
|
||||
|
||||
assert((asplit == an) || (a[ai + asplit] & mask));
|
||||
assert((bsplit == bn) || (b[bi + bsplit] & mask));
|
||||
|
||||
|
||||
if (mask & findme)
|
||||
{
|
||||
zprintf("%*s" "one path" "\n", calldepth, "");
|
||||
|
||||
|
||||
// 0 ... (asplit - 1) | asplit ... (an - 1)
|
||||
// --------------------- -------------------
|
||||
// 0 | | |
|
||||
|
|
@ -98,12 +98,12 @@ void search(
|
|||
// (bn - 1) | | |
|
||||
// --- | | |
|
||||
// ---------------------- -------------------
|
||||
|
||||
|
||||
// second quadrant.
|
||||
if (asplit < an && 0 < bsplit)
|
||||
{
|
||||
zprintf("%*s" "entering second quadrant." "\n", calldepth, "");
|
||||
|
||||
|
||||
search(
|
||||
mask >> 1,
|
||||
ai + asplit, an - asplit,
|
||||
|
|
@ -115,12 +115,12 @@ void search(
|
|||
{
|
||||
zprintf("%*s" "empty second quadrant." "\n", calldepth, "");
|
||||
}
|
||||
|
||||
|
||||
// third quadrant.
|
||||
if (0 < asplit && bsplit < bn)
|
||||
{
|
||||
zprintf("%*s" "entering third quadrant." "\n", calldepth, "");
|
||||
|
||||
|
||||
search(
|
||||
mask >> 1,
|
||||
ai, asplit,
|
||||
|
|
@ -132,12 +132,12 @@ void search(
|
|||
{
|
||||
zprintf("%*s" "empty third quadrant." "\n", calldepth, "");
|
||||
}
|
||||
|
||||
|
||||
// fourth quadrant.
|
||||
if (asplit < an && bsplit < bn)
|
||||
{
|
||||
zprintf("%*s" "entering fourth quadrant." "\n", calldepth, "");
|
||||
|
||||
|
||||
search(
|
||||
mask >> 1,
|
||||
ai + asplit, an - asplit,
|
||||
|
|
@ -153,12 +153,12 @@ void search(
|
|||
else
|
||||
{
|
||||
zprintf("%*s" "zero path" "\n", calldepth, "");
|
||||
|
||||
|
||||
// first quadrant.
|
||||
if (0 < asplit && 0 < bsplit)
|
||||
{
|
||||
zprintf("%*s" "entering first quadrant." "\n", calldepth, "");
|
||||
|
||||
|
||||
search(
|
||||
mask >> 1,
|
||||
ai, asplit,
|
||||
|
|
@ -177,7 +177,7 @@ void search(
|
|||
for (int j = 0; j < bn; j++)
|
||||
{
|
||||
assert((a[ai + i] | b[bi + j]) == findme);
|
||||
|
||||
|
||||
printf("%2i [%2i] (0b%05b) | %2i [%2i] "
|
||||
"(0b%05b) == %2i (0b%05b)" "\n",
|
||||
a[ai + i], ai + i, a[ai + i],
|
||||
|
|
@ -185,7 +185,7 @@ void search(
|
|||
findme, findme);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
calldepth--;
|
||||
}
|
||||
|
||||
|
|
@ -197,7 +197,7 @@ int main()
|
|||
0, 10,
|
||||
23,
|
||||
0);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue