I would like to know that as I am learning Java from tutorials and there is a program for rolling the dice 1000 times and printing its frequency.
import java.util.Random;
public class RollDicewitharray {
public static void main(String[] args) {
Random r=new Random();
int arr[]= new int[7];
System.out.println("diceNo.\tFrequency");
for (int roll = 1; roll < 1000; roll++) {
++arr[1+r.nextInt(6)]; /* this line */
}
for (int i = 1; i < arr.length; i++) {
System.out.println(i+"\t"+arr[i]);
}
}
To summarise all, this program simulates rolling a six-sided dice 1000 times and records the occurrences of each number rolled.
public static void main(String[] args) {
Random r=new Random();
int arr[]= new int[7]; //Craete an array with 7 int elements
System.out.println("diceNo.\tFrequency");
for(int roll=1;roll<1000;roll++){ //Loop 1000 times
++arr[1+r.nextInt(6)]; //Randomly pick arr[1] to
} //arr[6] and plus one to it
for(int i=1;i<arr.length;i++){
System.out.println(i+"\t"+arr[i]); //Print occurrence of 1-6
}
}
Breaking the following code:
++arr[1+r.nextInt(6)]; //r.nextInt(6) will be evaluated first:
r.nextInt(6) returns random value of (0-5), so you have:
++arr[1+(random 0 to 5)]; //+1 will be evaluated next:
So you are generating a random value of 1-6. Next you add 1 to the array:
++arr[random 1 to 6]; //+1 to arr[1] or arr[2] or arr[3] or arr[4] or arr[5] or arr[6]
It can now be interpreted as:
arr[1] +=1; //or
arr[2] +=1; //or
arr[3] +=1; //or
arr[4] +=1; //or
arr[5] +=1; //or
arr[6] +=1;
So after running your program, if your array looks like:
[0] [1] [2] [3] [4] [5] [6] Array index
+---+---+---+---+---+---+---+
| 0 |175|170|165|170|165|175| <-- arr
+---+---+---+---+---+---+---+
It means 1 was rolled 175 times,
2 was rolled 170 times,
3 was rolled 165 times,
and so on..
r.nextInt(6) produces a random integer between 0 and 5. Adding 1 to it gives you a random dice roll between 1 and 6.
The arr array is used to count the number of times each dice roll occurred, so ++arr[1+r.nextInt(6)] increments the count for the current roll.
When the first loop is done, arr[1] holds the number of 1s, arr[2] the number of 2s, and so on.
1 + r.nextInt(6) draws a random number from 1 to 6 inclusive.
++arr[1 + r.nextInt(6)]; increments that element of the array arr.
So a frequency distribution of dice-rolls is built up. The zeroth element of the array is not used. Which is why it's set up with 7 elements. Wasteful perhaps? You tell me.
r.nextInt(6) - get the random number < 6;
arr[1+r.nextInt(6)] - get an item from the array arr with index 1 + random number from step 1;
++arr[1+r.nextInt(6)] increase the item from step 2 by 1
This line is equivalant to:
int number = r.nextInt(6); // Generates a random number between 0 and 6(exclusive)
int index = number + 1; // Since the faces of dice has value from 1 to 6
int value = arr[index];
and increases this number by 1;
Related
I need and array that generates 10 random numbers between 1 and 5,
inclusive. I then need to display the number of times 1-5 shows up in the array. This is what I have so far, it runs fine, it's just that the number of occurrences for the numberes 1-5 totals different everytime, which it should total exactly 10 everytime since the array can only hold 10 integers.
public static void main(String[] args){
//create an array that will produce 10 numbers
int[] randArray = new int[10];
//initialize randArray to the values 1-5
for(int i = 0; i < 6; i++){
randArray[i] = (int)(Math.random() * (6 - 1)) + 1;
}
System.out.println("Number\t" + "Appears");
for(int x = 1; x < 6; x++){
System.out.println(x + "\t" + randArray[x]);
}
}
Confusing limit on size-of-array with random-range
Your for loop addresses only the first six slots in your array rather than all ten, index # 0 through # 5 = 6 slots, not 10.
Use named variables
You may have been confusing your limit on the random number generator with your limit on the size of the array. This is a good example of why one should use well-named variables rather than “magic” numbers.
//create an array that will produce 10 numbers
final int countElements = 10;
final int randomRange = 5;
int[] randArray = new int[ countElements ];
//initialize randArray to the values 1-5
for ( int arrayIndex = 0 ; arrayIndex < countElements ; arrayIndex ++ ) {
randArray[ arrayIndex ] = ( int ) ( Math.random() * ( randomRange ) ) + 1; // (int)(Math.random() * range) + min;
}
System.out.println( "Number\t" + "Appears" );
for ( int arrayIndex = 0 ; arrayIndex < countElements ; arrayIndex ++ ) { // Start at zero, not one, as arrays are accessed by index (zero-based counting).
System.out.println( arrayIndex + "\t" + randArray[ arrayIndex ] );
}
Number Appears
0 3
1 2
2 3
3 3
4 3
5 2
6 4
7 5
8 5
9 3
ThreadLocalRandom
Generally better, and simpler, to use the ThreadLocalRandom class rather than Math.random.
This class uses the Half-Open approach to defining a range, where the beginning is inclusive while the ending is exclusive. If you want results to include only 1, 2, 3, 4, and 5, specify range of 1-6.
int randomRangeHalfOpen_Origin = 1 ; // We want results generated in range of 1-5 in fully-closed range, which is 1-6 in half-open range, ending is exclusive).
int randomRangeHalfOpen_Bound = 6 ; // The limit is *exclusive* (never appearing in generated results). This is known as "Half-Open" approach to defining a range. This is often the wisest approach in defining ranges.
…
randArray[ arrayIndex ] =
ThreadLocalRandom.current().nextInt(
randomRangeHalfOpen_Origin ,
randomRangeHalfOpen_Bound
)
; // Returns a pseudorandom int value between zero (inclusive) and the specified bound (exclusive).
Counting occurrences
As for counting the number of occurrences amongst the generated random numbers, I will leave that to the author to finish their own homework assignment. And already covered many times on Stack Overflow if one bothers to search.
The loop:
for (int i = 0; i < 6; i++){
randArray[i] = (int)(Math.random() * (6 - 1)) + 1;
}
Doesn't initialize 10 but only six random numbers since there is 6 as the limitation for the loops count. Then you print only 5 array elements since you loop indices from 1...5. Arrays are indexed from 0. Use the following for-statement for both of the loops:
for (int i = 0; i < 10; i++) { ... }
A final note: The better way without casting to generate a random integer between 1 and 5, both inclusive is:
Random r= new Random();
for (int i=0; i<10; i++){
randArray[i] = 1 + r.nextInt(5); // 5 is exclusive, the nearest lower possible int is 4
}
You have two problems in your code :
First
I need and array that generates 10 random numbers between 1 and 5
in this case you have to loop until 10 which is the array length so instead of :
for (int i = 0; i < 6; i++) {
You have to use :
for (int i = 0; i < randArray.length; i++) {
^^^^^^^^^^^^^^^^
Second
... then need to display the number of times 1-5 shows up in the array
To display the frequency of each value 1-5 you can use this way with Java 8 :
Map<Integer, Long> appearence = Arrays.stream(randArray).boxed()
.collect(Collectors.groupingBy(n -> n, Collectors.counting()));
to display the result you can use :
System.out.println("Number\t" + "Appears");
appearence.forEach((k, v) -> System.out.println(k + "\t\t" + v));
Number Appears
1 2
2 2
3 4
4 2
I am trying to solve this problem. http://www.lintcode.com/en/problem/coin-change-ii/#
This is the standard coin change problem solvable with dynamic programming. The goal is to find the number of ways to create an amount using an infinite set of coins, where each has a certain value. I have created the following solution :
public int change(int amount, int[] coins) {
// write your code here
int[] dp = new int[amount + 1];
dp[0] = 1;
// for(int coin : coins) {
// for(int i = 1; i <= amount; i++) {
// if(i >= coin) dp[i] += dp[i-coin];
// }
// }
for(int i = 1; i <= amount; i++) {
for(int coin : coins) {
if(i >= coin) dp[i] += dp[i-coin];
}
}
return dp[amount];
}
Why does the first for loop give the correct answer, but the second one does not? What am I missing here? Shouldn't the answer be the same? Could you provide a visual to help me "see" why the second for loop is incorrect?
When the amount = 8 and coins = [2,3,8] the output is 5 when it should be 3 when using the 2nd for loop's technique which is not correct.
Thank you.
Let's consider the loop that works first:
for(int coin : coins) {
for(int i = 1; i <= amount; i++) {
if(i >= coin) dp[i] += dp[i-coin];
}
}
Each iteration of the outer loop takes a coin of one value and finds out the number of ways to reach any value between the coin value and amount, adding that coin to the result of the previous iterations.
Considering your amount = 8 and coins = [2,3,8] example:
The array is initialized to
index 0 1 2 3 4 5 6 7 8
value 1 0 0 0 0 0 0 0 0
which means that without any of the coins, the only amount we can reach is 0, and we have a single way to reach that amount (0 2s, 0 3s, 0 8s).
Now we find the amounts we can reach with just the coin of value 2:
index 0 1 2 3 4 5 6 7 8
value 1 0 1 0 1 0 1 0 1
It's not surprising that we can reach any even amount. For each such amount we have a single way to reach that amount (1 2s to reach 2, 2 2s to reach 4, etc...).
Now we find the amounts we can reach with coins of value 2 or 3. We can reach an amount k using a single coin of 3 if we already found ways to reach the amount k-3.
Below I show the number of ways to reach each value between 0 and 8, and specify how many coins of each type are used in each combination.
index 0 1 2 3 4 5 6 7 8
value 1 0 1 1 1 1 2 1 2
0x2 - 1x2 0x2 2x2 1x2 3x2 2x2 4x2
0x3 - 0x3 1x3 0x3 1x3 0x3 1x3 0x3
or or
0x2 1x2
2x3 3x3
Finally, in the last iteration we consider the coin of 8. It can only be used to reach the amount 8, so we get the final result:
index 0 1 2 3 4 5 6 7 8
value 1 0 1 1 1 1 2 1 3
When you swap the loops:
for(int i = 1; i <= amount; i++) {
for(int coin : coins) {
if(i >= coin) dp[i] += dp[i-coin];
}
}
you bring the order the coins are added into play. For example, the amount 5 can be reached by either first taking a coin of 2 and then a coin of 3, or by first taking a coin of 3 and then a coin of 5. Therefore the value of dp[5] is now 2.
Similarly, dp[8] results in 5 since you can take any of the following sequences of coins:
2+3+3
3+2+3
3+3+2
2+2+2+2
8
The original loop doesn't distinguish between 2+3+3, 3+2+3 and 3+3+2. Hence the different output.
private static int coinChange(int[] coins, int sum) {
int size = coins.length;
int[][] arr = new int[size + 1][sum + 1];
// Applying the recursive solution:
for(int i = 1; i < size +1; i++){
for(int j = 1; j < sum +1; j++) {
arr[i][0] = 1;
if (coins[i - 1] > j) {
arr[i][j] = arr[i - 1][j];
} else
arr[i][j] = arr[i - 1][j]+arr[i][j - coins[i - 1]] ;
}}
return arr[size][sum];enter code here
import java.util.*;
import java.lang.*;
public class Main {
public static void main(String[] args) {
Random dice = new Random();
int a[]=new int [7];
for(int i = 1 ; i <=100;i++){
++a[1+dice.nextInt(6)];
}
System.out.println("Sno\t Values");
int no;
for(int i=1;i<a.length;i++){
System.out.println(i+"\t"+a[i]);
}
}
}
Sno Values
1 19
2 13
3 16
4 16
5 19
6 18
Can any one please explain this line "++a[1+dice.nextInt(6)]"
i know this program provides random number generated from 1-6 on how many times within the given value
Mostly, that's just hard to read code. It would be at least slightly simpler to read (IMO) as
a[dice.nextInt(6) + 1]++;
... but it's easier still to understand it if you split things up:
int roll = dice.nextInt(6) + 1;
a[roll]++;
Note that there's no difference between ++foo and foo++ when that's the whole of a statement - using the post-increment form (foo++) is generally easier to read, IMO: work out what you're going to increment, then increment it.
Random.nextInt(6) will return a value between 0 and 5 inclusive - so adding 1 to that result gets you a value between 1 and 6 inclusive.
Yes, first you have
int a[]=new int [7];
which is an array that can hold 7 elements (valid indices being 0-6), all of which have an initial value of 0. Then
++a[1+dice.nextInt(6)];
is saying
int randomIndex = 1 + dice.nextInt(6); // <-- a random value 1 to 6 inclusive
a[randomIndex] = a[randomIndex] + 1;
Which is counting how many ones through sixes are rolled.
++a[1+dice.nextInt(6)]
dice.nextInt(6)= return an integer between 0 and 5
then you add 1 to that value, after that you get the element at that index in the array a and you increase that using the ++ operation
nextInt() returns a pseudorandom, uniformly distributed value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator's sequence.
So the value of 1+dice.nextInt(6) will fall between 1 to 6 (both inclusive) and increment the value of a[x] like a counter for x
T - number of test cases | 1<=T<=10 and n - number of elements | 1<=n<=1000000
Eg
if (T >= 1 && T <= 10) {
for (int i = 0; i < T; i++) {
int n = sc.nextInt();
if (n > 0 && n <= 1000000) {
array = new int[n][n];
System.out.print("\n" + sumOfArray(array, n));
}
}
}
Need to find the sum of M[i][j], where M[i][j] = (int) i/j;
I have written the code, but for n>10000, I start getting OOM, (for obvious reason).
If someone can help me with it, it'll be great. Need a whole new approach on solving the problem.
Eg.
Input Output
2
2 4
4 17
Here It is obvious that you don't need to store the values in the matrices because It is not possible to have that much space (Array[10000][10000]) available to allocate. So you need to think somehow in a mathematical way.
Consider a 4x4 Matrix and represent each element in the term of i,j.
1,1 1,2 1,3 1,4
2,1 2,2 2,3 2,4
3,1 3,2 3,3 3,4
4,1 4,2 4,3 4,4
Now we can represent here that what is stored in each of these elements.
1/1 1/2 1/3 1/4 (In Integers) 1 0 0 0
2/1 2/2 2/3 2/4 ============> 2 1 0 0
3/1 3/2 3/3 3/4 3 1 1 0
4/1 4/2 4/3 4/4 4 2 1 1
Tackle this matrix by dividing it into columns and solve each of the columns.
For the first column series would be 1+2+3+4.Then for the column number two(2) the series would be 0+1+1+2.
Notice here that for ith column first i-1 values are zeros and then i values are same in the column. Then value is increased. Again it will be same for i values. Again increases by 1 and so on.
So in ith column value get increased on the jth element where j%i==0.
So you can implement this logic in 1-D array and Complexity of this approach will be O(n logn) for each testcase.
Code:
import java.util.Scanner;
public class Main
{
public static void main(String args[])
{
Scanner sc=new Scanner(System.in);
int testcases=sc.nextInt();
while(testcases-- >0)
{
int n=sc.nextInt();
long array[]=new long[n+1]; //Take long array to avoid overflow
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j+=i)
{
array[j]++; //This will store that which elements get increased
//from zero how many times
}
}
//Now we can do summation of all elements of array but we need to do prefix sum here
long sum=0;
for(int i=1;i<=n;i++)
{
array[i]+=array[i-1];
sum+=array[i];
}
System.out.println(sum);
}
}
}
Basically, two dice are rolled randomly a bunch of times and then the two dice values are added together (You roll a 6 and a 3, your total is 9).
The frequency of how many times the total is rolled is stored in totalTally[].
So say you roll 10 times, 3 of those times you roll a total of 9, totalTally[9] = 3.
Here's my code:
import java.util.Random;
public class dice
{
public static void main(String a[])
{
System.out.println("Creating arrays to store information. This might take a while.");
int[][] tally = new int[6][6]; //Creates an array called tally to keep track of how many times each number was rolled. [Dice1][Dice2]
int[] totalTally = new int[12]; //Creates an array called totalTally to keep track of frequency of totals rolled.
int[][] roll = new int[36000000][2]; //Creates an array to store dice roll info.
System.out.println("Rolling two 6-sided dice " + roll.length + " times...");
Random r = new Random(); //Creates a new random number generator
for (int i = 0; i < roll.length; i++) //For loop that rolls the dice to fill the length of the array.
{
roll[i][0] = (r.nextInt(6) + 1); //Assigns random number between 1 and 6 to the array for dice 1 result.
roll[i][1] = (r.nextInt(6) + 1); //Assigns random number between 1 and 6 to the array for dice 2 result.
tally[roll[i][0]-1][roll[i][1]-1]++; //Increments by 1 the respective result in the tally array.
totalTally[roll[i][0] + roll[i][1]-2]++; //Increments by 1 the respective result in the totalTally array.
}
System.out.println("All done. Results are below.");
//Following lines print first table header
System.out.println("\n ROLL SUMMARY:");
System.out.println("Dice 1 + Dice 2 Frequency");
System.out.println("---------------------------------");
for (int i = 1; i <= totalTally.length; i++)//for loop goes through totalTally values
{
System.out.println(" " + i + " " + totalTally[i-1]);
}
//Following lines print second table header
System.out.println("\n DETAILED VIEW:");
System.out.println("Dice 1 Dice 2 Total Frequency");
System.out.println("---------------------------------------------");
for (int j = 1; j <= 6; j++) //For loop goes through dice 1 values
{
for (int k = 1; k <= 6; k++) // Nested for loop goes through dice 2 values
{
System.out.println(j + " " + k + " " + (j+k) + " " + tally[j-1][k-1]); //Prints line for table with dice values
}
}
}
}
and here is the output I am getting for the first table with that code:
Dice 1 + Dice 2 Frequency
1 998639
2 1997209
3 2998118
4 4000336
5 4999210
6 6001277
7 5001144
8 4000794
9 3002596
10 2001501
11 999176
12 0
Here's my issue: It's not possible to roll a 1 if you are rolling two dice.
And it IS possible to roll a 12.
So all my values need to be shifted.
What am I doing wrong?
totalTally[roll[i][0] + roll[i][1]-2]++
Why you subtract 2 ?
you should subtract 1 instead
totalTally[roll[i][0] + roll[i][1]-1]++
This is how you "tally" a single die.
Random r = new Random();
int[] die1 = new int[5]; //Creates an array to tally die 1
for (int roll = 0; roll < totalRolls; roll++) {
die1[r.nextInt(6)] += 1; // increment the index of the random roll
}
Do that for each die.
Your total tally would look like this to count individual rolls
for (int side = 1; side <= 6; side++) {
System.out.printf("%d\t%d\n", side, die1[side-1] + die2[side-1]);
}
If you want to tally the total of the rolls, sure, start printing at 2, not 1
System.out.println("Dice 1 + Dice 2 Frequency");
System.out.println("---------------------------------");
/// See here
for (int i = 1; i <= totalTally.length; i++)//for loop goes through totalTally values
{
System.out.println(" " + i + " " + totalTally[i-1]);
}