Putting a number at random spots in 2D array - java

I have a 2D Array that has 5 rows and 5 columns. I want it so that at 8 random spots in that 2D array (make it pick a random row and column) to put a char of '1'.
What I did was call the Random class and generate a number between 0 and 4 (for the 5 spots of the array) then I have two for loops that run 8 times (for the 8 random spots I want), one that goes through the row, the other through the column.
This is the code I have so far:
char[][] battleship = new char[5][5];
//I didn't include this but I have a for loop that populates all the rows and columns with a char of '0'
Random random = new Random();
int randomNum = random.nextInt(4);
for (int i = 0; i < 8; i++)
{
for (int o = 0; o < 8; o++)
{
battleship[randomNum][randomNum] = '1';
}
}
The issue I am getting is that instead of it putting the '1' at 8 random spots, it's putting in 5 spots back to back.
How do I correct this?
Here is an example of the output:
0
0
0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
1
1
1
0
0
0
0
0
The '1' isn't in 8 random spots.
Where did I go wrong?

Having nested loop running 8 times each will iterate it 64 times. You don't need nested loops to do that. One of the easy ways will be using a while-loop and distribute the 8 random spots till all 8 spots are taken:
int occupiedSpots = 0;
Random random = new Random();
while(occupiedSpots < 8){
int x = random.nextInt(array.length);
int y = random.nextInt(array[0].length);
if(battleship[x][y] == 0){
battleship[x][y] = 1;
occupiedSpots++;
}
}
Also ensure you are generating new random numbers in every iteration, else you will always be using the same random values.
Using a while-loop also ensures all 8 spots are on different locations. If you simply implement it with a for-loop without checking, there is a tendency some spots may fall on the same location twice.

You are getting a random number before the loop, so it never changes. Basically, randomNum variable was rolled and assigned once - you should call the nextInt method multiple times. Try this:
for (int i = 0; i < 8; i++) {
int randomX = random.nextInt(battleship.length);
int randomY = random.nextInt(battleship[randomX].length);
battleship[randomX][randomY] = '1';
}
Note that this do not address the issue of collisions - you can be unlucky enough to get the same position multiple times and fill only 1-7 spots.
From the documentation of nextInt(int):
Returns a pseudorandom, uniformly distributed int value between 0
(inclusive) and the specified value (exclusive), drawn from this
random number generator's sequence.

I would take a different approach. If you pretend your 5x5 2D array is actually one long 25-element one-dimensional array, than basically all you need to do is produce 8 distinct numbers between 0 and 25.
Your code also doesn't guarantee the 8 random numbers are all different.
Try this:
// Initialize random number array
int[] positions = new int[25];
for (int i = 0; i < 25; i++) {
positions[i] = i;
}
char[][] battleship = new char[5][5];
// Fill the battleship field
for (int i = 0; i < 8; i++) {
int random = (int)(Math.random() * (25 - i - 1));
int position = positions[random];
positions[random] = positions[25 - i - 1];
int row = position / 5;
int col = position % 5;
battleship[row][col] = '1';
}
// Show the field
for (int row = 0; row < 5; row++) {
for (int col = 0; col < 5; col++) {
System.out.print(battleship[row][col] + " ");
}
System.out.println();
}

Related

Fill array with zero in random places

So, what I am trying to do is to fill a 2D array with zeros in random places a specific amount of times. Let's say that it has to be 20 zeros in an array of 90 places. What I have done so far is to declare a 2D array and fill it with random numbers. And my next thought was to simply choose random positions and replace them with zeros. Any idea how I could do that?
int[][] myboard = new int[9][9];
for (int i = 0; i < myboard.length; i++) {
for (int j = 0; j < myboard[i].length; j++) {
myboard[i][j] = (int) (Math.random() * 10);
}
}
It is a rather simple way to achieve the goal, but it should do the job. So you need to get the length of each row. After you have done that you can call a function that will give you a random number between some start point and the length of the row. Here is some code sample to show you what I mean:
import java.util.concurrent.ThreadLocalRandom;
import java.util.Arrays;
public class Example {
public static void main(String []args) {
int[][] myboard = new int[9][9];
for (int i = 0; i < myboard.length; i++) {
for (int j = 0; j < myboard[i].length; j++) {
// fill the row with random vals
myboard[i][j] = GetRandomNumber(0, myboard[i].length);
}
// sneak as much zeros as your heart content
int random = GetRandomNumber(0, myboard[i].length);
myboard[i][random] = 0;
}
System.out.println(Arrays.deepToString(myboard));
}
private static int GetRandomNumber(int min, int max) {
/*
min is the start point
max is the curr row len
*/
return ThreadLocalRandom.current().nextInt(min, max);
}
}
A pseudo code would look like:
while (num_zeros_filled < 20):
row = random()%total_rows
col = random()%total_cols
if (arr[row][col] == 0): # already filled in with 0
continue
else:
arr[row][col] = 0
num_zeros_filled += 1
This, however, could take infinite time theoretically if only those cells are generated which have already been filled with 0. A better approach would be to map the two-dimensional array into a 1-d array, and then sample out only from those cells which haven't been filled with 0 yet.

