Method to count the sum of n dice (without using arrays) - java

I'm trying to develop a method that interacts with this main class code to find the sum of n dice. (the main class program limits this count to the sum of 2, 3, 4 and 5 dice respectively).
for (int numberOfDice = 2; numberOfDice <= 5; ++numberOfDice) {
System.out.println("Rolling " + numberOfDice + " dice gives "
+ MathCalc.rollDice(numberOfDice));
The task of the method is to sum the number of dice (each evaluation is independent of another, meaning that the sum of 3 dice could be 11 for example while the sum of 4 dice might only be 8.) using only a loop and some local variables.
I have produced this method for another section of my code to simulate a single roll of the dice but for some reason I cant seem to wrap my head around this next step.
public static int rollDie() {
//roll a random number between 1-6 to simulate the roll of a die
return 1 + (int) (Math.random() * 6);
}

Math.random is obsolete and flawed, don't use it, use Random instead, specifically its nextInt() method, for example:
Random random = new Random();
// get values in the range [1:6]
int roll() {
return 1 + random.nextInt(6);
}
To sum up n rolls, call this method in a loop:
int sum = 0;
for (int numberOfDice = 0; numberOfDice < count; ++numberOfDice) {
sum += roll();
}

For bonus points in your tutorial, submit this:
public static int rollDie() {
return DoubleStream.generate(Math::random).limit(n).mapToInt(d -> (int)(d * 6) + 1).sum();
}

Related

How can I make the script that counts which number occurred most often and counts how many times do each of the 10 random numbers occur

To explain about the program that I am making, it is program that asks the user how many times he would like his coin to flip. In this program, the coin of the head is even, and the odd is the tail.
I created a script that randomizes numbers from 1 to 10 based on the number you entered. And also I've made the script that how many odd and even numbers had come out, but I don't know how to make a script that shows how many times do each of the 10 random numbers occur and which number occurred most often.
Here is the script that I have made:
import java.util.*;
public class GreatCoinFlipping {
public static void main(String[] args) {
System.out.println("How many times do you want to flip the coin? : ");
Scanner sc = new Scanner(System.in);
int amount = sc.nextInt();
int[] arrNum = new int[amount];
int even = 0, odd = 0;
for (int i = 0; i < amount ; i++) {
arrNum[i] = (int)(Math.random() * 10 + 1);
System.out.println(arrNum[i]);
if (arrNum[i] % 2 == 0) even++;
else odd++;
}//end for
System.out.println("Head: " + even + ", Tail: " + odd);
}//end main
}//end class
What I am expecting on this script that that I want to make the script that shows how many times do each of the 10 random numbers occur and which number occurred most often and I want to make it by the count method. But the ramdon number part has to be in array method. Can someone please help me with this problem?
The arrNum variable will contain an array of all occurences of each number. So if you want to count, for example, how many times 4 occurred in this, you can do this:
Arrays.stream(arrNum).filter(n -> n == 4).count()
For 7 you can do this:
Arrays.stream(arrNum).filter(n -> n == 7).count()
And you can do the same for other digits (1 to 10).
This would be a simple/straight-forward way of doing it. You can also improve it by creating a method that returns this count:
public static int getCount(int[] arr, int num) {
return Arrays.stream(arr).filter(n -> n == num).count();
}
And then call this in a loop:
for(int i=1; i<=10; i++) {
System.out.println("Count for " + i + ": " + getCount(arrNum, i));
}
To keep track of the random number you generate you can use a array. The array starts out as all 0's and is of size 10 (because there are 10 numbers between 0-9).
int size = 10;
int numbers_counter[] = new int[size];
// initialize the values
for(int i = 0; i < size; i++){
numbers_counter[i] = 0;
}
// count some random numbers
for(int i = 0; i < 100; i++){
numbers_counter[(int)(Math.random() * size)] += 1;
}
// print how many times each number accured
for(int i = 0; i < size; i++){
System.out.println("" + i + " occured: " + numbers_counter[i] + " times");
}
You can apply this method to your code.

Java, program that counts random number and saves it

I am trying to make a program that lets the user choose how many times he want to throw the dice, and then every value of the thrown dice should be counted. In the end of the program the user should see how many times he threw 1, 2, 3 etc. This is a program to see if every number has an equal chance of being shown.
I encountered problems in the beginning of my code since I don't know how to let the computer throw the dice lets say 1000 times and then save every value from those thrown dices. This is what I have so far:
import java.util.Scanner;
public class Uppgift4_5
{
public static void main(String[] args)
{
Scanner inputReader = new Scanner (System.in);
System.out.println("How many times do you want to throw the dice:");
int amount = inputReader.nextInt();
int [] dice = { 1, 2, 3, 4, 5, 6 };
int random = 0;
for (int i = 0; i < amount; i++)
{
random = (int) (Math.random () + 1);
}
}
}
The problem I'm facing is that it only saves one random number and then loops that number 6 times.
As you can see I have not come far, I just need to know how I can save and count every individual thrown dice. And then I think I am going to use a switch and case to somehow save that(any suggestions there would also be helpful). Any suggestions or answers would be helpful. Thanks.
I would use a HashMap to store the value of the throw (1 to 6), as well as storing the number of times you got that value (increment by one for each):
public static void main(String[] args) {
Scanner inputReader = new Scanner(System.in);
System.out.println("How many times do you want to throw the dice:");
int amount = inputReader.nextInt();
Map<Integer, Integer> rolls = new HashMap<>();
for (int i = 1; i < 7; i++) {
rolls.put(i, 0);
}
for (int i = 0; i < amount; i++) {
int value = (int) (Math.random() * 6 + 1);
rolls.put(value, rolls.get(value) + 1);
}
for (Map.Entry<Integer, Integer> entry : rolls.entrySet()) {
System.out.println(entry.getKey() + ": " + entry.getValue());
}
}
The first for-loop initializes the keys 1 to 6 in the hashmap.
The second for-loop computes X number of dice throws and adds them to the hashmap.
The third for-loop iterates through the values in the hashmap and prints out the results.
Output:
How many times do you want to throw the dice:
500
1: 92
2: 88
3: 72
4: 78
5: 81
6: 89
EDIT: If you want to get the average and the median you could do the following:
double average = 0;
int[] storedSums = new int[6];
int i = 0;
for (Map.Entry<Integer, Integer> entry : rolls.entrySet()) {
int sum = entry.getValue();
average += sum;
storedSums[i++] = sum;
System.out.println(entry.getKey() + ": " + sum);
}
Arrays.sort(storedSums);
System.out.println("Average: " + (average / 6));
System.out.println("Median: " + storedSums[2]);
The average is simply the process of summing the values and dividing by the amount. The median with a hashmap is a little bit more tricky, however. The better choice here is to use an Array or an ArrayList to store the different values, then sort them and finally pick the middle element (either index 2 or 3).
I opted for an array in this case because we know the size of it.
EDIT: Regarding your last request:
To get the dice the median value corresponds to, I simply convert the array to a list, and use the indexOf method with the known value:
int medianDice = Arrays.asList(storedSums).indexOf(storedSums[2]);
System.out.println("Median: " + storedSums[2] + ", which belongs to dice: " + medianDice + ".");
It's a bit more complicated to get the value of the dice for the average (since this number isn't represented by one of the dies). You would have to use the average to find the closest value in the array, and then output the index for that value.
You are over writing the same random int value again and again, so use an array of int to store the values as shown below:
int[] random = new int[amount];//declare an array
Random randomNumber = new Random();
for (int i = 0; i < amount; i++) {
random[i] = randomNumber.nextInt(7);
}
Also, use java.util.Random nextInt() with an upper bound (in your case, the max value for the dice can be 6, so use upper bound as 7) to generate the random numbers as shown above.
you could use an ArrayList to store the random numbers and later process it when needed.
List<Integer> listOfNumbers = new ArrayList<>(amount);
Random generator = new Random();
for (int i = 0; i < amount; i++)
{
listOfNumbers.add(generator.nextInt(7));
}
Also, your current algorithm for the random numbers is incorrect, you should use the Random class to generator random numbers between 1 - 6 (inclusive).
import java.util.Scanner;
import java.util.Random;
public static void main(String[] args){
Scanner inputReader = new Scanner(System.in);
System.out.println("How many times do you want to roll the dice:");
int num_rolls = inputReader.nextInt();
int NUM_SIDES_ON_DICE = 6;
int[] results = new int[NUM_SIDES_ON_DICE]
Random rand = new Random();
for (int i = 0; i < num_rolls; i++) {
results[rand.nextInt(NUM_SIDES_ON_DICE)] += 1
}
for (int i = 0; i < dice.length; i++) {
System.out.println("Number of " + (i+1) + "'s thrown: " + results[i]
}
}
Version with stream:
new Random()
.ints(amount, 1, 7).boxed()
.collect(Collectors.groupingBy(s -> s))
.forEach((k, v) -> System.out.println(k + ": "+v.size()));;

How to average random numbers in java?

thanks in advance for any help I'm in an intro to java class and our home work was to generate 10 random numbers between 1&50 which I got and then average the generated numbers. I can't figure out how to average them here's what I have. Is there a way to store each random number as a variable?
public class randomNumberGen
{
public static void main(String [] args)
{
Random r=new Random();
for (int i=1;i<=10;i++){
System.out.println(r.nextInt(50));
System.out.println();
int average = (i/4);
System.out.println("your average is"+average);
}
}
}
use streams with java 8
final int numberOfRandom = 10;
final int min = 0;
final int max = 50;
final Random random = new Random();
System.out.println("The ave is: "+random.ints(min, max).limit(numberOfRandom).average());
First of all you have to replace "r.nextInt(50)" for "r.nextInt(50) + 1" because r.nextInt(n) returns a number between 0 (inclusive) and n (exclusive). Then, you know that an average is just a sum of n values divided by n. What you can do is just declare a "total" variable initialized to 0 before the loop. On each iteration you add to this variable the random value generated by r.nextInt(50). After the loop you can just divide the total by 10 so you get the average.
PS: it's a good practice to don't use "magic numbers", so it would be perfect (and luckily your teacher will have it in count) if you declare a constant for the number of iterations and then use it both in the loop condition and in the average calculation. Like this, if you have to make it for 100 numbers you only have to change the constant value from 10 to 100 instead of replacing two 10's por two 100's. Also this gives you the chance to give semantic value to these numbers, because now they will be "AMOUNT_OF_NUMBERS = 10" instead of just "10".
Like every average, it's sum of elements / amount of elements. So let's apply it here:
import java.util.Random;
public class randomNumberGen
{
public static void main(String [] args)
{
Random r=new Random();
double sum = 0; // is double so to prevent int division later on
int amount = 10;
int upperBound = 50;
for (int i = 0; i < amount; i++){
int next = r.nextInt(upperBound) + 1; // creates a random int in [1,50]
System.out.println(next);
sum += next; // accumulate sum of all random numbers
}
System.out.println("Your average is: " + (sum/amount));
}
}
Store variables outside of the loop to store both the total amount of numbers generated as well as the sum of those numbers. After the loop completes, divide the sum by the total amount of numbers.
public static void main(String [] args)
{
Random r=new Random();
double sum = 0;
int totalNums;
for (totalNums=1;totalNums<=10;totalNums++){
int randomNum = r.nextInt(50);
sum += randomNum;
System.out.println(randomNum);
}
double average = sum/totalNums;
System.out.println("your average is: "+average);
}
Average = Sum of numbers / amount of numbers
int sum = 0;
for (int i=1;i<=10;i++){
sum += r.nextInt(50) +1; //nextInt 50 produces value 0 to 49 so you add 1 to get 1 to 50 OR as suggested in the comments sum/10d
}
System.out.println("Average is: " + sum/10) // If you want the result in double (with decimals) just write sum*1.0/10
You could also do the same with a while loop.
int i = 0;
int sum = 0;
while(i < 10){
sum += r.nextInt(50) +1;
i++;
}
System.out.println("Average is: " + sum*1.0/i);
Or even shorter with lambda expressions: (/java 8 streams)
OptionalDouble average = IntStream.range(1, 10).map(x-> x = r.nextInt(50) +1).average();
System.out.println("Average is "+ average.getAsDouble());
.map(x-> x = r.nextInt(50) +1) // maps (changes) each value from 1 to 10 to a random number between 1 and 50
.average(); // calculates the average.
Simply create a variable sum starting at zero that you increment at each iteration. After the loop, simply divide by the number of elements..
Average means you should add everything up and devide it by the number of elements (50).
import java.util.Random;
class Homework {
public static final Random RANDOM = Random(); // never regenerate randoms
public static void main(String args[]) {
final int N = 50;
int sum = 0;
for (int i = 0; i < N; ++i) {
sum += RANDOM.nextInt(50)+1;
}
System.out.println("Avg: "+ sum / (float) N);
}
}
This should do the trick. Try to learn from it not just C+P.
Ps: Friggin annoying to write code on a phone.

How do I write a random array of 5 integers but have it not count 0 as an integer?

I am trying to write a program that selects 5 integers at random between 1 and 6. I then need the program to display the missing integer. I can't figure out how to have it not display "0" as an integer. This is what I have so far...
import java.util.Random;
public class Task6
{
public static void main(String[] args)
{
int[] numbers = new int[5];
Random random = new Random();
for(int n = 1; n < 5; n++)
{
int select = random.nextInt(n + 1); //shuffle generator so it will not duplicate numbers
numbers[n] = numbers[select];
numbers[select] = n;
}//end for statement
for(int number : numbers)
{
System.out.println("Numbers selected : " + number);
}//end for
}
}
I have to have a O(n^2) operation in this as well.
If I understand correctly, you want your random numbers to only be between 1 and 6 (inclusive)? If that's the case then you need to restrict the range of what the RNG can actually spit out, using code similar to this:
/**
* Returns a pseudo-random number between min and max, inclusive.
* The difference between min and max can be at most
* <code>Integer.MAX_VALUE - 1</code>.
*
* #param min Minimum value
* #param max Maximum value. Must be greater than min.
* #return Integer between min and max, inclusive.
* #see java.util.Random#nextInt(int)
*/
public static int randInt(int min, int max) {
// NOTE: Usually this should be a field rather than a method
// variable so that it is not re-seeded every call.
Random rand = new Random();
// nextInt is normally exclusive of the top value,
// so add 1 to make it inclusive
int randomNum = rand.nextInt((max - min) + 1) + min;
return randomNum;
}
Also, your for loop:
for(int n = 1; n < 5; n++) { ... }
will not generate 5 numbers, it will generate 4. Think about the constraints of the loop; it will run through once with n = 1, 2, 3, 4, and then stop (5 is not less than 5).
If you want 5 iterations, you can do this:
for (int n = 0; n < 5; n++) { ... }.
or this:
for (int n = 1; n <= 5; n++) { ... }
Your number of iterations and your random number range don't need to be related.
Check this excellent answer for more detail if you need it.
Create a method that applies your constraints to the random number. Here is an example.
// this assumes that only 0 is unacceptable.
private static int myRandomBlammy()
{
int returnValue;
do
{
returnValue = blam; // replace blam with some way of generating a random integer.
} while (returnValue == 0);
return returnValue;
}
You should have an if statement on your loop that goes through the numbers.
for(int number : numbers)
{
if(number != 0){
System.out.println("Numbers selected : " + number);
}
}//end for
I am trying to write a program that selects 5 integers at random
between 1 and 6. I then need the program to display the missing
integer. I can't figure out how to have it not display "0" as an
integer.
From your question, there may be a case where your 5 random integers will not all be unique, and there may be more than one unique number that was not generated.
I would handle this with an array that counts how many of each number is generated:
import java.util.Random;
public class RandomCounter
{
/**
* An example that uses array indices to count how many random
* numbers are generated in a range.
*/
public static void main(String[] args)
{
//use an array of size n + 1 (ignore the zero index)
int[] numbers = new int[7];
Random r = new Random();
//generate random numbers
for (int i = 1; i < 6; i++){
int next = r.nextInt(6) + 1;
numbers[next]++; //count each number at the index
}
//print any numbers that didn't occur at least once.
for(int i = 1; i < numbers.length; i++){
if(numbers[i] != 0){
System.out.println(i);
}
}
}
}
Replace the last for-loop with this code snippet to see how many of each number occurred:
//print how many of each number occurred.
for(int i = 1; i < numbers.length; i++){
System.out.println (i + ": " + numbers[i]); }
}
Array index counting is a useful way to dynamically count occurrences of numbers.

