Home > Back-end >  create a randomly generated two dimensional matrix that has all unique elements
create a randomly generated two dimensional matrix that has all unique elements

Time:12-07

I am trying to create a 3x3 matrix that has the numbers 1 to 9 generated at different locations each time you run the code. the method I came up with does not work and I can't find out why it doesn't work, so if anyone could point out the reason why it does not work it would be really really appreciated.

and if anyone knows how to solve this problem in any other way please let me know.

Here's the method I created:

public static int[][] randgen() {
        Random rand = new Random();
        int[][] a = new int[3][3];
        int x;
        
        for(int i = 0; i<a.length; i  ) {
            for (int j = 0; j < a.length; j  ) {
                a[i][j] = rand.nextInt(8)  1;
                
                do {
                    x = 1;
                    for(int k = 0; k<i; k  ) {
                        for(int l = 0; l<j; l  ) {
                            if(a[k][l] == a[i][j]) {
                                x  ;
                            }
                        }
                    }
                    if(x!=1) {
                        a[i][j] = rand.nextInt(8)  1;
                    }
                } while (x!=1); //this while loop I'm using as a way to find duplicates and keep changing up the number until I reach an integer with no duplicates, and this is the part of the program that is failing and I can't understand why
            }
        }
        
    }

I've tried creating a sorted algorithm and then making a function to shuffle some of the elements which also did not work.

The only thing that worked for me is creating an ArrayList and then printing it out in a way that it looks like an array

CodePudding user response:

The problem with your code is that you are only checking if the current element has duplicates in the rows above it and the columns to the left of it. This means that if an element has a duplicate in the same row or the same column, your code will not detect it and will generate a matrix with duplicate elements.

To fix this, you can change your code to check for duplicates in the entire matrix, rather than just the rows above and columns to the left of the current element. You can do this by using a nested loop to iterate over the entire matrix, and then checking if the current element has a duplicate in the rest of the matrix.

Here is an example of how you can do this:

public static int[][] randgen() {
    Random rand = new Random();
    int[][] a = new int[3][3];
    int x;
        
    for(int i = 0; i<a.length; i  ) {
        for (int j = 0; j < a.length; j  ) {
            a[i][j] = rand.nextInt(8)  1;

            // Check for duplicates in the entire matrix
            do {
                x = 1;
                for(int k = 0; k<a.length; k  ) {
                    for(int l = 0; l<a.length; l  ) {
                        if(a[k][l] == a[i][j]) {
                            x  ;
                        }
                    }
                }
                if(x!=1) {
                    a[i][j] = rand.nextInt(8)  1;
                }
            } while (x!=1);
        }
    }
    return a;
}

Another way to solve this problem is to generate a list of the numbers 1 to 9 in random order, and then assign each element of the matrix to a number in the list. This way, you can ensure that each element in the matrix is unique without having to check for duplicates.

public static int[][] randgen() {
    Random rand = new Random();
    int[][] a = new int[3][3];

    // Create a list of the numbers 1 to 9 in random order
    List<Integer> numbers = IntStream.rangeClosed(1, 9).boxed().collect(Collectors.toList());
    Collections.shuffle(numbers);

    // Assign each element of the matrix to a number in the list
    for(int i = 0; i<a.length; i  ) {
        for (int j = 0; j < a.length; j  ) {
            a[i][j] = numbers.get(i * 3   j);
        }
    }

    return a;
}

CodePudding user response:

I would create an array with 1-9 Then i’d use a for loop with math.random and math.floor repeating over the 3x3 so 9 variables you need

CodePudding user response:

public static int[][] randgen() {
    List<Integer> list = new ArrayList<>(List.of(1,2,3,4,5,6,7,8,9));
    Collections.shuffle(list);
    int[][] result = new int[3][3];
    for( int i = 0; i < 9; i   ) {
        result[i/3][i%3] = list.get(i);
    }
    return result;
}

CodePudding user response:

Another variation...

Populate the list with the numbers 1 to 9 but then pick a random spot from it to fill the next slot of your array. Each time you pick a random spot from the list you remove it.

Might look like:

import java.util.List;
import java.util.ArrayList;
import java.util.Random;
import java.util.Arrays;
class Main {
  
  public static void main(String[] args) {
    Random rand = new Random();
    int[][] a = new int[3][3];

    int counter = 1;
    int totalSpots = a.length * a[0].length; // assumes RECTANGULAR array
    List<Integer> numbers = new ArrayList<Integer>();
    while (counter <= totalSpots) {
      numbers.add(counter);
      counter  ;
    }

    for(int row = 0;row < a.length; row  ) {
      for(int col = 0; col < a[0].length; col  ) {
        int index = rand.nextInt(numbers.size());
        a[row][col] = numbers.get(index);
        numbers.remove(index);
      }
    }

    for(int[] row : a) {
      System.out.println(Arrays.toString(row));
    }
  }
  
}

Sample output:

[5, 3, 6]
[9, 4, 8]
[2, 7, 1]

If we change the size of the array:

int[][] a = new int[5][4];

It sill works:

[7, 3, 6, 11]
[19, 20, 1, 4]
[13, 12, 17, 2]
[5, 18, 9, 16]
[14, 15, 10, 8]
  • Related