How do I get the code to print random numbers in all the elements of the 2d array?

I got the 2d array to print but with all zero's and the only random number comes up on the bottom right corner
How do I get the code to print random numbers in all the elements of the 2d array?
Here is my code:
public static void main(String[] args) {
int columns = 8;
int rows = 4;
int rLow = 2;
int rHigh = 9;
printRandos(columns, rows, rLow, rHigh);
}
public static void printRandos(int clmn, int rws, int rlow, int rhigh) {
Random rando = new Random();
int randoNum = rlow + rando.nextInt(rhigh);
int[][] randoArray = new int[rws][clmn];
for (int i = 0; i < rws; i++) {
for (int k = 0; k < clmn; k++) {
randoArray[rws - 1][clmn - 1] = randoNum;
System.out.print(randoArray[i][k] + " ");
}
System.out.print("\n");
}
}
for (int i = 0; i < rws; i++)
{
for (int k = 0; k < clmn; k++)
{
int randoNum = rlow + rando.nextInt(rhigh);
randoArray[i][k] = randoNum;
System.out.print(randoArray[i][k]+" ");
}
System.out.print("\n");
}
your mistake inside the inner for loop of the printRandos method. Firstly your random number is outside the loop so your array elements were receiving the same number all the time. Another mistake is that you are assigning the value to the same array element all the time i.e rws-1 and clmn-1 .
inside your inner loop replace it with this:
int randoNum = rlow + rando.nextInt(rhigh);
randoArray[i][k] = randoNum;
System.out.print(randoArray[i][k]+" ");
Your bug is in this line:
randoArray[rws-1][clmn-1] = randoNum;
This stores your random number into randoArray[rws-1][clmn-1] each time, which as you noticed, is the bottom right corner. rws is always 4, and clmn is always 8. So you store the same number there 32 times, which gives the same result as storing it only once.
In the following line you are correctly printing the number from the current array location:
System.out.print(randoArray[i][k]+" ");
An int array comes initialized with all zeroes, and since except for the last corner you have not filled anything into your array, 0 is printed.
Also if you want different random numbers in all the cells, you would need to call rando.nextInt() inside your innermost for loop.
Unless you need this 2-D array for some purpose (which doesn't show from the minimal example code that you have posted), you do not need it for printing a matrix of random numbers, i.e., you may just print the numbers form within your loop without putting them into the array first.
Finally if rhigh should be the highest possible random number in the array, you should use rando.nextInt(rhigh - rlow + 1). With rlow equal to 2 and rhigh equal to 9 this will give numbers in the range from 0 inclusive to 9 - 2 + 1 = 8 exclusive, which means that after adding to rlow = 2 you will get a number in the range from 2 to 10 exclusive, in other words, to 9 inclusive.
I am on purpose leaving to yourself to fix your code based on my comments. I believe your learning will benefit more from working it out yourself.
Your assign the array value outside the array length
int[][] randoArray = new int[rws][clmn];
randoArray[rws][clmn] = randoNum;
Here randoArray[rws] is out of bounds.

java.lang.ArrayIndexOutOfBoundsException - Fill new Array with looped Data from other Array

I have a Scanner which sets the arrayLenght, then the array is filled with random numbers between 0 and 1000.
Next, I want to get all even numbers and store them in a new array. For that, I created a loop to count the size of the new array.
Second, I run the loop again and want to fill the new array with all even numbers from the original array.
If I test with a length of 1 or 2, the code sometimes works and the new array can be generated. If I work with an array lenght of like 10, I get an Error like:
java.lang.ArrayIndexOutOfBoundsException: Index 5 out of bounds for length 4
For this Error example I have set up an array with a length of 10. I got 4 Even Numbers in it. The Count worked and changed to "4". Yet I get an Error.
//GET A COUNT FOR THE LENGHT OF ARRAY
int count = 0;
for(int i = 0; i < arrayLenght; i++){
if (dasArray[i] % 2 == 0) {
count++;
}
}
System.out.println("COUNT " + count);
//CREATE NEW ARRAY WITH ALL EVEN NUMBERS AND THE LENGHT OF COUNT
int []dasGeradeArray = new int[count];
for(int i = 0; i < arrayLenght; i++){
if (dasArray[i] % 2 == 0) {
dasGeradeArray[i]= dasArray[i];
}
}
This is because the dasGeradeArray has half of the indexes that dasArray has. You shouldn't use the same i variable. You can add another variable that you increment each time you add something to dasGeradeArray:
/
/CREATE NEW ARRAY WITH ALL EVEN NUMBERS AND THE LENGHT OF COUNT
int []dasGeradeArray = new int[count];
int dasGeradeCounter = 0
for(int i = 0; i < arrayLenght; i++){
if (dasArray[i] % 2 == 0) {
dasGeradeArray[dasGeradeCounter]= dasArray[i];
dasGeradeCounter++;
}

Random number in array

int[] integers = new int[12];
Random r = new Random();
for (int i = 0; i < integers.length; i++) {
integers[i] = r.nextInt((10 - (-10) + 1) + (-10));
}
I'm executing it using online compiler and it throws an error at random.
can anyone help me to solve that problem? I don't know how to write that half of it be negative and half positive. And that random number can't be 0
First of all, to generate a number between -10 and 10, the correct code is :
integers[i] = r.nextInt(21)-10;
r.nextInt(21) will generate numbers between 0 and 20, so subtracting 10 will give you the desired range.
Now, you must validate the random numbers you generated, to make sure you don't generate too many positives or negative, and no zeroes.
int posCount=0;
int negCount=0;
for (int i = 0; i < integers.length; i++) {
integers[i] = r.nextInt(21)-10;
if (integers[i]>0)
posCount++;
else if (integers[i]<0)
negCount--;
if (posCount>6||negCount>6||integers[i]==0)
i--; // redo the current iteration of the loop, since the last generated
// number should be replaced
}
Another alternative, which will run faster, is to generate first 6 positive integers (r.nextInt(10)+1) and then 6 negative integers (-1-r.nextInt(10)), but I'm not sure whether the order of the generated numbers is important (i.e. is it acceptable that all the positives will come before all of the negatives).
1+ r.nextInt(10) gives integers 1-10. For negative integers, just put minus sign to the result of this calculation. Call it six times for positives and six times for negatives. What kind of error you get?
check this :
Random r = new Random();
int[] integers = new int[10];
boolean isEven=false;
int i = 0;
while(true){
int check = r.nextInt(10)*(isEven?-1:1);
if (check != 0){
isEven = !isEven;
integers[i] = check;
System.out.println(integers[i]);
i++;
}
if(i == 10){
break;
}
}
Keeping it simple:
Fill the current index with a random number from (1 to 10);
Fill the next index with a random number from (-1 to -10);
int[] integers = new int[12];
Random r = new Random();
for (int i = 0; i < integers.length; i+=2) {
integers[i] = r.nextInt(10) + 1;
if((i+1)<integers.length){
integers[i+1] = r.nextInt(10) -10;
}
}

Random Uniform Distribution

So i want to get random elements of a list with uniform distribution in Java. I know that in the Random class, for example the nextInt method, already give me something like that:
Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator's sequence.
So given something like the code below:
Random rnd = new Random();
int numTimes = 10;
for(int i = 0; i < numTimes*n; i++){
System.out.println(rnd.nextInt(10));
}
I expect that for small "n" I can't quite see a good uniform distribution, probably increasing it, I will see something better. So my question is, how can I guarantee a uniform distribution within smaller n, or in other words, with "n = 2" how can I get every number at least once?
Trying to explain better: giving 10-number range dataset, and for example 20 iterations, is there a way that each number is printed 1-3 times, in other words, at least once?
If you want to generate numbers that occur exactly the same number of times (which is not the same as a uniform distribution), then there is a better way to do it.
int n = 2; // your "n"
int t = 100; // how often you want each number x to occur, where 0 <= x < n
// Build a list of numbers
List<Integer> l = new ArrayList<>();
for (int i = 0; i < t; i++) {
for (int j = 0; j < n; j++) {
l.add(j);
}
}
// Shuffle the list randomly; this ensures the order is random but each number x occurs
// as often as any other x
Collections.shuffle(l);
for (Integer value : l) {
System.out.println(value);
}
If you want to have some numbers at least once, but don't care about the others; then insert 1 of each number that you want at least once and the rest randomly. If I understand you correctly, you want the numbers 1, 2 and 3 at least once, and then randomly numbers 1, 2 and 3. So, that would be:
int n = 3; // your "n"
// Build a list of numbers
List<Integer> l = new ArrayList<>();
for (int x = 1; x <= n; x++) {
l.add(x);
}
int t = 17; // add 17 more random numbers in range 1-3 inclusive
for (int i = 0; i < t; i++) {
l.add(rnd.nextInt(n) + 1);
}
// Shuffle
Collections.shuffle(l);
// Print
for (Integer value : l) {
System.out.println(value);
}

Categories

Resources