ADT.Sequence|array(int) data = ADT.Sequence(0); void fill(array(int) r1, array(int) r2, array(int) r3, array(int) elems) { if(sizeof(r1)>3) { return; } if(sizeof(elems)==0) { data->add(({r1, r2, r3})); return; } array(int) tmp = elems[1..]; fill(r1+({elems[0]}), r2, r3, tmp); fill(r1, r2+({elems[0]}), r3, tmp); fill(r1, r2, r3+({elems[0]}), tmp); } int to_bin(array(array(int)) rows) { int ret = 0; foreach(rows, array(int) r) { ret = ret << 5; foreach(r, int c) { ret = ret | (1<<c); } } return ret; } int compatible(array(int) a, array(int) b) { for(int i = 0; i < min(sizeof(a), sizeof(b)); ++i) { if(a[i]+b[i] > 1) { return 0; } } return 1; } array(int|array(int)) hash_func(array(int) data, void|int pow2) { if(pow2) { } array(int) st; array(int) o; int fitted; do { fitted = 1; array(int) rowcounts = ({0})*size; o = indices(rowcounts); array(array(int)) table = ({({0})*size})*size; table = map(table, lambda(array arr) {return arr+({});}); foreach(data, int i) { table[i/size][i%size] = 1; rowcounts[i/size] += 1; } sort(rowcounts, table, o); array(int) ht = ({0})*size; st = ({0})*size; for(int i = size-1; i >= 0; --i) { while(st[i] < size && compatible(ht, table[i])==0){ table[i] = Array.unshift(@reverse(Array.pop(table[i]))); ++st[i]; } if(st[i] == size) { fitted = 0; if(pow2) { size <<= 1; } else { ++size; } break; } for(int j = 0; j < size; ++j) { ht[j] += table[i][j]; } } } while(fitted == 0); sort(o, st); return ({size, st}); } void|string size(string prefix, void|int sz) { if(sz) { write("#define %sSIZE %d\n", prefix, sz); } else { return prefix+"SIZE"; } } void table(string prefix, string|int index) { write("%sTABLE[%s]", prefix, ""+index); } void shift(string prefix, string|int index, void|array(int) st) { if(st) { write("int "); } write("%sSHIFT[%s]", prefix, ""+index); if(st) { write(" = {%d", st[0]); foreach(st[1..], int s) { write(", %d", s); } write("};\n"); } } void key(string prefix, string|int index) { write("(((%s)+", ""+index); shift(prefix, index); write(")%%%s)", size(prefix)); } void output_c(string prefix, int sz, array(int) st) { size(prefix, sz); shift(prefix, size(prefix), st); write("int "); table(prefix, size(prefix)); write(";\n#define %skey(index) ", prefix); key(prefix, "index"); write("\n#define %slookup(index) ", prefix); table(prefix, prefix+"key(index)"); write("\n"); } int main() { fill(({}), ({}), ({}), ({0,1,2,3,4})); data = map(data, to_bin); array hf = hash_func(data); output_c("HT_", hf[0], hf[1]); }
Standard input is empty
#define HT_SIZE 232 int HT_SHIFT[HT_SIZE] = {0, 0, 0, 0, 1, 0, 12, 6, 10, 4, 3, 0, 0, 15, 1, 51, 62, 34, 4, 4, 0, 4, 78, 11, 37, 6, 13, 12, 22, 0, 0, 135, 118, 71, 54, 0, 10, 1, 0, 10, 7, 7, 2, 0, 2, 0, 3, 63, 6, 9, 18, 5, 0, 0, 0, 0, 0, 1, 0, 1, 0, 6, 6, 0, 3, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 1, 0, 0, 0, 4, 0, 1, 0, 8, 19, 10, 0, 0, 0, 0, 0, 0, 25, 7, 9, 0, 0, 0, 17, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 5, 0, 0, 2, 10, 0, 0, 0, 0, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; int HT_TABLE[HT_SIZE]; #define HT_key(index) (((index)+HT_SHIFT[index])%HT_SIZE) #define HT_lookup(index) HT_TABLE[HT_key(index)]