What does this code mean? how does the count increase? - java

I am new to Java so I don't really understand this yet, I just want to know how does this code work and how the count increase. Why is there a loop inside a loop?
(This is not my own code it is something i am studying.)
Random r = new Random();
for (int i = 0; i < 5; i++)
{
for (int j = 0; j < 5; j++) {
int n = r.nextInt(3);
Gridbox[i][j] = n;
if (n == 0)
{
count++;
}
}

r.nextInt(3) results in a uniform random number between 0 (inclusive) and 3 (exclusive). Why? Because the docs say so; javadoc is a great place to start when trying to figure out what things do.
In other words, 33% of the time that returns 0, 33% of the time it returns 1, and 33% of the time it returns 2, randomly determined.
In other words, 33% of the time (on average), n would be 0, and count would be increased.
All this code does is loop 5 times (first 'for'), and per outer loop, loop 5 times (for a total of 5*5 = 25 times a random number is generated).
Gridbox is some sort of 5 by 5 array; the randomly generated number is placed in this grid, and count is incremented 33% of the time.

The count increases here, by one each time this line is executed:
count++;
Look up the increment operator ++ to understand.
There is loop inside a loop, a socalled pair of nested loops, in order to cover all possible combinations of possible is and js, i.e. to cover all of the 2D range.
If you want to learn a programming language I recommend to first read a book and maybe follow tutorials. Reading existing code is for later, though not a bad idea.

I added a comment to every line of code; and tried to explain here.
You're creating a gridbox of size i x j. In your code's case you are hardcoding i and j to a size of 5(using the for loops both sized 5)
r.nextInt(3) results in a uniform random number between 0 (inclusive) and 3 (exclusive). So you are assigning each value inside the gridbox a random value between 0 and 3.
Whenever you do the assignment, if the value is 0 increment the count.
//random class that allows generation of random values
Random r = new Random();
//for loop of size 5, start at 0 and go through it 5 times. **i** is the first param of gridbox
for (int i = 0; i < 5; i++)
{
//for loop of size 5, start at 0 and go through it 5 times. **j** is the second param of Gridbox
for (int j = 0; j < 5; j++) {
// assign random integer value between 0 and 3 to field n.
int n = r.nextInt(3);
// push n into GridBox. this might be a typo. In java Capital indicates its a class not a instance of the class
Gridbox[i][j] = n;
// if **n is equal 0 increment count.
if (n == 0)
{
count++;
}
}
I imagine you need to do a instantiation
//this needs to be properly instantiated, to right size.
Gridbox gridbox = new Gridbox();
gridbox[i][j] = n

Related

How to make a random super increasing array

I'm having a lab about making a Merkle Hellman Knapsack,the request said i need to make an automatically super increasing array but i don't know how to make it,is there any way to make it ? Thanks for reading
Random random = new Random();
int[] wInt = random.ints(8, 1, 999).toArray();
for(int i = 0; i < 8 - 1; i++) {
for (int j = i + 1; j < wInt.length; j++) {
if(wInt[i] > wInt[j]) {
int temp = wInt[i];
wInt[i] = wInt[j];
wInt[j] = temp;
}
}
}
A superincreasing sequence is one where each term is at least as big as the sum of all the preceding terms. Therefore, one way to generate a superincreasing sequence would be to keep track of the sum of all elements currently in the sequence, then to add some random, nonzero number onto the total when forming the next element. In pseudocode:
sequence = []
total = 0
while the sequence has fewer than n items in it:
total += some random number
append total to the sequence
I'll leave it as an exercise to translate this into your Programming Language of Choice.

What is this algorithm doing?

I got a pseudocode:
Input: Array A with n (= length) >= 2
Output: x
x = 0;
for i = 1 to n do
for j = i+1 to n do
if x < |A[i] - A[j]| then
x = |A[i] - A[j]|;
end if
end for
end for
return x;
I have converted that to a real code to see better what it does:
public class Test
{
public static void main (String[] args)
{
int A[] = {1,2,3,4,5,6,7,8,9};
int x = 0;
for (int i = 1; i < A.length; i++)
{
for (int j = i + 1; j < A.length; j++)
{
if (x < Math.abs(A[i] - A[j]))
{
x = Math.abs(A[i] - A[j]);
}
}
}
System.out.println(x);
}
}
The output was 7 with the array in the code.
I have used another array (1 to 20) and the putput was 18.
Array 1-30, the output was 28.
The pattern seems clear, the algorithm gives you the antepenultimate / third from last array value. Or am I wrong?
I think the pseudo code tries to find the greater of the difference between any 2 elements within an array.
Your real code however, starts from 1 instead of 0 and therefore excludes the first element within this array.
I think pseudocode is trying to find the greatest difference between two numbers in an array. It should be the difference between the minimum and maximum value of the array.
I personally think this is a really poor algorithm since it is doing this task in O(n^2). You can find the min and maximum value of an array in O(n). and take the difference between those numbers and result will be the same. check the pseudocode
Input: Array A with n (= length) >= 2
min=A[0];max = A[0];
for i = 1 to n do
if min > A[i] then
min = A[i];
end if
if max < A[i] then
max = A[i]
end if
end for
return (max-min);
The code gives the biggest difference between any two elements in the array.
There are 2 nested loops, each running over each element of the array. The second loop starts at the element after the first loop's element, so that each possible pair is considered only once.
The variable x is the current maximum, initialized to 0. If x is less than the absolute value of the current pair's difference, then we have a new maximum and it is stored.
However, because you directly copied the pseudocode's starting index of 1, you are inadvertently skipping the first element of the array, with index 0. So your Java code is giving you the maximum difference without considering the first element.
If you have an array of values between 1 and n, you are skipping the 1 (in index 0) and the returned value is n - 2, which happens to be the third-to-last value in the array. If you had shuffled the values in the array as a different test case, then you would see that the returned value would have changed to n - 1 as now both 1 and n would be considered (as long as n itself wasn't in the first position).
In any case, you would need to set the index of the first element to 0 so that the first element is considered. Then {1,2,3,4,5,6,7,8,9} would yield 8 (or any other order of those same elements).
Assuming all positive integers, the algorithm in a nutshell finds the difference between the maximum and the minimum value in the array. However, it will not work correctly unless you initialize i to 0 in the for loop.
for (int i = 0; i < A.length; i++)

Testing elements in an array

Hello I have searched for a simple way to check ,
if any number of elements up to 6 in the array add up to seven. I have yet to find one my array is this,
private int[] diceRoll = new int[6];
The question is a bit vague, however, here's my attempt at an answer:
If what you're trying to do is take two indices x and y in diceRoll[] and see if they add up to 7, the simplest thing to do is
if(diceRoll[x] + diceRoll[y] ==7){
return true;}
If you're trying to see if ANY item with any other item adds up to 7, use a double for-loop (these are weird, but very helpful)
for(int i = 0; i < diceRoll.length; i++){
for(int j = 0; i < diceRoll.length; i++){
if(diceRoll[i] + diceRoll[j] != 7){
return false;
}
}
}
Hope this helps!
-katie
It sounds like what you need to do is take every subset of the diceRoll array and see which ones add up to 7. This is how it can be done.
Assuming you know that 1 & 1 = 1, and that 1 & 0 = 0, imagine each element of the array having a number in 0 0 0 0 0, if the element is selected, say element 5, the subset representation in binary form would be 0 0 0 0 1. If element 2 and 3 are selected, the subset representation would be 0 0 1 1 0. If you take a binary one, keep track of its index, and move it from right to left in the array computing index&1 each time, you can get which indexes of the array are in the current subset (if the index&1 computation results in a 1 for that index). Translating this to a smaller array called currSubset, you can sum it up and check if it is equal to 7.
The termination of the outer for loop comes from the maximum value of a 5 digit binary number, which is 11111 = 31 = 2^5-1, hence the use of the less than sign.
int sum = 0;
int index = 0;
ArrayList<ArrayList<Integer>> subsetsThatAddTo7 = new ArrayList<ArrayList<Integer>>();
for(int subsetRep = 0b00001; i < Math.pow(2,5); i++){
ArrayList<Integer> currSubset = new ArrayList<Integer>
for(index = 0; index < 5; index++){
if(subsetRep & (1 << index))
currSubset.add(diceRoll[5-index]);
}
int sum = 0;
for(int num : currSubset)
sum += num;
if(sum == 7)
subsetsThatAddTo7.add(currSubset);
}

Level of randomness

my goal is to randomly shuffle an array, (from 0 to 9) but every number has to appear in the array only once. I have got two (working) ideas, but I would like to find out how many times must this random2 method iterate to achieve the same level of randomness in array as in the first method (random1).
import java.util.Random;
class RandomStuff {
static Random r;
final static int iteraction = 10;
public static void main (String[] args) {
r = new Random();
int[] array = new int[10];
random1(array);
random2(array, iteraction);
}
static void random1(int[] array) {
for(int i = 0; i < array.length; i++) pole[i] = -1;
for(int i = 0; i < array.length; i++) {
while(true) {
int y = r.nextInt(10);
if(!find(array, y)) {
array[i] = y;
break;
}
}
}
}
static void random2(int[] array, int iteraction) {
for(int i = 0; i <= iteraction; i++) {
int y1 = r.nextInt(array.length);
int y2 = r.nextInt(array.length);
int p = array[y1];
array[y1] = array[y2];
array[y2] = p;
}
}
static boolean find(int[] array , int value) {
for(int i = 0; i < array.length; i++) {
if(pole[i] == value) return true;
}
return false;
}
}
The first method (random1) works assigning of random numbers and testing, if they are/aren't in the array already. Which seems to be pretty random to me.
The second method (random2) works on swaping two random random values in the array. So the question is, how many times do I have to swap two numbers in the array to achieve the same level of randomness. (or what value shoud the variable iteraction have).
Thanks for any reply.
How about assigning a random number to each element of the array, arrange the random numbers in order and in that order read the element of the array assigned to that random number
0.64342 0
0.95229 1
0.23047 2
0.82793 3
0.19014 4
0.18528 5
0.15684 6
0.99546 7
0.54524 8
0.90612 9
Order
0.15684 6
0.18528 5
0.19014 4
0.23047 2
0.54524 8
0.64342 0
0.82793 3
0.90612 9
0.95229 1
0.99546 7
numbers 0 to 9 now in random order
To answer your original question, "how many times must this random2 method iterate to achieve the same level of randomness in array as in the first method?"
The answer is: it will never achieve the same level of randomness.
For any position that has been swapped, there is an equal chance of it arriving in any position, which means a 10% chance it ends up back where it started.
In each iteration, 2 numbers are swapped (or zero if the number is swapped to its own position). That means there's an 80% chance for any given position to never have been swapped, after 1 iteration. After N iterations, there is still a 0.8^N chance that it was never swapped. If it was swapped, there is a 10% chance it went back where it started. So the probability that any given digit is in its starting position is 10% + 0.8^N. This is always > 10%, so you will never get a perfectly even distribution.
For example, for your choice of 10 iterations, there remains a 10.7% chance for each digit that it never moved, or a total of 19.7% chance it'll be in its starting position. So ten iterations is not even close to enough.

How do I generate random numbers in an array that add up to a defined total?

I need to randomly generate an array with 7 slots in Java. All these slots must have a value of at LEAST 1, but combined, have a total value of another defined number. They also all need to be an int value, no 1.5 or 0.9816465684646 numbers.
Example:
int a=10;
int[] ar = new int[7]
ar[0] = 1
ar[1] = 1
ar[2] = 2
ar[3] = 2
ar[4] = 1
ar[5] = 2
ar[6] = 1
I want it to generate something like that, but if int a=15, all the numbers would total 15 in any order
The standard way to generate N random numbers that add to a given sum is to think of your sum as a number line, generate N-1 random points on the line, sort them, then use the differences between the points as your final values. To get the minimum 1, start by subtracting N from your sum, run the algorithm given, then add 1 back to each segment.
public class Rand {
public static void main(String[] args) {
int count = 8;
int sum = 100;
java.util.Random g = new java.util.Random();
int vals[] = new int[count];
sum -= count;
for (int i = 0; i < count-1; ++i) {
vals[i] = g.nextInt(sum);
}
vals[count-1] = sum;
java.util.Arrays.sort(vals);
for (int i = count-1; i > 0; --i) {
vals[i] -= vals[i-1];
}
for (int i = 0; i < count; ++i) { ++vals[i]; }
for (int i = 0; i < count; ++i) {
System.out.printf("%4d", vals[i]);
}
System.out.printf("\n");
}
}
A good way to achieve uniformity is, for example, to fill up a = 15 units into an 8 element array:
Put 1 in each element in the array as this is your requirement, you have now 7 values left to distribute
Roll a random number between 0 and the max index of the array, and add 1 to that element, and subtract 1 from 7. Do this until 7 goes down to zero.
In this way, you'll meet your minimum conditions by having each element have minimum value 1. Then you distribute the remaining totals in a completely random way.
Adding on to what #Kon said, you could use two random numbers rather than one for more randomness. That is:
Fill every element in the array with the value 1
valuesToDistribute = a - array.length-1
randomIndex = Roll a number between 0 and array.length-1
randomValue = Roll a number between 1 and valuesToDistribute
Add to randomIndex the value randomValue
Subtract randomValue from valuesToDistribute
Repeat until valuesToDistribute = 0
My java is horrible, so I'm not providing the actual code here, as it would probably be wrong. I've done this exact thing in SQL before though, so I know it works...
Let Y be the Total value you want the elements to add up to
Begin a loop with variable Z going from 1 to X where X is the number elements in your array (here called AR)
In the loop, set AR(Z) to a random number between 1 and Y-X+Z
Subtract the new value from Y, so Y = Y - AR(Z)
End loop : back to step 2, advancing Z by 1

Categories