import ranrot.*; // // System // record System ( Pointer[RanrotBGen] r, Int n, Vector[Int] board, Vector[Int] rdiag, Vector[Int] ldiag, Int e, ); System: n, r [ var s = System: ; s.n = n; s.r = &r; s.board resize: n; s.rdiag resize: 2*n; s.ldiag resize: 2*n; sample: s; return s; ] sample: System s { for (range: s.n) each: [ x -> s.board[x] = x; ]; // biased, valid initial board... // burn-in for: (range: 100) each: [ i -> var r1 = s.r^ randomInt: 0, s.n-1; var r2 = s.r^ randomInt: 0, s.n-1; swap: s.board[r1], s.board[r2]; ] setDiags: s; s.e = computeEnergy: s; } setDiags: System s [ s.rdiag each: [ v -> v = 0; ]; s.ldiag each: [ v -> v = 0; ]; (range: s.n) each: [ x -> s.rdiag[s.board[x]-x+s.n] += 1; s.ldiag[s.board[x]+x] += 1; ]; ] computeEnergy: System s [ var oldr = s.rdiag; var oldl = s.ldiag; s.rdiag each: [ v -> v = 0; ]; s.ldiag each: [ v -> v = 0; ]; (range: s.n) each: [ x -> s.rdiag[s.board[x]-x+s.n] += 1; s.ldiag[s.board[x]+x] += 1; ]; //(range: (size: oldr)) each: [ x -> if: oldr[x] != s.rdiag[x] then: [ println: "rdiag corrupted" ]; ]; //(range: (size: oldl)) each: [ x -> if: oldl[x] != s.ldiag[x] then: [ println: "ldiag corrupted" ]; ]; var e = 0; s.rdiag each: [ v -> e += max: v-1, 0; ]; s.ldiag each: [ v -> e += max: v-1, 0; ]; // avoid side effect s.rdiag = oldr; s.ldiag = oldl; return e; ] print: System s [ println: "board:"; for: s.board each: [ v -> //println: v; for: (range: v) each: [ print: ". "; ]; print: "x "; for: (range: s.n-v-1) each: [ print: ". "; ]; println: ; ]; //println: "energy: ", s.e, "[", (computeEnergy: s), "]"; println: "energy: ", (computeEnergy: s); ];