简体   繁体   中英

Creating an N by N grid of letters so that no two adjacent letters are the same

I need to print out a N by N grid containing the letters A to F, so that no two adjacent letters are the same. The code below prints out an N by N grid, however I can only get the letters on the left and right to be different. I can't find a way to get the letters above and below to be different as well. I need to solve this problem without the use of arrays. The letters have to be randomized.

public static void main(String[] args) {
    int N = StdIn.readInt();
    for (int column = 0; column < N; column++) {
        int x = 0;

        for (int row = 0; row < N; row++) {

            int c = (int) (Math.random() * 6 + 1);

            while (x == c) {
                c = (int) (Math.random() * 6 + 1);
            }
            if (c == 1) {
                System.out.print("A ");
            }
            if (c == 2) {
                System.out.print("B ");
            }
            if (c == 3) {
                System.out.print("C ");
            }
            if (c == 4) {
                System.out.print("D ");
            }
            if (c == 5) {
                System.out.print("E ");
            }
            if (c == 6) {
                System.out.print("F ");
            }

            x = c;

        }

        System.out.println();

    }

I did you the favor of simplifying your for loop a bit

for (int row = 0; row < N; row++) {
  char c = (char) (Math.random() * 6 + 'A');
  while (x == c) {
    c = (char) (Math.random() * 6 + 'A');
  }
  System.out.print(c + " ");
  x = c;
}

That uses the ASCII values of the letters so you don't need a big if statement.

Your question is unclear about what storage formats are allowed, but consider this: If you could store each row as a string (one temporary string that is deleted after moving on a row), how would you check if a letter in the row you're building below it matches the letter above? Think of a string as an array (which is its true form).

Easy to do with 2 queues.

If you analyse the below, you should realise that you really only need one size N linked-list.

current is the current row, each new element is simply enqueued.

last is the previous row. It takes the value of current once you're done with a row, then the first element we want to check is at the front.

I separated the first row from the others to make things simpler and more understandable.

  int N = 10;
  Queue<Character> last,
                   current = new Queue<Character>();
  char prev = '0';
  for (int row = 0; row < N; row++)
  {
     char c;
     do { c = (char)(Math.random() * 6 + 'A'); }
     while (prev == c);
     current.enqueue(c);
     prev = c;
     System.out.print(c + " ");
  }
  System.out.println();
  for (int col = 1; col < N; col++)
  {
     last = current;
     current = new Queue<Character>();
     prev = '0';
     for (int row = 0; row < N; row++)
     {
        char c;
        do { c = (char)(Math.random() * 6 + 'A'); }
        while (last.peek() == c || prev == c);
        current.enqueue(c);
        last.dequeue();
        prev = c;
        System.out.print(c + " ");
     }
     System.out.println();
  }

You can do this with a pair of stacks and a candidate character. The NxN grid is represented by a stack containing up to N times N characters. Try this with a deck of cards, with the stacks represented by two spots for stacks of cards, to get a feel for how it works.

  1. Create two stacks, A and B. Keep a running index for the number of items in A.
  2. Generate a random number. This is your Candidate.
  3. If there are a multiple of N items in stack A (you just finished a row) skip to step 6.
  4. Pop the top of stack A and store it as Check.
  5. Is Check adjacent to Candidate? If yes, push Check back onto stack A, and go back to step 2. (null is non-adjacent)
  6. Push Check onto stack B. Pop N-2 more items, pushing them onto stack B as you go.
  7. Pop the top of stack A and store it as Check. (There should be N-1 items in stack B, and one in Check: a whole row)
  8. Is Check adjacent to Candidate? (null is non-adjacent) If yes, push Check back onto stack A, pop each of the items from stack B, pushing onto stack A as you go, and go back to step 2.
  9. push check back onto stack A. Pop each item from stack B, pushing onto stack A as you go.
  10. Push Candidate onto stack A.
  11. Increment the index. If we now have NxN items in stack A, we're done: pop everything off stack A, writing them down in an NxN grid as you go. Otherwise return to step 2.

Basically, you're drawing a card, and checking up to two items. Because stack A is guaranteed never to have adjacencies in it, once an item is placed, it never has to be removed. So once you get to the end, you're done.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM