4-variable-simplifier/spikes/linear-add.c

172 lines
3.6 KiB
C

#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;
}