What is the logical difference between these two classes?

I have written a Java class to solve a problem in the textbook, Javanotes 7, which asks for a program that displays statistics related to the number of rolls it takes to get a given value on a pair of dice. My class does not give me the correct statistics, yet—as far as I can tell—it is logically identical to the solution given in the textbook. Obviously it is not.
Here is my code:
/**
This program rolls a pair of dice until they come up a certain value. It repeats this for a certain number of trials and then gives the user the average number of
rolls required to achieve the target value. It does this for each possible value of two six-sided dice. It also gives the standard deviation and the maximum
number of rolls.
*/
public class DiceAverage{
static final int SAMPLE_SIZE = 10000;
public static void main(String[] args){
System.out.println("Total on Dice Average Number of Rolls Standard Deviation Maximum Number of Rolls");
System.out.println("------------- ----------------------- ------------------ -----------------------");
//each dice value iterator
for(int i = 2; i < 13; i ++){
//for each value, create a Statcalc, and PairOfDice object
StatCalc dataset = new StatCalc();
PairOfDice dice = new PairOfDice();
//each trial iterator
for(int j = 0; j < SAMPLE_SIZE; j ++){
int counter = 1;//counter for number of rolls. Initialized at 1 because dice object is rolled upon construction.
//get die1 and die2
while(dice.getDie1() + dice.getDie2() != i){
dice.roll();
counter ++;
}
dataset.enter(counter);
}
System.out.printf(" %-19d%-25.3f%-25.3f%1.3f%n", i, dataset.getMean(), dataset.getStandardDeviation(), dataset.getMax());
}
}
}
And here is the actual solution:
/**This program performs the following type of experiment:
* Given a desired total roll, such as 7, roll a pair of
* dice until the given total comes up, and count how many
* rolls are necessary. Now do the experiment over and over,
* and find the average number of rolls. The number of times
* the experiment is repeated is given by the constant,
* NUMBER_OF_EXPERIMENTS. Several statistics are computed and
* printed out for each possible roll = 2, 3, ..., 12:
* the average number of rolls, the standard deviation,
* and the maximum number of rolls.
*/
public class DiceRollStats2 {
static final int NUMBER_OF_EXPERIMENTS = 10000;
private static PairOfDice dice = new PairOfDice();
// A single pair of dice, which will be used for all
// the experiments.
public static void main(String[] args) {
System.out.println("Dice Total Avg # of Rolls Stand. Deviation Max # of Rolls");
System.out.println("---------- -------------- ---------------- --------------");
for ( int total = 2; total <= 12; total++ ) {
StatCalc stats; // An object that will compute the statistics.
stats = new StatCalc();
for ( int i = 0; i < NUMBER_OF_EXPERIMENTS; i++ ) {
// Do the experiment of counting the number of rolls
// required to roll the desired total, and enter the
// number of rolls into stats' dataset.
stats.enter( rollFor(total) );
}
System.out.printf("%6d", total);
System.out.printf("%18.3f", stats.getMean());
System.out.printf("%19.3f", stats.getStandardDeviation());
System.out.printf("%14.3f", stats.getMax());
System.out.println();
}
} // end main
/**
* Roll the dice repeatedly until the total on the
* two dice comes up to be N. N MUST be one of the numbers
* 2, 3, ..., 12. (If not, this routine will go into an
* infinite loop!). The number of rolls is returned.
*/
static int rollFor( int N ) {
int rollCt = 0; // Number of rolls made.
do {
dice.roll();
rollCt++;
} while ( dice.getDie1() + dice.getDie2() != N );
return rollCt;
}
} // end class DiceRollStats2
I cannot see the logical difference between these. What is it?
You are counting 1 extra roll by initializing int counter = 1;
Try initializing it with 0.
int rollCt = 0; // Number of rolls made.
do {
dice.roll();
rollCt++;
} while ( dice.getDie1() + dice.getDie2() != N );
return rollCt;
Here the dice are rolled before the boolean test in the do...while loop.
int counter = 1;//counter for number of rolls. Initialized at 1 because dice object is rolled upon construction.
//get die1 and die2
while(dice.getDie1() + dice.getDie2() != i){
dice.roll();
counter ++;
}
Whereas here the dice are rolled after the boolean test. So if the dice become equal to i, the dice values are never changed by roll()—as the while loop is skipped—and you get a bunch of iterations through the for loop with count == 1. Basically, the dice roll is not simulated properly this way.

Categories

Resources