LIB "threadtasks.lib";

string code = "proc newBoard(int n) {
  intmat board[n][n]=0;
  return(board);
}

proc legalMove(intmat board, int n, int x, int y) {
  for (int i = 1; i < x; i++) {
    if (board[i,y]) { return(0); };
    if (i < y) { if (board[x-i,y-i]) { return(0); }; };
    if (y+i <= n) { if (board[x-i,y+i]) { return(0); }; };
  }
  return(1);
}

proc countRec(intmat board, n, x) {
  int result = 0;
  for (int y = 1; y <= n; y++) {
    if (legalMove(board, n, x, y)) {
      if (x == n) {
        result++;
      } else {
        board[x,y] = 1;
	result = result + countRec(board, n, x+1);
	board[x,y] = 0;
      }
    }
  }
  return(result);
}

proc countSeq(int n) {
  intmat board[n][n] = newBoard(n);
  return(countRec(board, n, 1));
}

proc countParInstance(intmat board) {
  return(countRec(board, nrows(board), 2));
}

proc countPar(int n) {
  intmat b;
  int total = 0;
  int i, j;
  for (i = 1; i <= n; i++) {
      b = newBoard(n);
      b[1,i] = 1;
      task tasks(i) = runTask(\"countParInstance\", b);
  }
  for (i = 1; i <= n; i++) {
    total = total + getResult(tasks(i));
  }
  return(total);
}";
execute(code);

createTaskSystem(10);
initWorkersFromString(code);
startTaskSystem();

proc nqueens(int n) {
  printf("Solving the N-queens problem for N=%s", n);
  system("--ticks-per-sec",1000);
  int tseq = rtimer;
  int nseq = countSeq(n);
  tseq = rtimer - tseq;
  printf("Sequential: %s solutions (%s milliseconds)", nseq, tseq);
  int tpar = rtimer;
  int npar = countPar(n);
  tpar = rtimer - tpar;
  printf("Parallel:   %s solutions (%s milliseconds)", npar, tpar);
}
;
