crooks

combinatorial rooks
git clone https://a3nm.net/git/crooks/
Log | Files | Refs

commit 8729df936060e870fdda89e0242179fc5ef6707d
parent 1cd7bbf5aba3a968c6ffbac5e4d1cbe65f538d90
Author: Antoine Amarilli <a3nm@a3nm.net>
Date:   Sat,  7 Jun 2014 19:21:27 +0200

update violations incrementally

Diffstat:
main.c | 131++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 100 insertions(+), 31 deletions(-)

diff --git a/main.c b/main.c @@ -117,31 +117,72 @@ void print_violations() { printf("=> %d total violations\n", tot); } -void upd_atk_rm(int i) { +int upd_vio(int z, int x, int y, int v, int d) { + int delta = 0; + int old = A[z][x][y]; + int val, new; + if (v > 0) + new = A[z][x][y] | (1 << d); + else + new = A[z][x][y] & ~(1 << d); + for (int p = 0; p < N; p++) { + if (p != z) { + val = ((new | (1 << 0)) == 7 ? 1 : 0) - ((old | (1 << 0)) == 7 ? 1 : 0); + V[p][x][y] += val; + if (G[p][x][y]) delta += val; + } + if (p != x) { + val = ((new | (1 << 1)) == 7 ? 1 : 0) - ((old | (1 << 1)) == 7 ? 1 : 0); + V[z][p][y] += val; + if (G[z][p][y]) delta += val; + } + if (p != y) { + val = ((new | (1 << 2)) == 7 ? 1 : 0) - ((old | (1 << 2)) == 7 ? 1 : 0); + V[z][x][p] += val; + if (G[z][x][p]) delta += val; + } + } + return delta; +} + +int upd_atk_rm(int i) { // update A to reflect the fact that rook i is about to be removed int z = R[i][0]; int x = R[i][1]; int y = R[i][2]; + //printf("rmv rook at %d %d %d\n", z, x, y); + int delta = 0; for (int p = 0; p < N; p++) { + delta += upd_vio(p, x, y, -1, 0); A[p][x][y] &= ~(1 << 0); // p x y attacked by z x y along direction z + delta += upd_vio(z, p, y, -1, 1); A[z][p][y] &= ~(1 << 1); // z p y attacked by z x y along direction x + delta += upd_vio(z, x, p, -1, 2); A[z][x][p] &= ~(1 << 2); // z x p attacked by z x y along direction y } + delta -= V[z][x][y]; + return delta; } -void upd_atk_add(int i) { +int upd_atk_add(int i) { // update A to reflect the fact that rook i was just added int z = R[i][0]; int x = R[i][1]; int y = R[i][2]; + //printf("added rook at %d %d %d\n", z, x, y); + int delta = 0; for (int p = 0; p < N; p++) { + delta += upd_vio(p, x, y, 1, 0); A[p][x][y] |= 1 << 0; + delta += upd_vio(z, p, y, 1, 1); A[z][p][y] |= 1 << 1; + delta += upd_vio(z, x, p, 1, 2); A[z][x][p] |= 1 << 2; } + delta += V[z][x][y]; + return delta; } - void num_attacks() { // generate A from scratch for (int i = 0; i < N; i++) @@ -155,26 +196,6 @@ void num_attacks() { } -void check_attacks() { - // debug: regenerate A from scratch - // and check that the previous version was already correct - int backup[MAXN][MAXN][MAXN]; - for (int i = 0; i < N; i++) - for (int j = 0; j < N; j++) - for (int k = 0; k < N; k++) - backup[i][j][k] = A[i][j][k]; - num_attacks(); - for (int i = 0; i < N; i++) - for (int j = 0; j < N; j++) - for (int k = 0; k < N; k++) - if (backup[i][j][k] != A[i][j][k]) { - print_attacks(); - printf("ERROR at %d %d %d\n", i, j, k); - exit(1); - } -} - - int num_violations() { // regenerate V from scratch // returns total number of violations @@ -205,6 +226,48 @@ int num_violations() { return tot; } +void check_increment(int ntot) { + //printf("CHECK: before\n"); + //print_all_violations(); + // debug: regenerate A, V from scratch + // and check that the previous version was already correct + int backupA[MAXN][MAXN][MAXN]; + int backupV[MAXN][MAXN][MAXN]; + for (int i = 0; i < N; i++) + for (int j = 0; j < N; j++) + for (int k = 0; k < N; k++) { + backupA[i][j][k] = A[i][j][k]; + backupV[i][j][k] = V[i][j][k]; + } + num_attacks(); + int rntot = num_violations(); + //printf("CHECK: after\n"); + //print_all_violations(); + for (int i = 0; i < N; i++) + for (int j = 0; j < N; j++) + for (int k = 0; k < N; k++) { + if (backupA[i][j][k] != A[i][j][k]) { + print_attacks(); + printf("ERROR attacks at %d %d %d\n", i, j, k); + exit(1); + } + if (backupV[i][j][k] != V[i][j][k]) { + print(); + print_attacks(); + print_all_violations(); + printf("ERROR violations at z=%d x=%d y=%d, had %d computed %d\n", i, j, k, backupV[i][j][k], V[i][j][k]); + exit(1); + } + } + if (ntot != rntot) { + print_all_violations(); + print_violations(); + printf("total violation miscount, had %d computed %d\n", ntot, rntot); + exit(1); + } +} + + void init_pos() { // create initial position for (int i = 0; i < N; i++) @@ -283,11 +346,12 @@ int random_move() { R[rook][1] = nx; R[rook][2] = ny; // recompute everything + // TODO: don't do this upd_atk_add(rook); return num_violations(); } -void position(int i) { +int position(int i) { // position rook i that was just removed // TODO: more efficient (pqueue?) // TODO more clever (chance to select cell with non-optimal number of @@ -324,7 +388,7 @@ void position(int i) { R[i][0] = bz; R[i][1] = bx; R[i][2] = by; - upd_atk_add(i); + return upd_atk_add(i); } void spawn_rook() { @@ -362,6 +426,7 @@ int main(int argc, char **argv) { // compute number of attacks and violations num_attacks(); tot = num_violations(); + //check_increment(); //print(); int useless = 0; @@ -385,20 +450,24 @@ int main(int argc, char **argv) { int y = R[rook][2]; // remove the rook + //printf("tot is %d will rm %d\n", tot, rook); G[z][x][y] = 0; - upd_atk_rm(rook); + tot += upd_atk_rm(rook); + //printf("tot is %d after rm\n", tot); R[rook][0] = MAXN; R[rook][1] = MAXN; R[rook][2] = MAXN; if(debug) print_attacks(); - //check_attacks(); + //check_increment(); // recompute V without the rook - num_violations(); + //num_violations(); + //printf("check_incr\n"); + //check_increment(tot); // choose next position - position(rook); + tot += position(rook); int otot = tot; int pred = V[R[rook][0]][R[rook][1]][R[rook][2]]; @@ -406,11 +475,11 @@ int main(int argc, char **argv) { if(debug) print_all_violations(); // recompute number of violations - tot = num_violations(); + //tot = num_violations(); if(debug) print_all_violations(); int npred = V[R[rook][0]][R[rook][1]][R[rook][2]]; - if (debug && npred != pred) { + if (npred != pred) { printf("violation mispredict: thought %d and had %d!\n", pred, npred); exit(1); }