-2

I translated Java code into R. I need to check if all lines are translated correctly.

Some part most probably is correct because I ran it and R says:

Error: C stack usage 7970192 is too close to the limit.

I am not sure which part went wrong because when I compile it, it doesn't show any error for all the lines except when I try to run it

Original Java code:

  public static void printQueens(int[] q) {
      int n = q.length;
      for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
          if (q[i] == j) StdOut.print("Q ");
          else           StdOut.print("* ");
        }
        StdOut.println();
      }  
      StdOut.println();
    }


  /***************************************************************************/

    public static void enumerate(int n) {
      int[] a = new int[n];
      enumerate(a, 0);
    }

  public static void enumerate(int[] q, int k) {
    int n = q.length;
    if (k == n) printQueens(q);
    else {
      for (int i = 0; i < n; i++) {
        q[k] = i;
        if (isConsistent(q, k)) enumerate(q, k+1);
      }
    }
  }  


  public static void main(String[] args) {
    int n = Integer.parseInt(args[0]);
    enumerate(n);
  }

}

R code to be corrected

# Prints n-by-n placement of queens from permutation q
printQueens <- function(q) {
  n = q.length
  for(i in seq_len(n)) {
    for(j in seq_len(n)) {
      if(q[i] == j) print("Q ")
      else{          print("* ")}
    }
    sep="/n"
  }  
  sep="/n"
}

#Try all permutations using backtracking

enumerate <- function(q, k) {
   n = q.length;
   if(k == n) print(Queens(q))
  else {
    for(i in seq_len(n)) {
      q[k] = i
      if (isConsistent(q, k)) enumerate(q, k+1)
    }
  }
}  

enumerate <- function(n) {
  a = n
  enumerate(a);
}

main <- function(args) {
  n =args[0];
  enumerate(n);
}
Artem
  • 3,304
  • 3
  • 18
  • 41
yakochang
  • 1
  • 1

1 Answers1

0

The error you indicated (stack usage) means that your code either wrongly translated (very deep recursion occured and function stack call exhausted) or you may be trying to solve very high N-queen problem (N > 30).

There are numerous problems to translate directly your code from Java to R:

  1. Arrays in Java are indexed from 0, in R - from 1. And you will have to redifine the indexing function [] in R.
  2. For-loop however similar have different semantics in R. It has more like foreach functionality. To model Java for-loop in R you have to use while construction.
  3. The source code presented is not full (isConsistent function is absent).

Please see the code which addresses all the problems outlined above:

StdOut.print <- cat
StdOut.println <- function(x) cat("\n")
index1 <- .Primitive('[')
`[.zero-based_vector` <- function(v, i) index1(as.vector(v), i+1)

isConsistent <- function(q, n) {
  i <- 0
  while(i < n) {
    if (q[i] == q[n])           
      return(FALSE)   # same column
    if ((q[i] - q[n]) == (n - i)) 
      return(FALSE)   # same major diagonal
    if ((q[n] - q[i]) == (n - i)) 
      return(FALSE)   # same minor diagonal

    i <- i + 1
  }
  return(TRUE)
}

printQueens <- function(q) {
  n <- length(q)
  for (i in seq.int(n) - 1) {
    for (j in seq.int(n) - 1) {
      if (q[i] == j) 
        StdOut.print("Q ")
      else
        StdOut.print("* ")
    }
    StdOut.println()
  }  
  StdOut.println()
}

enumerate_n <- function(n) {
  a <- integer(n)
  class(a) <- c("zero-based_vector", class(a))

    enumerate_qk(a, 0)
}

enumerate_qk <- function(q, k) {
  n <- length(q)
  if (k == n) {
    printQueens(q)
  } else {
    i <- 0
    while(i < n) {
      q[k + 1] <- i
      if (isConsistent(q, k)) {
        enumerate_qk(q, k + 1)
      }

      i <- i + 1
    }
  }
}  

main <- function(args) {
  n <- as.integer(args[1])
  enumerate_n(n)
}

main(4)

Output:

* Q * * 
* * * Q 
Q * * * 
* * Q * 

* * Q * 
Q * * * 
* * * Q 
* Q * * 

For reference: The full source code published at Queens.java

Artem
  • 3,304
  • 3
  • 18
  • 41