added more spikes about divide-and-conquer binary opeartions, changed over to using "done" list, changed cache encoding
This commit is contained in:
parent
d3ae35ceb5
commit
cb1738376d
12 changed files with 1816 additions and 161 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
|
@ -3,3 +3,5 @@ simplifications.bin
|
|||
|
||||
.simplifier-*.bin
|
||||
|
||||
.direnv/
|
||||
typescript
|
||||
|
|
|
|||
410
main.c
410
main.c
|
|
@ -182,7 +182,8 @@ static void parse_args(int argc, char* const* argv)
|
|||
#define N (65536)
|
||||
|
||||
enum kind {
|
||||
ek_undef,
|
||||
ek_unreachable,
|
||||
|
||||
ek_0,
|
||||
ek_1,
|
||||
ek_W,
|
||||
|
|
@ -215,11 +216,10 @@ struct expr {
|
|||
enum kind kind;
|
||||
|
||||
uint16_t cond, left, right;
|
||||
|
||||
int cost;
|
||||
} lookup[N];
|
||||
|
||||
// truthtable -> cost
|
||||
int costs[N] = {};
|
||||
|
||||
static void print(uint16_t truthtable, int depth)
|
||||
{
|
||||
#define LITERAL_ESCAPE "\e[38;2;200;200;100m"
|
||||
|
|
@ -243,10 +243,12 @@ static void print(uint16_t truthtable, int depth)
|
|||
|
||||
switch (e->kind)
|
||||
{
|
||||
case ek_undef:
|
||||
case ek_unreachable:
|
||||
{
|
||||
assert(!"NOPE");
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
case ek_0:
|
||||
{
|
||||
printf(print_with_color ? LITERAL_ESCAPE "0" RESET_ESCAPE : "0");
|
||||
|
|
@ -364,34 +366,46 @@ static void print(uint16_t truthtable, int depth)
|
|||
|
||||
void calculate_simplifications(void)
|
||||
{
|
||||
// heap of truthtables; key = cost
|
||||
uint16_t todo[N];
|
||||
int todo_n = 0;
|
||||
|
||||
// truthtable -> index in 'todo'
|
||||
int reverse[N];
|
||||
|
||||
// init:
|
||||
for (int i = 0; i < N; i++)
|
||||
// init 'lookup':
|
||||
{
|
||||
lookup[i].kind = ek_undef;
|
||||
|
||||
reverse[i] = -1;
|
||||
|
||||
costs[i] = INT_MAX;
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
lookup[i].kind = ek_unreachable;
|
||||
|
||||
lookup[i].cost = INT_MAX;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// heap of truthtables; key = cost
|
||||
struct {
|
||||
uint16_t data[N];
|
||||
int n;
|
||||
|
||||
// truthtable -> index in 'todo'
|
||||
int reverse[N];
|
||||
} todo;
|
||||
|
||||
// init 'todo':
|
||||
{
|
||||
todo.n = 0;
|
||||
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
todo.reverse[i] = -1;
|
||||
}
|
||||
}
|
||||
|
||||
uint16_t pop(void)
|
||||
{
|
||||
assert(todo_n > 0);
|
||||
assert(todo.n > 0);
|
||||
|
||||
uint16_t retval = todo[0];
|
||||
uint16_t retval = todo.data[0];
|
||||
|
||||
reverse[retval] = -1;
|
||||
todo.reverse[retval] = -1;
|
||||
|
||||
uint16_t moving = todo[todo_n-- - 1];
|
||||
uint16_t moving = todo.data[todo.n-- - 1];
|
||||
|
||||
int cost = costs[moving];
|
||||
int cost = lookup[moving].cost;
|
||||
|
||||
int index = 0;
|
||||
|
||||
|
|
@ -402,25 +416,25 @@ void calculate_simplifications(void)
|
|||
|
||||
uint16_t smallest = moving;
|
||||
|
||||
if (left < todo_n && costs[todo[left]] < cost)
|
||||
smallest = todo[left];
|
||||
if (left < todo.n && lookup[todo.data[left]].cost < cost)
|
||||
smallest = todo.data[left];
|
||||
|
||||
if (right < todo_n && costs[todo[right]] < costs[smallest])
|
||||
smallest = todo[right];
|
||||
if (right < todo.n && lookup[todo.data[right]].cost < lookup[smallest].cost)
|
||||
smallest = todo.data[right];
|
||||
|
||||
if (smallest == moving)
|
||||
{
|
||||
todo[index] = moving;
|
||||
todo.data[index] = moving;
|
||||
|
||||
reverse[moving] = index;
|
||||
todo.reverse[moving] = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
int new = reverse[smallest];
|
||||
int new = todo.reverse[smallest];
|
||||
|
||||
todo[index] = smallest;
|
||||
todo.data[index] = smallest;
|
||||
|
||||
reverse[smallest] = index;
|
||||
todo.reverse[smallest] = index;
|
||||
|
||||
index = new;
|
||||
|
||||
|
|
@ -433,73 +447,166 @@ void calculate_simplifications(void)
|
|||
|
||||
void append(uint16_t truthtable, int cost)
|
||||
{
|
||||
assert(reverse[truthtable] == -1);
|
||||
assert(todo.reverse[truthtable] == -1);
|
||||
|
||||
int index = todo_n++, new_index;
|
||||
int index = todo.n++, new_index;
|
||||
|
||||
while (index > 0 && costs[todo[new_index = (index - 1) / 2]] > cost)
|
||||
while (index > 0 && lookup[todo.data[new_index = (index - 1) / 2]].cost > cost)
|
||||
{
|
||||
todo[index] = todo[new_index];
|
||||
todo.data[index] = todo.data[new_index];
|
||||
|
||||
reverse[todo[new_index]] = index;
|
||||
todo.reverse[todo.data[new_index]] = index;
|
||||
|
||||
index = new_index;
|
||||
}
|
||||
|
||||
todo[index] = truthtable;
|
||||
|
||||
reverse[truthtable] = index;
|
||||
|
||||
costs[truthtable] = cost;
|
||||
|
||||
todo.data[index] = truthtable;
|
||||
|
||||
todo.reverse[truthtable] = index;
|
||||
|
||||
lookup[truthtable].cost = cost;
|
||||
}
|
||||
|
||||
void update(uint16_t truthtable, int cost)
|
||||
{
|
||||
assert(reverse[truthtable] != -1);
|
||||
assert(todo.reverse[truthtable] != -1);
|
||||
|
||||
assert(cost < costs[truthtable]);
|
||||
assert(cost < lookup[truthtable].cost);
|
||||
|
||||
int index = reverse[truthtable], new_index;
|
||||
int index =todo. reverse[truthtable], new_index;
|
||||
|
||||
while (index > 0 && costs[todo[new_index = (index - 1) / 2]] > cost)
|
||||
while (index > 0 && lookup[todo.data[new_index = (index - 1) / 2]].cost > cost)
|
||||
{
|
||||
todo[index] = todo[new_index];
|
||||
todo.data[index] = todo.data[new_index];
|
||||
|
||||
reverse[todo[new_index]] = index;
|
||||
todo.reverse[todo.data[new_index]] = index;
|
||||
|
||||
index = new_index;
|
||||
}
|
||||
|
||||
todo[index] = truthtable;
|
||||
reverse[truthtable] = index;
|
||||
todo.data[index] = truthtable;
|
||||
todo.reverse[truthtable] = index;
|
||||
|
||||
costs[truthtable] = cost;
|
||||
lookup[truthtable].cost = cost;
|
||||
}
|
||||
|
||||
|
||||
// create a list of the "done" truthtables
|
||||
struct {
|
||||
int headtails[N], next[N], head;
|
||||
|
||||
// for debugging:
|
||||
bool in[N];
|
||||
} done = {};
|
||||
|
||||
// init 'done':
|
||||
{
|
||||
done.head = -1;
|
||||
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
done.headtails[i] = -1;
|
||||
|
||||
done.in[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
void insert(int index)
|
||||
{
|
||||
assert(!done.in[index]);
|
||||
|
||||
int head = index & 1 ? index & ~(index & -index) : index, prevhead = -1;
|
||||
|
||||
while (done.headtails[head] == -1 || index < done.headtails[head])
|
||||
{
|
||||
done.headtails[head] = index;
|
||||
|
||||
prevhead = head, head = head & ~(head & -head);
|
||||
}
|
||||
|
||||
if (done.headtails[head] < index)
|
||||
{
|
||||
if (prevhead == -1)
|
||||
{
|
||||
assert(done.headtails[head] == head);
|
||||
|
||||
done.next[head] = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
int tophalftail = done.headtails[prevhead - 1];
|
||||
|
||||
assert(tophalftail != -1);
|
||||
|
||||
done.next[tophalftail] = index;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
done.head = index;
|
||||
}
|
||||
|
||||
int n = ~index & M;
|
||||
int tail = index & 1 ? index : index | (n & -n), prevtail = -1;
|
||||
|
||||
while (done.headtails[tail] == -1 || done.headtails[tail] < index)
|
||||
{
|
||||
done.headtails[tail] = index;
|
||||
|
||||
prevtail = tail, tail = tail | (n = ~tail & M, n & -n);
|
||||
}
|
||||
|
||||
if (index < done.headtails[tail])
|
||||
{
|
||||
if (prevtail == -1)
|
||||
{
|
||||
assert(done.headtails[tail] == tail);
|
||||
|
||||
assert(done.in[tail]);
|
||||
|
||||
done.next[index] = tail;
|
||||
}
|
||||
else
|
||||
{
|
||||
int bottomhalfhead = done.headtails[prevtail + 1];
|
||||
|
||||
assert(bottomhalfhead != -1);
|
||||
|
||||
done.next[index] = bottomhalfhead;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
done.next[index] = -1;
|
||||
}
|
||||
|
||||
done.in[index] = true;
|
||||
}
|
||||
|
||||
append(W, 0), lookup[W].kind = ek_W;
|
||||
append(X, 0), lookup[X].kind = ek_X;
|
||||
append(Y, 0), lookup[Y].kind = ek_Y;
|
||||
append(Z, 0), lookup[Z].kind = ek_Z;
|
||||
|
||||
|
||||
append(0, 1), lookup[0].kind = ek_0;
|
||||
append(M, 1), lookup[M].kind = ek_1;
|
||||
|
||||
while (todo_n)
|
||||
|
||||
for (int iterations = 1; todo.n && iterations <= N; iterations++)
|
||||
{
|
||||
uint16_t truthtable = pop();
|
||||
|
||||
int cost = costs[truthtable];
|
||||
|
||||
insert(truthtable);
|
||||
|
||||
int cost = lookup[truthtable].cost;
|
||||
|
||||
if (verbose)
|
||||
{
|
||||
int left = N - todo_n;
|
||||
|
||||
if (print_with_color)
|
||||
{
|
||||
printf("\e[2K");
|
||||
}
|
||||
|
||||
printf("%i of %i (%.2f%%): [%i] ", left, N, (100.0 * left / N), cost);
|
||||
printf("%i of %i (%.2f%%): [%i] ",
|
||||
iterations, N, (100.0 * iterations / N), cost);
|
||||
|
||||
print(truthtable, 0), puts("");
|
||||
|
||||
|
|
@ -516,9 +623,9 @@ void calculate_simplifications(void)
|
|||
|
||||
int not_cost = cost + 1;
|
||||
|
||||
if (not_cost < costs[not_truthtable])
|
||||
if (not_cost < lookup[not_truthtable].cost)
|
||||
{
|
||||
if (reverse[not_truthtable] == -1)
|
||||
if (todo.reverse[not_truthtable] == -1)
|
||||
{
|
||||
append(not_truthtable, not_cost);
|
||||
}
|
||||
|
|
@ -534,44 +641,41 @@ void calculate_simplifications(void)
|
|||
|
||||
#define BINARY_OPERATOR(ekind, function) \
|
||||
{ \
|
||||
for (int i = 0; i < N; i++) \
|
||||
for (int i = done.head; i != -1; i = done.next[i]) \
|
||||
{ \
|
||||
if (costs[i] != INT_MAX) \
|
||||
{ \
|
||||
uint16_t bin_truthtable = function(truthtable, i) & M; \
|
||||
\
|
||||
int bin_cost = 1 + cost + lookup[i].cost; \
|
||||
\
|
||||
if (bin_cost < lookup[bin_truthtable].cost) \
|
||||
{ \
|
||||
uint16_t bin_truthtable = function(truthtable, i) & M; \
|
||||
if (todo.reverse[bin_truthtable] == -1) \
|
||||
append(bin_truthtable, bin_cost); \
|
||||
else \
|
||||
update(bin_truthtable, bin_cost); \
|
||||
\
|
||||
int bin_cost = 1 + cost + costs[i]; \
|
||||
\
|
||||
if (bin_cost < costs[bin_truthtable]) \
|
||||
{ \
|
||||
if (reverse[bin_truthtable] == -1) \
|
||||
append(bin_truthtable, bin_cost); \
|
||||
else \
|
||||
update(bin_truthtable, bin_cost); \
|
||||
\
|
||||
lookup[bin_truthtable].kind = ekind; \
|
||||
lookup[bin_truthtable].left = truthtable; \
|
||||
lookup[bin_truthtable].right = i; \
|
||||
} \
|
||||
lookup[bin_truthtable].kind = ekind; \
|
||||
lookup[bin_truthtable].left = truthtable; \
|
||||
lookup[bin_truthtable].right = i; \
|
||||
} \
|
||||
\
|
||||
} \
|
||||
\
|
||||
{ \
|
||||
uint16_t bin_truthtable = function(i, truthtable) & M; \
|
||||
\
|
||||
int bin_cost = 1 + cost + lookup[i].cost; \
|
||||
\
|
||||
if (bin_cost < lookup[bin_truthtable].cost) \
|
||||
{ \
|
||||
uint16_t bin_truthtable = function(i, truthtable) & M; \
|
||||
if (todo.reverse[bin_truthtable] == -1) \
|
||||
append(bin_truthtable, bin_cost); \
|
||||
else \
|
||||
update(bin_truthtable, bin_cost); \
|
||||
\
|
||||
int bin_cost = 1 + cost + costs[i]; \
|
||||
\
|
||||
if (bin_cost < costs[bin_truthtable]) \
|
||||
{ \
|
||||
if (reverse[bin_truthtable] == -1) \
|
||||
append(bin_truthtable, bin_cost); \
|
||||
else \
|
||||
update(bin_truthtable, bin_cost); \
|
||||
\
|
||||
lookup[bin_truthtable].kind = ekind; \
|
||||
lookup[bin_truthtable].left = i; \
|
||||
lookup[bin_truthtable].right = truthtable; \
|
||||
} \
|
||||
lookup[bin_truthtable].kind = ekind; \
|
||||
lookup[bin_truthtable].left = i; \
|
||||
lookup[bin_truthtable].right = truthtable; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
|
|
@ -654,44 +758,38 @@ void calculate_simplifications(void)
|
|||
|
||||
if (use_operators.ternary)
|
||||
{
|
||||
for (int i = 0; i < N; i++)
|
||||
for (int i = done.head; i != -1; i = done.next[i])
|
||||
{
|
||||
if (costs[i] != INT_MAX)
|
||||
for (int j = done.head; j != -1; j = done.next[j])
|
||||
{
|
||||
for (int j = 0; j < N; j++)
|
||||
{
|
||||
if (costs[j] != INT_MAX)
|
||||
{
|
||||
int ternary_cost = 1 + cost + costs[i] + costs[j];
|
||||
int ternary_cost = 1 + cost + lookup[i].cost + lookup[j].cost;
|
||||
|
||||
#define TERNARY(C, T, F) \
|
||||
#define TERNARY(C, T, F) \
|
||||
{ \
|
||||
uint16_t ternary_truthtable = \
|
||||
((C) & (T)) | (~(C) & (F)); \
|
||||
\
|
||||
if (ternary_cost < lookup[ternary_truthtable].cost) \
|
||||
{ \
|
||||
if (todo.reverse[ternary_truthtable] == -1) \
|
||||
{ \
|
||||
uint16_t ternary_truthtable = \
|
||||
((C) & (T)) | (~(C) & (F)); \
|
||||
\
|
||||
if (ternary_cost < costs[ternary_truthtable]) \
|
||||
{ \
|
||||
if (reverse[ternary_truthtable] == -1) \
|
||||
{ \
|
||||
append(ternary_truthtable, ternary_cost); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
update(ternary_truthtable, ternary_cost); \
|
||||
} \
|
||||
\
|
||||
lookup[ternary_truthtable].kind = ek_ternary; \
|
||||
lookup[ternary_truthtable].cond = (C); \
|
||||
lookup[ternary_truthtable].left = (T); \
|
||||
lookup[ternary_truthtable].right = (F); \
|
||||
} \
|
||||
append(ternary_truthtable, ternary_cost); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
update(ternary_truthtable, ternary_cost); \
|
||||
} \
|
||||
\
|
||||
lookup[ternary_truthtable].kind = ek_ternary; \
|
||||
lookup[ternary_truthtable].cond = (C); \
|
||||
lookup[ternary_truthtable].left = (T); \
|
||||
lookup[ternary_truthtable].right = (F); \
|
||||
} \
|
||||
} \
|
||||
|
||||
TERNARY(truthtable, i, j);
|
||||
TERNARY(i, truthtable, j);
|
||||
TERNARY(i, j, truthtable);
|
||||
}
|
||||
}
|
||||
TERNARY(truthtable, i, j);
|
||||
TERNARY(i, truthtable, j);
|
||||
TERNARY(i, j, truthtable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -705,7 +803,7 @@ void calculate_simplifications(void)
|
|||
|
||||
void get_simplifications(void)
|
||||
{
|
||||
char path[PATH_MAX] = ".simplifier-cache";
|
||||
char path[PATH_MAX] = ".simplifier-cache-2";
|
||||
|
||||
if (use_operators.not)
|
||||
strcat(path, "-not");
|
||||
|
|
@ -766,12 +864,6 @@ void get_simplifications(void)
|
|||
printf("%s: read() to cache failed: %m\n", argv0);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (read(fd, costs, sizeof(costs)) < (ssize_t) sizeof(costs))
|
||||
{
|
||||
printf("%s: read() to cache failed: %m\n", argv0);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else if (fd < 0 && errno == ENOENT)
|
||||
{
|
||||
|
|
@ -806,12 +898,6 @@ void get_simplifications(void)
|
|||
printf("%s: write() to cache failed: %m\n", argv0);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (write(fd, costs, sizeof(costs)) < (ssize_t) sizeof(costs))
|
||||
{
|
||||
printf("%s: write() to cache failed: %m\n", argv0);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -1326,7 +1412,7 @@ int main(int argc, char* const* argv)
|
|||
{
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
int cost = costs[i];
|
||||
int cost = lookup[i].cost;
|
||||
|
||||
if (cost != INT_MAX)
|
||||
{
|
||||
|
|
@ -1340,48 +1426,52 @@ int main(int argc, char* const* argv)
|
|||
|
||||
// printf("truthtable = 0b%016b\n", truthtable);
|
||||
|
||||
if (costs[truthtable] == INT_MAX)
|
||||
if (lookup[truthtable].kind == ek_unreachable)
|
||||
{
|
||||
puts("unreachable");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%2i: ", costs[truthtable]), print(truthtable, 0), puts("");
|
||||
printf("%2i: ", lookup[truthtable].cost), print(truthtable, 0), puts("");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int max_cost = 0;
|
||||
|
||||
for (int i = 0; i < N; i++)
|
||||
// Let's humble-brag just a little.
|
||||
{
|
||||
int cost = costs[i];
|
||||
int max_cost = 0;
|
||||
|
||||
if (cost != INT_MAX && max_cost < cost)
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
max_cost = cost;
|
||||
int cost = lookup[i].cost;
|
||||
|
||||
if (cost != INT_MAX && max_cost < cost)
|
||||
{
|
||||
max_cost = cost;
|
||||
}
|
||||
}
|
||||
|
||||
puts("");
|
||||
printf("I can simplify any tree down to %i operators or less.\n",
|
||||
max_cost);
|
||||
puts("");
|
||||
}
|
||||
|
||||
// we subtract 4 from the cost because
|
||||
puts("");
|
||||
printf("I can simplify any tree down to %i operators or less.\n",
|
||||
max_cost);
|
||||
puts("");
|
||||
|
||||
|
||||
for (char* line; (line = readline(">>> ")); free(line))
|
||||
{
|
||||
add_history(line);
|
||||
|
||||
uint16_t truthtable = evaluate(line);
|
||||
|
||||
// printf("truthtable = 0b%016b\n", truthtable);
|
||||
|
||||
if (costs[truthtable] == INT_MAX)
|
||||
if (lookup[truthtable].kind == ek_unreachable)
|
||||
{
|
||||
puts("unreachable");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("%2i: ", costs[truthtable]), print(truthtable, 0), puts("");
|
||||
printf("%2i: ", lookup[truthtable].cost), print(truthtable, 0), puts("");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
3
makefile
3
makefile
|
|
@ -23,5 +23,6 @@ run: /tmp/4-variable-simplifier
|
|||
$< $(args)
|
||||
|
||||
|
||||
# nix --extra-experimental-features nix-command --extra-experimental-features flakes develop --command 'make'
|
||||
# nix --extra-experimental-features nix-command \
|
||||
# --extra-experimental-features flakes develop --command 'make'
|
||||
|
||||
|
|
|
|||
100
spikes/kattis-add-find-all.c
Normal file
100
spikes/kattis-add-find-all.c
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define N(array) (sizeof(array) / sizeof(*array))
|
||||
|
||||
// 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};
|
||||
|
||||
int c[20] = {
|
||||
15, 17, 19, 21, 22, 25, 26, 26, 27, 32,
|
||||
33, 33, 36, 39, 42, 44, 48, 49, 49, 49
|
||||
};
|
||||
|
||||
// [ 0] [ 1] [ 2] [ 3] [ 4] [ 5] [ 6] [ 7] [ 8] [ 9]
|
||||
// 2 4 5 7 9 11 15 17 17 19
|
||||
// --------------------------------------------------
|
||||
// [ 0] 10 | 12 14 (15) (17) (19) (21) (25) (27) (27) 29
|
||||
|
||||
// [ 1] 11 | 13 (15) 16 28 20 (22) (26) 28 28 30
|
||||
|
||||
// [ 2] 11 | 13 (15) 16 18 20 (22) (26) 28 28 30
|
||||
|
||||
// [ 3] 14 | 16 18 (19) (21) 23 (25) 29 31 31 (33)
|
||||
|
||||
// [ 4] 14 | 16 18 (19) (21) 23 (25) 29 31 31 (33)
|
||||
|
||||
// [ 5] 19 |(21) 23 24 (26) 28 30 34 (36) (36) 38
|
||||
|
||||
// [ 6] 20 |(22) 24 (25) (27) 29 31 38 40 40 (42)
|
||||
|
||||
// [ 7] 23 |(25) (27) 28 30 (32) 34 38 40 40 (42)
|
||||
|
||||
// [ 8] 26 | 28 30 31 (33) 35 37 41 43 43 45
|
||||
|
||||
// [ 9] 29 | 31 (33) 34 (36) 38 40 (44) 46 46 (48)
|
||||
|
||||
int main()
|
||||
{
|
||||
puts("hello, world!");
|
||||
|
||||
for (int ci = 0; ci < 20; ci++)
|
||||
{
|
||||
bool found[10][10] = {};
|
||||
|
||||
int goal = c[ci];
|
||||
|
||||
bool again = true;
|
||||
|
||||
while (again)
|
||||
{
|
||||
again = false;
|
||||
|
||||
int ai = 0, bi = 9;
|
||||
|
||||
while (ai < 10 && bi >= 0)
|
||||
{
|
||||
int sum = found[ai][bi] ? 0 : a[ai] + b[bi];
|
||||
|
||||
if (sum < goal)
|
||||
{
|
||||
ai++;
|
||||
}
|
||||
else if (sum > goal)
|
||||
{
|
||||
bi--;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(a[ai] + b[bi] == c[ci]);
|
||||
|
||||
printf("a[%2i] + b[%2i] == c[%2i] "
|
||||
"(%2i + %2i == %2i)\n",
|
||||
ai, bi, ci, a[ai], b[bi], c[ci]);
|
||||
|
||||
found[ai][bi] = true;
|
||||
again = true;
|
||||
|
||||
bi--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
94
spikes/kattis-add.c
Normal file
94
spikes/kattis-add.c
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define N(array) (sizeof(array) / sizeof(*array))
|
||||
|
||||
// 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};
|
||||
|
||||
int c[20] = {
|
||||
15, 17, 19, 21, 22, 25, 26, 26, 27, 32,
|
||||
33, 33, 36, 39, 42, 44, 48, 49, 49, 49
|
||||
};
|
||||
|
||||
// [ 0] [ 1] [ 2] [ 3] [ 4] [ 5] [ 6] [ 7] [ 8] [ 9]
|
||||
// 2 4 5 7 9 11 15 17 17 19
|
||||
// --------------------------------------------------
|
||||
// [ 0] 10 | 12 14 15 (17) 19 21 25 27 27 29
|
||||
|
||||
// [ 1] 11 | 13 15 16 28 20 22 26 28 28 30
|
||||
|
||||
// [ 2] 11 | 13 (15) 16 18 20 22 26 28 28 30
|
||||
|
||||
// [ 3] 14 | 16 18 19 21 23 25 29 31 31 33
|
||||
|
||||
// [ 4] 14 | 16 18 (19) 21 23 25 29 31 31 33
|
||||
|
||||
// [ 5] 19 |(21) 23 24 (26) 28 30 34 36 36 38
|
||||
|
||||
// [ 6] 20 |(22) 24 25 27 29 31 38 40 40 (42)
|
||||
|
||||
// [ 7] 23 |(25) (27) 28 30 32 34 38 40 40 (42)
|
||||
|
||||
// [ 8] 26 | 28 30 31 33 35 37 41 43 43 45
|
||||
|
||||
// [ 9] 29 | 31 (33) 34 (36) 38 40 (44) 46 46 (48)
|
||||
|
||||
int main()
|
||||
{
|
||||
puts("hello, world!");
|
||||
|
||||
for (int ci = 0; ci < 20; ci++)
|
||||
{
|
||||
int goal = c[ci];
|
||||
|
||||
int ai = 0, bi = 9;
|
||||
|
||||
while (1)
|
||||
{
|
||||
int sum = a[ai] + b[bi];
|
||||
|
||||
if (sum < goal)
|
||||
{
|
||||
ai++;
|
||||
|
||||
if (ai == 10)
|
||||
break;
|
||||
}
|
||||
else if (sum > goal)
|
||||
{
|
||||
if (bi == 0)
|
||||
break;
|
||||
|
||||
bi--;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(a[ai] + b[bi] == c[ci]);
|
||||
|
||||
printf("a[%2i] + b[%2i] == c[%2i] "
|
||||
"(%2i + %2i == %2i)\n",
|
||||
ai, bi, ci, a[ai], b[bi], c[ci]);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
85
spikes/kattis-subtract.c
Normal file
85
spikes/kattis-subtract.c
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
|
||||
// in this one, 'a' is fixed and we're trying to find a 'b' and 'c' to
|
||||
// satisify the equation: `a + b = c`
|
||||
|
||||
// which we're re-writing as:
|
||||
// `a = c - b`
|
||||
|
||||
int a = 7;
|
||||
/*int a = 11;*/
|
||||
|
||||
// 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] = {
|
||||
15, 17, 19, 21, 22, 25, 26, 26, 27, 32,
|
||||
33, 33, 36, 39, 42, 44, 48, 49, 49, 49
|
||||
};
|
||||
|
||||
int main()
|
||||
{
|
||||
puts("hello, world!");
|
||||
|
||||
bool found[10][20] = {};
|
||||
|
||||
int passes = 0;
|
||||
|
||||
bool again = true;
|
||||
|
||||
while (again)
|
||||
{
|
||||
passes++;
|
||||
again = false;
|
||||
|
||||
int bi = 0, ci = 0;
|
||||
|
||||
while (bi < 10 && ci < 20)
|
||||
{
|
||||
int diff = found[bi][ci] ? INT_MIN : c[ci] - b[bi];
|
||||
|
||||
if (a < diff)
|
||||
{
|
||||
bi++;
|
||||
}
|
||||
else if (diff < a)
|
||||
{
|
||||
ci++;
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(a + b[bi] == c[ci]);
|
||||
|
||||
printf("a + b[%2i] == c[%2i] "
|
||||
"(%2i + %2i == %2i)\n",
|
||||
bi, ci, a, b[bi], c[ci]);
|
||||
|
||||
found[bi][ci] = true;
|
||||
again = true;
|
||||
|
||||
// From now on, this cell will be seen as "too low"
|
||||
// so we'll take that path like it's too high.
|
||||
bi++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
printf("passes = %i\n", passes);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
172
spikes/linear-add.c
Normal file
172
spikes/linear-add.c
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define N(array) (sizeof(array) / sizeof(*array))
|
||||
|
||||
// 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};
|
||||
|
||||
int c[20] = {
|
||||
15, 17, 19, 21, 22, 25, 26, 26, 27, 32,
|
||||
33, 33, 36, 39, 42, 44, 48, 49, 49, 49
|
||||
};
|
||||
|
||||
// [ 0] [ 1] [ 2] [ 3] [ 4] [ 5] [ 6] [ 7] [ 8] [ 9]
|
||||
// 2 4 5 7 9 11 15 17 17 19
|
||||
// --------------------------------------------------
|
||||
// [ 0] 10 | 12 14 (15) (17) (19) (21) (25) (27) (27) 29
|
||||
|
||||
// [ 1] 11 | 13 (15) 16 28 20 (22) (26) 28 28 30
|
||||
|
||||
// [ 2] 11 | 13 (15) 16 18 20 (22) (26) 28 28 30
|
||||
|
||||
// [ 3] 14 | 16 18 (19) (21) 23 (25) 29 31 31 (33)
|
||||
|
||||
// [ 4] 14 | 16 18 (19) (21) 23 (25) 29 31 31 (33)
|
||||
|
||||
// [ 5] 19 |(21) 23 24 (26) 28 30 34 (36) (36) 38
|
||||
|
||||
// [ 6] 20 |(22) 24 (25) (27) 29 31 38 40 40 (42)
|
||||
|
||||
// [ 7] 23 |(25) (27) 28 30 (32) 34 38 40 40 (42)
|
||||
|
||||
// [ 8] 26 | 28 30 31 (33) 35 37 41 43 43 45
|
||||
|
||||
// [ 9] 29 | 31 (33) 34 (36) 38 40 (44) 46 46 (48)
|
||||
|
||||
int sums[10 * 10];
|
||||
|
||||
bool queued[10 * 10];
|
||||
|
||||
struct {
|
||||
int data[10 * 10];
|
||||
int n;
|
||||
} heap;
|
||||
|
||||
void append(int e)
|
||||
{
|
||||
int index = heap.n++, new_index;
|
||||
|
||||
while (index > 0 && sums[heap.data[new_index = (index - 1) / 2]] > sums[e])
|
||||
{
|
||||
heap.data[index] = heap.data[new_index];
|
||||
|
||||
index = new_index;
|
||||
}
|
||||
|
||||
heap.data[index] = e;
|
||||
}
|
||||
|
||||
int pop(void)
|
||||
{
|
||||
assert(heap.n > 0);
|
||||
|
||||
int retval = heap.data[0];
|
||||
|
||||
heap.data[0] = heap.data[heap.n-- - 1];
|
||||
|
||||
int index = 0;
|
||||
|
||||
again:
|
||||
{
|
||||
int left = index * 2 + 1;
|
||||
int right = index * 2 + 2;
|
||||
|
||||
int smallest = index;
|
||||
|
||||
if (left < heap.n && sums[heap.data[left]] < sums[heap.data[index]])
|
||||
smallest = left;
|
||||
|
||||
if (right < heap.n && sums[heap.data[right]] < sums[heap.data[smallest]])
|
||||
smallest = right;
|
||||
|
||||
if (smallest != index)
|
||||
{
|
||||
int tmp = heap.data[index];
|
||||
heap.data[index] = heap.data[smallest];
|
||||
heap.data[smallest] = tmp;
|
||||
|
||||
index = smallest;
|
||||
|
||||
goto again;
|
||||
}
|
||||
}
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
int main()
|
||||
{
|
||||
puts("hello, world!");
|
||||
|
||||
int ci = 0;
|
||||
|
||||
sums[0] = a[0] + b[0];
|
||||
queued[0] = true;
|
||||
append(0);
|
||||
|
||||
while (heap.n && ci < 20)
|
||||
{
|
||||
int sum = sums[heap.data[0]], ce = c[ci];
|
||||
|
||||
// printf("sum = %i, ce = %i\n", sum, ce);
|
||||
|
||||
if (sum < ce)
|
||||
{
|
||||
next_sum: ;
|
||||
|
||||
int xy = pop();
|
||||
|
||||
if (xy % 10 + 1 < 10 && !queued[xy + 1])
|
||||
{
|
||||
int nxy = xy + 1;
|
||||
sums[nxy] = a[nxy % 10] + b[nxy / 10];
|
||||
queued[nxy] = true;
|
||||
append(nxy);
|
||||
}
|
||||
|
||||
if (xy + 10 < 100 && !queued[xy + 10])
|
||||
{
|
||||
int nxy = xy + 10;
|
||||
sums[nxy] = a[nxy % 10] + b[nxy / 10];
|
||||
queued[nxy] = true;
|
||||
append(nxy);
|
||||
}
|
||||
}
|
||||
else if (sum > ce)
|
||||
{
|
||||
ci++;
|
||||
}
|
||||
else
|
||||
{
|
||||
int xy = heap.data[0];
|
||||
|
||||
int ai = xy % 10, bi = xy / 10;
|
||||
|
||||
assert(a[ai] + b[bi] == c[ci]);
|
||||
|
||||
printf("a[%2i] + b[%2i] == c[%2i] (%2i + %2i == %2i)\n",
|
||||
ai, bi, ci, a[ai], b[bi], c[ci]);
|
||||
|
||||
goto next_sum;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
37
spikes/quadrant-or-1.c
Normal file
37
spikes/quadrant-or-1.c
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
void search(
|
||||
int mask,
|
||||
int ai, int bi,
|
||||
int findme)
|
||||
{
|
||||
if (mask)
|
||||
{
|
||||
if (findme & mask)
|
||||
{
|
||||
search(mask >> 1, ai, bi | mask, findme);
|
||||
search(mask >> 1, ai | mask, bi, findme);
|
||||
search(mask >> 1, ai | mask, bi | mask, findme);
|
||||
}
|
||||
else
|
||||
{
|
||||
search(mask >> 1, ai, bi, findme);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert((ai | bi) == findme);
|
||||
|
||||
printf("0b%04b | 0b%04b == 0b%04b "
|
||||
"(%2i | %2i == %2i)\n", ai, bi, findme, ai, bi, findme);
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
search(0b1000, 0, 0, 11);
|
||||
|
||||
return 0;
|
||||
}
|
||||
220
spikes/quadrant-or-2.c
Normal file
220
spikes/quadrant-or-2.c
Normal file
|
|
@ -0,0 +1,220 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef ZDEBUG
|
||||
#define zprintf(fmt, ...) printf(fmt, ## __VA_ARGS__);
|
||||
#else
|
||||
#define zprintf(...) ;
|
||||
#endif
|
||||
|
||||
// 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 binary(
|
||||
int mask,
|
||||
int *array,
|
||||
int i, int n)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void search(
|
||||
int mask,
|
||||
int ai, int an,
|
||||
int bi, int bn,
|
||||
int findme,
|
||||
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 | | |
|
||||
// ... | first quadrant. | second quadrant |
|
||||
// (bsplit - 1) | | |
|
||||
// --- ---------------------- -------------------
|
||||
// bsplit | | |
|
||||
// ... | third quadrant | fourth quadrant |
|
||||
// (bn - 1) | | |
|
||||
// --- | | |
|
||||
// ---------------------- -------------------
|
||||
|
||||
// second quadrant.
|
||||
if (asplit < an && 0 < bsplit)
|
||||
{
|
||||
zprintf("%*s" "entering second quadrant." "\n", calldepth, "");
|
||||
|
||||
search(
|
||||
mask >> 1,
|
||||
ai + asplit, an - asplit,
|
||||
bi, bsplit,
|
||||
findme,
|
||||
calldepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
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,
|
||||
bi + bsplit, bn - bsplit,
|
||||
findme,
|
||||
calldepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
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,
|
||||
bi + bsplit, bn - bsplit,
|
||||
findme,
|
||||
calldepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
zprintf("%*s" "empty fourth quadrant." "\n", calldepth, "");
|
||||
}
|
||||
}
|
||||
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,
|
||||
bi, bsplit,
|
||||
findme,
|
||||
calldepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
zprintf("%*s" "empty first quadrant." "\n", calldepth, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
else for (int i = 0; i < an; i++)
|
||||
{
|
||||
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],
|
||||
b[bi + j], bi + j, b[bi + j],
|
||||
findme, findme);
|
||||
}
|
||||
}
|
||||
|
||||
calldepth--;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
search(
|
||||
16,
|
||||
0, 10,
|
||||
0, 10,
|
||||
23,
|
||||
0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
341
spikes/quadrant-reverse-or-with-lists.c
Normal file
341
spikes/quadrant-reverse-or-with-lists.c
Normal file
|
|
@ -0,0 +1,341 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef ZDEBUG
|
||||
#define zprintf(fmt, ...) printf(fmt, ## __VA_ARGS__);
|
||||
#else
|
||||
#define zprintf(...) ;
|
||||
#endif
|
||||
|
||||
#define N (256)
|
||||
|
||||
#define M (255)
|
||||
|
||||
struct sparselist {
|
||||
int headtails[N], next[N], head;
|
||||
|
||||
bool in[N];
|
||||
} b, c;
|
||||
|
||||
void init(struct sparselist* this)
|
||||
{
|
||||
this->head = -1;
|
||||
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
this->headtails[i] = -1;
|
||||
|
||||
this->next[i] = -1;
|
||||
|
||||
this->in[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
void print(struct sparselist* this)
|
||||
{
|
||||
puts("print():");
|
||||
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
if (this->headtails[i] != -1)
|
||||
{
|
||||
printf(" " "headtails[%3i (0b%08b)] = %i" "\n", i, i, this->headtails[i]);
|
||||
}
|
||||
}
|
||||
|
||||
printf("head = %i\n", this->head);
|
||||
|
||||
for (int index = this->head; index != -1; index = this->next[index])
|
||||
{
|
||||
printf(" " "index = %i\n", index);
|
||||
}
|
||||
}
|
||||
|
||||
void insert(struct sparselist* this, int index)
|
||||
{
|
||||
assert(!this->in[index]);
|
||||
|
||||
int head = index & 1 ? index & ~(index & -index) : index, prevhead = -1;
|
||||
|
||||
while (this->headtails[head] == -1 || index < this->headtails[head])
|
||||
{
|
||||
this->headtails[head] = index;
|
||||
prevhead = head, head = head & ~(head & -head);
|
||||
}
|
||||
|
||||
if (this->headtails[head] < index)
|
||||
{
|
||||
if (prevhead == -1)
|
||||
{
|
||||
assert(this->headtails[head] == head);
|
||||
|
||||
assert(this->in[head]);
|
||||
|
||||
this->next[head] = index;
|
||||
}
|
||||
else
|
||||
{
|
||||
int tophalftail = this->headtails[prevhead - 1];
|
||||
|
||||
assert(tophalftail != -1);
|
||||
|
||||
this->next[tophalftail] = index;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->head = index;
|
||||
}
|
||||
|
||||
int n = ~index & M;
|
||||
int tail = index & 1 ? index : index | (n & -n), prevtail = -1;
|
||||
|
||||
while (this->headtails[tail] == -1 || this->headtails[tail] < index)
|
||||
{
|
||||
this->headtails[tail] = index;
|
||||
prevtail = tail, tail = tail | (n = ~tail & M, n & -n);
|
||||
}
|
||||
|
||||
if (index < this->headtails[tail])
|
||||
{
|
||||
if (prevtail == -1)
|
||||
{
|
||||
assert(this->headtails[tail] == tail);
|
||||
|
||||
assert(this->in[tail]);
|
||||
|
||||
this->next[index] = tail;
|
||||
}
|
||||
else
|
||||
{
|
||||
int bottomhalfhead = this->headtails[prevtail + 1];
|
||||
|
||||
assert(bottomhalfhead != -1);
|
||||
|
||||
this->next[index] = bottomhalfhead;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this->next[index] = -1;
|
||||
}
|
||||
|
||||
this->in[index] = true;
|
||||
}
|
||||
|
||||
int a = 17;
|
||||
|
||||
void search(
|
||||
int mask,
|
||||
int bheadindex, int btailindex,
|
||||
int cheadindex, int ctailindex,
|
||||
int calldepth)
|
||||
{
|
||||
zprintf("%*s" "quadrant_search():" "\n", calldepth++, "");
|
||||
|
||||
zprintf("%*s" "mask = 0b%05b" "\n", calldepth, "", mask);
|
||||
|
||||
zprintf("%*s" "bheadindex = %i" "\n", calldepth, "", bheadindex);
|
||||
zprintf("%*s" "btailindex = %i" "\n", calldepth, "", btailindex);
|
||||
|
||||
zprintf("%*s" "cheadindex = %i" "\n", calldepth, "", cheadindex);
|
||||
zprintf("%*s" "ctailindex = %i" "\n", calldepth, "", ctailindex);
|
||||
|
||||
if (mask)
|
||||
{
|
||||
// 0 ... (bsplit - 1) | bsplit ... (an - 1)
|
||||
// --------------------- -------------------
|
||||
// 0 | | |
|
||||
// ... | first quadrant. | second quadrant |
|
||||
// (csplit - 1) | | |
|
||||
// --- ---------------------- -------------------
|
||||
// csplit | | |
|
||||
// ... | third quadrant | fourth quadrant |
|
||||
// (cn - 1) | | |
|
||||
// --- | | |
|
||||
// ---------------------- -------------------
|
||||
|
||||
if (mask & a)
|
||||
{
|
||||
zprintf("%*s" "one case" "\n", calldepth, "");
|
||||
|
||||
// third quadrant
|
||||
int q3_btailindex = btailindex & ~mask;
|
||||
int q3_cheadindex = cheadindex | mask;
|
||||
|
||||
zprintf("%*s" "q3_btailindex = %i" "\n", calldepth, "", q3_btailindex);
|
||||
zprintf("%*s" "q3_cheadindex = %i" "\n", calldepth, "", q3_cheadindex);
|
||||
|
||||
if (true
|
||||
&& b.headtails[q3_btailindex] != -1
|
||||
&& c.headtails[q3_cheadindex] != -1)
|
||||
{
|
||||
zprintf("%*s" "entering third quadrant." "\n", calldepth, "");
|
||||
|
||||
search(
|
||||
mask >> 1,
|
||||
bheadindex, q3_btailindex,
|
||||
q3_cheadindex, ctailindex,
|
||||
calldepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
zprintf("%*s" "empty third quadrant." "\n", calldepth, "");
|
||||
}
|
||||
|
||||
// fourth quadrant
|
||||
int q4_bheadindex = bheadindex | mask;
|
||||
int q4_cheadindex = cheadindex | mask;
|
||||
|
||||
if (true
|
||||
&& b.headtails[q4_bheadindex] != -1
|
||||
&& c.headtails[q4_cheadindex] != -1)
|
||||
{
|
||||
zprintf("%*s" "entering fourth quadrant." "\n", calldepth, "");
|
||||
|
||||
search(
|
||||
mask >> 1,
|
||||
q4_bheadindex, btailindex,
|
||||
q4_cheadindex, ctailindex,
|
||||
calldepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
zprintf("%*s" "empty fourth quadrant." "\n", calldepth, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
zprintf("%*s" "zero case" "\n", calldepth, "");
|
||||
|
||||
// first quadrant
|
||||
int q1_btailindex = btailindex & ~mask;
|
||||
int q1_ctailindex = ctailindex & ~mask;
|
||||
|
||||
zprintf("%*s" "q1_btailindex = %i" "\n", calldepth, "", q1_btailindex);
|
||||
zprintf("%*s" "q1_ctailindex = %i" "\n", calldepth, "", q1_ctailindex);
|
||||
|
||||
if (true
|
||||
&& b.headtails[q1_btailindex] != -1
|
||||
&& c.headtails[q1_ctailindex] != -1)
|
||||
{
|
||||
zprintf("%*s" "entering first quadrant." "\n", calldepth, "");
|
||||
|
||||
search(
|
||||
mask >> 1,
|
||||
bheadindex, q1_btailindex,
|
||||
cheadindex, q1_ctailindex,
|
||||
calldepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
zprintf("%*s" "empty first quadrant." "\n", calldepth, "");
|
||||
}
|
||||
|
||||
// fourth quadrant
|
||||
int q4_bheadindex = bheadindex | mask;
|
||||
int q4_cheadindex = cheadindex | mask;
|
||||
|
||||
if (true
|
||||
&& b.headtails[q4_bheadindex] != -1
|
||||
&& c.headtails[q4_cheadindex] != -1)
|
||||
{
|
||||
zprintf("%*s" "entering fourth quadrant." "\n", calldepth, "");
|
||||
|
||||
search(
|
||||
mask >> 1,
|
||||
q4_bheadindex, btailindex,
|
||||
q4_cheadindex, ctailindex,
|
||||
calldepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
zprintf("%*s" "empty fourth quadrant." "\n", calldepth, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(bheadindex == btailindex);
|
||||
assert(cheadindex == ctailindex);
|
||||
|
||||
int be = b.headtails[bheadindex];
|
||||
|
||||
int ce = c.headtails[cheadindex];
|
||||
|
||||
if (be == bheadindex && ce == cheadindex && (a | be) == ce)
|
||||
{
|
||||
assert(b.in[be]);
|
||||
assert(c.in[ce]);
|
||||
|
||||
printf("%2i (0b%05b) | %2i (0b%05b) == %2i (0b%05b)" "\n",
|
||||
a, a, be, be, ce, ce);
|
||||
}
|
||||
}
|
||||
|
||||
calldepth--;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
puts("hello, world!");
|
||||
|
||||
init(&b);
|
||||
insert(&b, 10);
|
||||
insert(&b, 11);
|
||||
insert(&b, 14);
|
||||
insert(&b, 19);
|
||||
insert(&b, 20);
|
||||
insert(&b, 23);
|
||||
insert(&b, 26);
|
||||
insert(&b, 29);
|
||||
|
||||
#ifdef ZDEBUG
|
||||
print(&b);
|
||||
#endif
|
||||
|
||||
init(&c);
|
||||
insert(&c, 15);
|
||||
insert(&c, 17);
|
||||
insert(&c, 19);
|
||||
insert(&c, 21);
|
||||
insert(&c, 22);
|
||||
insert(&c, 25);
|
||||
insert(&c, 26);
|
||||
insert(&c, 27);
|
||||
insert(&c, 32);
|
||||
insert(&c, 33);
|
||||
insert(&c, 36);
|
||||
insert(&c, 39);
|
||||
insert(&c, 42);
|
||||
insert(&c, 44);
|
||||
insert(&c, 48);
|
||||
insert(&c, 49);
|
||||
|
||||
#ifdef ZDEBUG
|
||||
print(&c);
|
||||
#endif
|
||||
|
||||
search(128, 0, 255, 0, 255, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
271
spikes/quadrant-reverse-or.c
Normal file
271
spikes/quadrant-reverse-or.c
Normal file
|
|
@ -0,0 +1,271 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef ZDEBUG
|
||||
#define zprintf(fmt, ...) printf(fmt, ## __VA_ARGS__);
|
||||
#else
|
||||
#define zprintf(...) ;
|
||||
#endif
|
||||
|
||||
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 binary(
|
||||
int mask,
|
||||
int *array,
|
||||
int i, int n)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
void quadrant_search(
|
||||
int mask,
|
||||
int bi, int bn,
|
||||
int ci, int cn,
|
||||
int calldepth)
|
||||
{
|
||||
zprintf("%*s" "quadrant_search():" "\n", calldepth++, "");
|
||||
|
||||
zprintf("%*s" "mask = 0b%05b" "\n", calldepth, "", mask);
|
||||
|
||||
zprintf("%*s" "bi = %i" "\n", calldepth, "", bi);
|
||||
zprintf("%*s" "bn = %i" "\n", calldepth, "", bn);
|
||||
|
||||
zprintf("%*s" "ci = %i" "\n", calldepth, "", ci);
|
||||
zprintf("%*s" "cn = %i" "\n", calldepth, "", cn);
|
||||
|
||||
if (mask)
|
||||
{
|
||||
int bsplit = binary(mask, b + bi, 0, bn);
|
||||
int csplit = binary(mask, c + ci, 0, cn);
|
||||
|
||||
zprintf("%*s" "bsplit = %i" "\n", calldepth, "", bsplit);
|
||||
zprintf("%*s" "csplit = %i" "\n", calldepth, "", csplit);
|
||||
|
||||
assert((bsplit == bn) || (b[bi + bsplit] & mask));
|
||||
assert((csplit == cn) || (c[ci + csplit] & mask));
|
||||
|
||||
// 0 ... (bsplit - 1) | bsplit ... (an - 1)
|
||||
// --------------------- -------------------
|
||||
// 0 | | |
|
||||
// ... | first quadrant. | second quadrant |
|
||||
// (csplit - 1) | | |
|
||||
// --- ---------------------- -------------------
|
||||
// csplit | | |
|
||||
// ... | third quadrant | fourth quadrant |
|
||||
// (cn - 1) | | |
|
||||
// --- | | |
|
||||
// ---------------------- -------------------
|
||||
|
||||
if (mask & a)
|
||||
{
|
||||
zprintf("%*s" "one case" "\n", calldepth, "");
|
||||
|
||||
// third quadrant
|
||||
if (0 < bsplit && csplit < cn)
|
||||
{
|
||||
zprintf("%*s" "entering third quadrant." "\n", calldepth, "");
|
||||
|
||||
quadrant_search(
|
||||
mask >> 1,
|
||||
bi, bsplit,
|
||||
ci + csplit, cn - csplit,
|
||||
calldepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
zprintf("%*s" "empty third quadrant." "\n", calldepth, "");
|
||||
}
|
||||
|
||||
// fourth quadrant
|
||||
if (bsplit < bn && csplit < cn)
|
||||
{
|
||||
zprintf("%*s" "entering fourth quadrant." "\n", calldepth, "");
|
||||
|
||||
quadrant_search(
|
||||
mask >> 1,
|
||||
bi + bsplit, bn - bsplit,
|
||||
ci + csplit, cn - csplit,
|
||||
calldepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
zprintf("%*s" "empty fourth quadrant." "\n", calldepth, "");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
zprintf("%*s" "zero case" "\n", calldepth, "");
|
||||
|
||||
// first quadrant
|
||||
if (0 < bsplit && 0 < csplit)
|
||||
{
|
||||
zprintf("%*s" "entering first quadrant." "\n", calldepth, "");
|
||||
|
||||
quadrant_search(
|
||||
mask >> 1,
|
||||
bi, bsplit,
|
||||
ci, csplit,
|
||||
calldepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
zprintf("%*s" "empty first quadrant." "\n", calldepth, "");
|
||||
}
|
||||
|
||||
// fourth quadrant
|
||||
if (bsplit < bn && csplit < cn)
|
||||
{
|
||||
zprintf("%*s" "entering fourth quadrant." "\n", calldepth, "");
|
||||
|
||||
quadrant_search(
|
||||
mask >> 1,
|
||||
bi + bsplit, bn - bsplit,
|
||||
ci + csplit, cn - csplit,
|
||||
calldepth);
|
||||
}
|
||||
else
|
||||
{
|
||||
zprintf("%*s" "empty fourth quadrant." "\n", calldepth, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
else for (int i = 0; i < bn; i++)
|
||||
{
|
||||
for (int j = 0; j < cn; j++)
|
||||
{
|
||||
assert((a | b[bi + i]) == c[ci + j]);
|
||||
|
||||
printf("%2i (0b%05b) | %2i [%2i] "
|
||||
"(0b%05b) == %2i [%2i] (0b%05b)" "\n",
|
||||
a, a,
|
||||
b[bi + i], bi + i, b[bi + i],
|
||||
c[ci + j], ci + j, c[ci + j]);
|
||||
}
|
||||
}
|
||||
|
||||
calldepth--;
|
||||
}
|
||||
|
||||
void brute_force_search(int bn, int cn)
|
||||
{
|
||||
for (int bi = 0; bi < bn; bi++)
|
||||
{
|
||||
for (int ci = 0; ci < cn; ci++)
|
||||
{
|
||||
if ((a | b[bi]) == c[ci])
|
||||
{
|
||||
printf("%2i (0b%05b) | %2i [%2i] "
|
||||
"(0b%05b) == %2i [%2i] (0b%05b)" "\n",
|
||||
a, a,
|
||||
b[bi], bi, b[bi],
|
||||
c[ci], ci, c[ci]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
puts("divide-and-conquer:");
|
||||
|
||||
quadrant_search(32, 0, 10, 0, 20, 0);
|
||||
|
||||
puts("");
|
||||
|
||||
puts("brute-force:");
|
||||
brute_force_search(10, 20);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
242
spikes/sorted-sparse-list-insert.c
Normal file
242
spikes/sorted-sparse-list-insert.c
Normal file
|
|
@ -0,0 +1,242 @@
|
|||
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#define N (256)
|
||||
|
||||
#define M (255)
|
||||
|
||||
int headtails[N], next[N], globalhead = -1;
|
||||
|
||||
bool in[N];
|
||||
|
||||
void init()
|
||||
{
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
headtails[i] = -1;
|
||||
|
||||
next[i] = -1;
|
||||
|
||||
in[i] = false;
|
||||
}
|
||||
}
|
||||
|
||||
void print()
|
||||
{
|
||||
puts("print():");
|
||||
|
||||
for (int i = 0; i < N; i++)
|
||||
{
|
||||
if (headtails[i] != -1)
|
||||
{
|
||||
printf(" " "headtails[%3i (0b%08b)] = %i" "\n", i, i, headtails[i]);
|
||||
}
|
||||
}
|
||||
|
||||
printf("globalhead = %i\n", globalhead);
|
||||
|
||||
for (int index = globalhead; index != -1; index = next[index])
|
||||
{
|
||||
printf(" " "index = %i\n", index);
|
||||
}
|
||||
}
|
||||
|
||||
void insert(int index)
|
||||
{
|
||||
printf("insert():" "\n");
|
||||
|
||||
assert(!in[index]);
|
||||
|
||||
printf(" " "index = %i (0b%08b)" "\n", index, index);
|
||||
|
||||
int head = index & 1 ? index & ~(index & -index) : index, prevhead = -1;
|
||||
|
||||
printf(" " "head = %i (0b%08b)" "\n", head, head);
|
||||
|
||||
// while they're blank or we beat them:
|
||||
while (headtails[head] == -1 || index < headtails[head])
|
||||
{
|
||||
headtails[head] = index;
|
||||
|
||||
printf(" " "headtails[%i] = %i" "\n", head, index);
|
||||
|
||||
prevhead = head, head = head & ~(head & -head);
|
||||
|
||||
printf(" " "head = %i (0b%08b)" "\n", head, head);
|
||||
}
|
||||
|
||||
// there should be only two reasons why we're stopped:
|
||||
// - because we hit the limits of the list
|
||||
// - because we found someone who beat us.
|
||||
|
||||
if (headtails[head] < index)
|
||||
{
|
||||
printf(" " "hit someone with a better head" "\n");
|
||||
|
||||
printf(" " "prevhead = %i (0b%08b)" "\n", prevhead, prevhead);
|
||||
|
||||
if (prevhead == -1)
|
||||
{
|
||||
// if we got beat imeedately, connect to them.
|
||||
|
||||
assert(headtails[head] == head);
|
||||
|
||||
assert(in[head]);
|
||||
|
||||
next[head] = index;
|
||||
|
||||
printf(" " "next[%i] = %i" "\n", head, next[head]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we must be coming out of the bottom half
|
||||
|
||||
// and if we lost, then we know there must be elements in the
|
||||
// first half that should come before us.
|
||||
|
||||
// and that we should connect to their tail.
|
||||
|
||||
// so the top-half's tail's "next" should point to us.
|
||||
|
||||
// and we also know that the top-half's tail comes right before
|
||||
// our previous's head.
|
||||
|
||||
int tophalftail = headtails[prevhead - 1];
|
||||
|
||||
printf(" " "tophalftail = %i" "\n", tophalftail);
|
||||
|
||||
assert(tophalftail != -1);
|
||||
|
||||
next[tophalftail] = index;
|
||||
|
||||
printf(" " "next[%i] = %i" "\n", tophalftail, next[tophalftail]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" " "hit the lower limit of the list" "\n");
|
||||
|
||||
globalhead = index;
|
||||
|
||||
printf(" " "globalhead = %i" "\n", globalhead);
|
||||
}
|
||||
|
||||
int n = ~index & M;
|
||||
int tail = index & 1 ? index : index | (n & -n), prevtail = -1;
|
||||
|
||||
printf(" " "tail = %i (0b%08b)" "\n", tail, tail);
|
||||
|
||||
// while they're blank:
|
||||
while (headtails[tail] == -1 || headtails[tail] < index)
|
||||
{
|
||||
headtails[tail] = index;
|
||||
|
||||
printf(" " "headtails[%i] = %i" "\n", tail, index);
|
||||
|
||||
prevtail = tail, tail = tail | (n = ~tail & M, n & -n);
|
||||
|
||||
printf(" " "tail = %i (0b%08b)" "\n", tail, tail);
|
||||
}
|
||||
|
||||
// there should be only two reasons why we're stopped:
|
||||
// - because we hit the limits of the list
|
||||
// - because we found someone who beat us.
|
||||
|
||||
if (index < headtails[tail])
|
||||
{
|
||||
printf(" " "hit someone with a better tail" "\n");
|
||||
|
||||
printf(" " "prevtail = %i (0b%08b)" "\n", prevtail, prevtail);
|
||||
|
||||
if (prevtail == -1)
|
||||
{
|
||||
// if we got beat imeedately, connect to them.
|
||||
|
||||
assert(headtails[tail] == tail);
|
||||
|
||||
assert(in[tail]);
|
||||
|
||||
next[index] = tail;
|
||||
|
||||
printf(" " "next[%i] = %i" "\n", index, next[index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
// we must be coming out of the top half
|
||||
|
||||
// and if we lost, then we know there must be elements in the
|
||||
// second half that should come after us.
|
||||
|
||||
// and that we should connect to their head.
|
||||
|
||||
// so we should point to the bottom half's "head"
|
||||
|
||||
// and we also know that the bottom half's haed comes right before
|
||||
// our previous's tail.
|
||||
|
||||
int bottomhalfhead = headtails[prevtail + 1];
|
||||
|
||||
printf(" " "bottomhalfhead = %i" "\n", bottomhalfhead);
|
||||
|
||||
assert(bottomhalfhead != -1);
|
||||
|
||||
next[index] = bottomhalfhead;
|
||||
|
||||
printf(" " "next[%i] = %i" "\n", index, next[index]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf(" " "hit the lower limit of the list" "\n");
|
||||
|
||||
next[index] = -1;
|
||||
|
||||
printf(" " "next[%i] = %i" "\n", index, next[index]);
|
||||
}
|
||||
|
||||
in[index] = true;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
puts("hello, world!");
|
||||
|
||||
init();
|
||||
|
||||
print();
|
||||
|
||||
insert(42); print();
|
||||
|
||||
/* insert(200); print();*/
|
||||
|
||||
/* insert(128); print();*/
|
||||
|
||||
insert(224); print();
|
||||
|
||||
/* insert(1); print();*/
|
||||
/* */
|
||||
/* insert(255); print();*/
|
||||
|
||||
insert(96); print();
|
||||
|
||||
insert(97); print();
|
||||
|
||||
insert(98); print();
|
||||
|
||||
insert(99); print();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Loading…
Reference in a new issue