The Question:
Write a program that rolls two dice and adds their sum 36,000,000 times and prints how many times each sum was calculated.
So obviously I need to get a rand for 6 numbers twice and add them - in a loop for 36 million times, and then get a frequency counter for however many times each sum was found (which ranges from 2 to 12).
Now given the fact that I'm not very experienced in Java, I ran into a couple of problems.
This is the code that I've got so far:
package twodice;
import java.util.Random;
public class TwoDice
{
public static void main(String[] args)
{
int sum;
Random randomNumbers = new Random();
int[] frequency = new int[13];
for (int roll = 2; roll <= 36000000; roll++)
{
++frequency[(1 + randomNumbers.nextInt(6)) + (1 + randomNumbers.nextInt(6))];
}
System.out.printf("%s%10s\n", "Face", "Frequency");
for(int face = 1; face < frequency.length; face++)
{
System.out.printf("%4d%10d\n", face, frequency[face]);
}
}
}
Output:
run:
Face Frequency
1 6001537
2 6003025
3 5997753
4 5997647
5 6000769
6 5999269
7 0
8 0
9 0
10 0
BUILD SUCCESSFUL (total time: 0 seconds)
The problems are that:
1. The sums that are displaying are not 2-12, they're 1-10 (The right number of sums, just not the right sums...
2. The frequencies are only being found for 1-6, not 1-6 + 1-6.
Thanks for all of your help!
EDIT: Solved by Oscar Lopez! Thanks so much man!
For the first problem, the array has the wrong size, this should fix it:
int[] frequency = new int[13];
Also the values at indexes 0 and 1 will always be 0, so the loop should start at face = 2. For the second problem, the program should simulate throwing two dice, not just one as it currently is. Try this:
++frequency[(1 + randomNumbers.nextInt(6)) + (1 + randomNumbers.nextInt(6))];
Also change your for loop. Final code looks like this:
import java.util.Random;
public class TwoDice
{
public static void main(String[] args)
{
Random randomNumbers = new Random();
int[] frequency = new int[13];
for (int roll = 1; roll <= 36000000; roll++)
{
++frequency[1 + (randomNumbers.nextInt(6)) + (1 + randomNumbers.nextInt(6))];
}
System.out.printf("%s%10s\n", "Face", "Frequency");
for(int face = 2; face < frequency.length; face++)
{
System.out.printf("%4d%10d\n", face, frequency[face]);
}
}
}
I ran this, and it works as you might expect.
Related
i searched this site and found similar codes but a little different. For my lab in class the instructions say that I need to roll N die , M times and display the number of times a roll occurs in a frequency table. so I'm having a bit of trouble setting up the data in my frequency table. The frequency table prints right but my numbers are wrong. I feel like I'm missing something either and array or an increment? Please Help
my input:
import javax.swing.*;
import java.awt.*;
import java.util.*;
public class Lab1
{
public static void main(String[] arg)
{
Random ran = new Random();
String n = JOptionPane.showInputDialog(null,"How many dice?: ");
String m = JOptionPane.showInputDialog(null,"How many rolls?: ");
int die = Integer.parseInt(n);
int roll = Integer.parseInt(m);
int count = 0;
int[] rollArr = new int[die*6+1];
for(int i=0;i<rollArr.length;i++)
{
rollArr[i] = 0;
}
for( int i=0; i<roll;i++)
{
count = die*1 + ran.nextInt ( 6 );
++rollArr[count];
}
for(int r=1;r<rollArr.length;r++)
System.out.println(r + ":" + rollArr[r]);
}
}
The example says to roll 4 dice 1,000,000 times to get a bell curve but my curve has alot of zeroes.
my output:
1:0
2:0
3:0
4:166309
5:166424
6:166523
7:166984
8:167286
9:166474
10:0
11:0
12:0
13:0
14:0
15:0
16:0
17:0
18:0
19:0
20:0
21:0
22:0
23:0
24:0
I'll just give a hint since this is a lab assignment.
I believe your instructor wants to see the distribution of sums of the die rolls, since that's what will show up as a bell curve. So your array would have to capture and count the possible sums. For example, if you rolled four dice, then the possible sums are 4-24, and you would tally those up.
I have ran into a bit of trouble with some code i had to write for my course.
I had to write a random number generator which run's through the numbers one to fifty, ten thousand times and then only print out the top 15 highest occurring numbers. I have managed to do everything correctly except printing out the top 15 highest.
Here is my full block of code
package section4;
import java.util.Random;
public class Lottery {
public static void main(String[] args) {
Random rand = new Random();
int freq[] = new int[51];
for(int roll = 1; roll<1000000;roll++){
++freq[1+rand.nextInt(50)];
}
System.out.println("Lottery Number\tFrequency");
for(int face = 0; face<freq.length ;face++){
System.out.println(face+"\t"+freq[face]);
}
}
}
I have tried using an ArrayList.
I first created the ArrayList and then added face and freq[face] to the arraylist and then printed the elements of the ArrayList. I tired it on a slim chance and as I thought I was wrong.
package section4;
import java.util.ArrayList;
import java.util.Random;
public class Lottery {
public static void main(String[] args) {
Random rand = new Random();
int freq[] = new int[51];
ArrayList<Integer> top = new ArrayList<Integer>(15);
for(int roll = 1; roll<1000000;roll++){
++freq[1+rand.nextInt(50)];
}
System.out.println("Lottery Number\tFrequency");
for(int face = 0; face<freq.length ;face++){
top.add(face);
top.add(freq[face]);
System.out.println(top);
}
}
}
And I have also tried to change the "For Statement" but I also knew that changing it to what I did only tells the compiler to run from 0 - 15 and not the full 50.
for(int face = 0; face< 15 ;face++){}
Can anyone help, as to how I can print out only the 15 highest, as I have been stuck on this for days.
int[] b =Arrays.copyOf(freq, 5);
Arrays.sort(b);
for(int i = 0 ; i < 15 ; i++){
System.out.println(b[50 - i]);
}
You may use a SortedMap to store the frequency as Key and number as the Value. Then just iterate over the map in the order you want.
Here is the deal: I have a java code that generates a random number between two numbers and it works just fine. But i'm trying to achieve something. I want it in such a way that after the first number has been generated, when it recalls it, it doesn't generate that same number. For instance, if number 4 is generated, i want it now to be included among the possible generated numbers for the second time. To make things a little bit clear, here's my code.
int Maximum=10;
int Minimum=1;
int r;
r = (int)(Math.random() * Maximum) + Minimum;
is there anything i can do to make the code above not to generate a particular number between 1 and 10? Thanks.
You could fill a collection and simply removed a randomly selected number:
List<Integer> nums = new ArrayList<>();
for (int i = /* start */; i < /* end */; i++) {
nums.add(i);
}
//Elsewhere
Random rand = new Random();
int get = nums.remove(rand.nextInt(/* end */);
/* end */--;
This may be a bit slower initially for large amounts of numbers but the end result is a lower time-complexity on your checks for new numbers (whereas a while loop could in theory be O(∞n) if I'm not mistaken)
Alternatively, use Collections#shuffle
This doesn't seem like random number generation, it seems like randomly shuffling a Collection.
In Java 8:
public static void main(String[] args) {
final int min = 0;
final int max = 10;
final List<Integer> nums = IntStream.rangeClosed(min, max).
boxed().
collect(toList());
Collections.shuffle(nums);
nums.forEach(System.out::println);
}
Output:
3
10
5
0
8
7
9
2
1
4
6
Each number [0, 10] appears only once in a random order.
if you just want to exclude a single number replace this:
r = (int)(Math.random() * Maximum) + Minimum;
with this:
while( ( r = (int)(Math.random() * Maximum) + Minimum) == excludedNumber );
ArrayList<Integer> intList = new ArrayList<Integer>();
int Maximum=10;
int Minimum=1;
int r;
int[] intArray = new int[6];
for(int i=0; i<intArray.length; i++){
r = (int)( Minimum+ (Math.random()* (Maximum-Minimum+1)) );
if(!intList.contains(r)){
intList.add(r);
intArray[i]=r;
System.out.println(r);
}
else{
System.out.println(r+ "is a duplicate generated earlier, not putting in array again");
i--;
}
}
I have to fill 1 row of an multidimensional array with integers going from 1 to 3 completely random.
Example: if I would print that row it could give : 1 2 2 1 2 3 1 2 3
Now to do this i thought following code would work:
private void fillArray()
{
for(int i=0; i<10;i++)
{
PincodeRandom[0][i]=i;
PincodeRandom[1][i]= (int)Math.random()*3 +1;
}
}
however this results into filling the entire second row with only 1 (random) integer.
How can I fix this?
If you are going to use the Random class, make sure you create an instance outside of the loop, since new Random() uses the system time as a seed. So if two randoms are created during the same tick, they will produce the same random number sequence.
private void fillArray()
{
Random rand = new Random();
for(int i=0; i<10;i++)
{
PincodeRandom[0][i]=i;
PincodeRandom[1][i]= rand.nextInt(2) + 1;
}
}
(int) will cast Math.random() to 0 before you multiply by 3, resulting in 0 * 3 + 1 which is always 1. Try:
(int)(Math.random()*3) + 1;
Try this:
import java.util.Random;
public class Test {
public static void main(String[] args){
int[][] array = new int[2][10];
Random rand = new Random();
for(int i=0; i<10;i++)
{
array[0][i]=i;
array[1][i]= (int)rand.nextInt(3) +1;
}
for (int j=0;j<10;j++){
System.out.println(Integer.toString(array[1][j]));
}
}
}
Try This...
Random r = new Random();
for(loop){
PincodeRandom[1][i]= = r.nextInt(4 - 1) + 1;
}
This is because (int)Math.random() is causing it to equal 0, since Math.random() is a double always inbetween 0 and 1.
Instead, import the java.util.Random class.
And use it like:
new Random().nextInt(2)+1
I am triying to create random value for my game to show enemies on screen. BUt it some times shows 2 together some times 3 ...I want to ask that which is the best formul for creating random value.. This is my so far random value
random = 1 * (int) (Math.random() * 100);
"BUt it some times shows 2 together some times 3"
Given perfectly random numbers... In every 100 random values from 0 to 99, you'll find an average of 1.0 doubles. A triple will occur on average once for every 10,000 values. Given 10 million random numbers, java.util.Random yeilds the following results on my machine:
Doubles: 99873
Triples: 985
Double Rate: 1 in 100
Triple Rate: 1 in 10152
Source code:
import static java.lang.System.*;
import java.util.Random;
public class Sandbox {
public static final int NUM_ITERATIONS = 10000000;
public static void main(String[] args) {
Random rand = new Random();
int cur;
int last = -1;
int secondLast = -2;
int nDoubles = 0;
int nTriples = 0;
for (int i = 0; i < NUM_ITERATIONS; i++) {
cur = rand.nextInt(100);
if (cur == last) {
nDoubles++;
if (cur == secondLast) nTriples++;
}
secondLast = last;
last = cur;
}
out.println("Doubles: " + nDoubles);
out.println("Triples: " + nTriples);
out.println();
out.println("Double Rate: 1 in " + Math.round(1.0 * NUM_ITERATIONS / nDoubles));
out.println("Triple Rate: 1 in " + Math.round(1.0 * NUM_ITERATIONS / nTriples));
exit(0);
}
}
Actually the creation of genuinely random random numbers is a complex game in its own right. The Wikipedia article on this subject will give you an insight into the complexity that lies therein. Simple approximations such as those outlined above are probably sufficient for game purposes but will, it should be noted, be inclined to be 'streaky' from time to time.
You can use java.util.Random:
Random random = new Random(); // uses System.nanoTime() as seed
int enemies = random.nextInt(100);
Anyway, your approach is also fine, as it is in fact equivalent (behind the scene) with the above.
You can print a sequence of 100 random numbers generated your way and see for yourself that there isn't a problem.
What you use if perfectly fine.
In case you want something simplier you might like to use Random class like this:
Random generator = new Random(seed);
int number = generator.nextInt(100);
...and sometimes 77, sometimes 23, etc, as expected in a uniform distribution?
If you would like a normal distribution instead for your "enemies", so that extremes are less likely, it seems to be there in Java.