1

How do I make it so that when I output the grid when I run the code, no two numbers or letters will be the same? When I currently run this code I could get 3x "L" or 2x "6", how do I make it so that they only appear once?

package polycipher;

import java.util.ArrayList;

public class Matrix {
private char[][] matrix = new char[6][6];
private int[] usedNumbers = new int[50];

{for(int x = 0; x < usedNumbers.length; x++) usedNumbers[x] = -1;}

private final char[] CIPHER_KEY = {'A','D','F','G','V','X'};
private final String validChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";

public Matrix() {
    int random;
    for(int i = 0; i < CIPHER_KEY.length; i++) {
        for(int j = 0; j < CIPHER_KEY.length; j++) {
            validation: while(true) {
                random = (int)(Math.random()*validChars.length()-1);
                for(int k = 0; k < usedNumbers.length; k++) {
                    if(random == usedNumbers[k]) continue validation;
                    else if(usedNumbers[k]==-1) usedNumbers[k] = random;
                }
                break;
            }
            matrix[i][j] = validChars.split("")[random].charAt(0);  
        }
    }
}

public String toString() {
    String output = "   A D F G V X\n";
    for(int i = 0; i < CIPHER_KEY.length; i++) {
        output += CIPHER_KEY[i] + "  ";
        for(int j = 0; j < CIPHER_KEY.length; j++) {
            output += matrix[i][j] + " ";
        }
        output += "\n";
    }
    return output;
}
}
conor tighe.
  • 121
  • 2
  • 19

2 Answers2

3

This should be much faster than validating each random choice:

  1. Store your valid chars into an array;

    char[] valid = validChars.toCharArray();
    
  2. Shuffle the array;

    shuffle(valid)
    
  3. Go through the positions in the matrix, storing the elements in the same order they appear in the shuffled array.

    assert (CIPHER_KEY.length * CIPHER_KEY.length) <= valid.length;
    int k = 0;
    for (int i = 0; i < CIPHER_KEY.length; i++) {
        for (int j = 0; j < CIPHER_KEY.length; j++) {
            matrix[i][j] = valid[k++];
        }
    }
    
Community
  • 1
  • 1
Anderson Vieira
  • 8,919
  • 2
  • 37
  • 48
  • How is this preventing the rng to generate the same char and the same chars ending up in the matrix? – XapaJIaMnu Mar 31 '15 at 18:22
  • 1
    @XapaJlaMnu The `valid` array contains the 36 unique chars from `validChars`. When you shuffle, the 36 chars will just change positions. So you only need to place them into the matrix. There are no duplicates to worry about. – Anderson Vieira Mar 31 '15 at 18:26
  • @XapaJIaMnu have you read the answer? Where do you see a randoml number generator being used in the code? If you shuffle a deck of 36 different cards and lay them out on a table, will you have repetitions? That's what the above code does. – JB Nizet Mar 31 '15 at 18:27
  • @JBNizet Just now I realize what this solution is doing. My bad. – XapaJIaMnu Mar 31 '15 at 18:28
1

Use a set and generate a new random if the old random number is in the map: Pseudocode:

Set<Integer> set = new HashSet<Integer>();
for () {
    int random = (int)(Math.random()*validChars.length()-1);
    //Your code for validation here (move it to a function)
    while (!set.contains(random)){
         int random = (int)(Math.random()*validChars.length()-1);
         //Your code for validation here (move it to a function)
    }
    //If we exit this loop it means the set doesn't contain the number
    set.add(random);
    //Insert your code here
}
XapaJIaMnu
  • 1,408
  • 3
  • 12
  • 28