Java, program that counts random number and saves it - java

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()));;

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.

How to write a code to find the mode of the ints in the array without using a personally created method ie just regular "raw code"

I'm writing a code to find the mean, median and mode of an array of randomly generated ints (user inputs a size for the array and a range between which random numbers are to be generated it generate numbers between 3-22 randomly. I have not had too much trouble writing code for a mean or median but I cannot seem to be able to write code to calculate the mode (most commonly occurring number). Can anyone help or show/put code for how to calculate the mode of a randomly generated array of ints without having to create a method for yourself in the code? Thanks. Here is what I have so far (code that finds the mean and median):
public class ArraysIntsMeanMedianAndMode {
public static void main(String[] args) {
int ArraySize;
int min;
int max;
double x;
// To get the Size and range of numbers for the randomly genereated ints in the array.
Scanner sc = new Scanner(System.in);
System.out.println("What size should the array be?");
ArraySize = sc.nextInt();
System.out.println("Please enter a minimum value for the range of ints.");
min = sc.nextInt();
System.out.println("Please enter a maximum value for the range of ints.");
max = sc.nextInt();
//Making the array and filling it based on the user inputs
int[] MMMarray = new int[ArraySize];
int total = 0;
for (int i = 0; i < ArraySize; i++) {
x = (int) (Math.random() * ((max - min) + 1)) + min;
System.out.println(x);
int RandoNums = (int) x;
total = total + RandoNums;
MMMarray[i] = RandoNums;
}
//Finding mean/average
double Mean = (total + 0.0) / ArraySize;
System.out.println("The mean is: " + Mean);
//Finding Median/Middle number
Arrays.sort(MMMarray);
System.out.println(Arrays.toString(MMMarray));
if (ArraySize % 2 == 0) {
System.out.println("The median is: " + ((MMMarray[(ArraySize / 2)] + 0.0) + MMMarray[(ArraySize / 2) - 1]) / 2 + ".");
} else System.out.println("The median is: " + MMMarray[ArraySize / 2] + ".");
//How to find mode????????
Finding mode of unsorted array of int:
int freq = 0;
int value = 0;
int length = MMMArray.length;
for (int outer = 0; outer < length; outer++)
{
int tempFreq = 0;
for (int inner = 0; inner < length; inner++)
{
if (MMMArray[outer] == MMMArray[inner])
{
tempFreq++;
}
}
if (tempFreq > freq)
{
freq = tempFreq;
value = MMMArray[outer];
}
}
System.out.println("Mode is " + value + ", which appears " + freq + " times.");
Because you have already sorted the array to calculate the median, the problem of finding the mode(s) becomes equivalent to finding the longest consecutive streak of the same number. So, for example, if you have [1, 1, 2, 2, 2, 3, 5, 5, 21], there are three consecutive 2's, which is longer than any other run, so 2 is the mode.
To find the longest run, you can pass over the data once more, not reading any element twice. I'm adapting the code of Litvin and Litvin ever so slightly to use your array name, to count a run of 1 as a run, and to report what number the mode is rather than where it is in the array. You can drop this code in right where you ask your question, after the median has been calculated.
// at this point MMMArray is a sorted, nonempty array of int, because it was already sorted to find the median
int maxRunStart = 0, maxRunLength = 1;
int runStart = 0, runLength = 1;
for (int i = 1; i <= MMMArray.length; i++) //what they do here by using <=
//rather than < is worth reflecting upon
//it handles the case of the biggest run being at the end within the loop body
{
if (i < MMMArray.length && MMMArray[i] == MMMArray[i - 1])//notice how the boolean short-circuit prevents reading beyond the end of the array
{
runLength++;
}
else
{
if (runLength > maxRunLength)
{
maxRunStart = runStart;
maxRunLength = runLength;
}
runStart = i;
runLength = 1;
}
}
System.out.println("The mode is: " + MMMArray[maxRunStart] + ".");
}
Now here is something new to ponder. Suppose MMMArray contains [1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3]. This code (or that of MarsAtomic) will report 1 is the only mode. But the data is bimodal, and 3 is the mode as much as 1 is. One way to adapt the code would be to store the mode(s) in an array list (or an array, because we know up front there cannot be more modes than numbers). I think it is simpler (not more efficient, just easier not to mess up and without introducing another non-simple type) to make one more pass over the data. If you want that, then after the first for loop, instead of the println of the one mode, insert the following:
runLength = 1;
runStart = 0;
for (int i = 1; i <= MMMArray.length; i++)
{
if (i < MMMArray.length && MMMArray[i] == MMMArray[i - 1])
{
runLength++;
}
else
{
if (runLength == maxRunLength)
{
System.out.println("The mode is: " + MMMArray[runStart] + ".");
}
runStart = i;
runLength = 1;
}
}

How can I find out the four unique random numbers in Android within the range of 1 to 60?

This is what I tried so far in my app.
I got this code by searching it from Google.
Inside the Button OnClick() I called the Arandom() method:
public void Arandom(View view) {
final int SET_SIZE_REQUIRED = 4;
final int NUMBER_RANGE = 70;
Random random = new Random();
Set set = new HashSet<Integer>(SET_SIZE_REQUIRED);
while(set.size()< SET_SIZE_REQUIRED) {
while (set.add(random.nextInt(NUMBER_RANGE)) != true) ;
}
assert set.size() == SET_SIZE_REQUIRED;
ArrayList<Integer> Elements = new ArrayList<>(set);
Log.i("Elements","A:" + Elements.get(0));
Log.i("Elements","B:" + Elements.get(1));
Log.i("Elements","C:" + Elements.get(2));
Log.i("Elements","D:" + Elements.get(3));
}
Now I am able to get four unique random numbers by this code but the problem is there sum is greater then 60. Let me explain it little bit.
When I run the code I get:
A:61
B:45
C:31
D:49
This is the screen shot of my log cat
So I want the sum of all the numbers should be in the specified range (which is 1 to 60).
e.g: A = 20 , B = 25 , C = 3 and D = 11 then their sum is 59 which is within the range
Now another e.g: Suppose A = 5 , B = 22 , C = 18 and D = 3 then their sum will be 48
When we Add A,B,C,D then their sum should not exceed the range that is 60
I am new to Android and Java, and I am learning on my own by searching some materials on Google.
Let's say your target sum is T. It's easiest if you try to pick the numbers in descending order (you can shuffle them afterwards, if you want).
The largest number you can pick for the 1st of four numbers is T-6, because you need to pick 3, 2 and 1 for the smaller numbers.
The smallest number you can pick is the one where n+(n-1)+2+1 = T, so T/2+1.
So, pick the first number in the range (T/2+1) to T-6.
Then repeat the process to pick the third-largest and second-largest, applying similar logic to determine the possible range. There should be no choice in the smallest number, it's just whatever else you need to add to make the final sum.
Note that you need to take care with rounding of things like the T/2.
I made the return type an int[]. You know how big you want to make the set, so there is no need to use sets or lists. The input parameter is changed to SET_SIZE_REQUIRED instead of using view. Make sure that a funtion only has one purpose and not do a calculation and change on a view at the same time.
Replace the 60f to something else if you want the sum to be more or less than 60.
public int[] Arandom(int numberOfValues) {
int[] values = new int[numberOfValues];
int sum = 0;
for(int i = 0; i < numberOfValues; i++){
values[i] = (int)(Math.random() * 100);
sum += values[i];
}
float multiplier = 60f / sum;
for(int i = 0; i < numberOfValues; i++){
values[i] = (int)(values[i] * multiplier);
Log.i("Value " + (i + 1), values[i]);
}
return values;
}
Or just do this:
public int[] Arandom(int numberOfValues) {
int[] values = new int[numberOfValues];
for(int i = 0; i < numberOfValues; i++){
values[i] = (int)(Math.random() * (60f / numberOfValues));
Log.i("Value " + (i + 1), values[i]);
}
return values;
}

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 to generate all numbers randomly between two given integers without duplication in Java?

I found answers on how to generate random numbers but nowhere how to generate all the numbers in the range without duplication in Java. Please share if you have a solution. Below is what I did but it simply generates randomly the numbers. I need to print out all numbers in the range without duplication!
package com.company;
import java.util.*;
public class RandomizeNumbers {
public static void main(String[] args) {
//Create Scanner
Scanner userInput = new Scanner(System.in);
//Ask for numbers N and M
System.out.println("Please enter two numbers and the program will randomize the numbers between them. " +
"The first number N must be bigger or equal to the second number M");
System.out.println("Please enter the first number N");
int n = userInput.nextInt();
System.out.println("Please enter the second number M");
int m = userInput.nextInt();
Random randomGenerator = new Random();
int difference = n - m;
//Randomize the numbers
if (m<=n){
for(int i = 0; i<= difference; i++ ) {
int randomInt = randomGenerator.nextInt(n - m + 1) + m;
System.out.println(randomInt);
}
}
else{
System.out.println("Please enter M less or equal to N");
}
}
}
What you need maybe generating a random permutation, pls see this link How to generate a random permutation in Java?
You can store generated number in a array.then after generate the next number check is there this number in array or no.
There are many ways to achieve this, lets suppose you want 50 numbers between A and B, then use a java.util.Set, since this collection does "ignore" duplicated values: following snippet describe it better:
Set<Integer> setA = new HashSet<Integer>();
Random r = new Random(System.currentTimeMillis());
int low = 10;
int high = 100;
int rnd = r.nextInt(high - low + 1) + low;
int maxCount = 50;
while (setA.size() < maxCount ) { //<--how many random numbers do you need?
rnd = r.nextInt(high - low + 1) + low;
setA.add(rnd);
}
and be careful, not to get in an infinite loop.
(there are only "B-A" possible integer options between A and B, so MaxCount<= B-A)
What I suggest you to do is to create a List and then shuffle it.
ArrayList<Integer> list = new ArrayList();
int high = 20;
int low = 10;
for(int i = low; i <= high; ++i)
list.add(i);
Collections.shuffle(list);
And then create a function to get a random Unique number each time.
static int index = 0;
public int roll(ArrayList<Integer> list)
{
return list.get(index ++);
}
You can put all the numbers between n & m into a list and then use Collections.shuffle(list) to make the numbers ordered randomly in the list.
if (difference > 0) {
List<Integer> integers = new ArrayList<>();
for (int i = 0; i <= difference; ++i) {
integers.add(m + i);
}
Collections.shuffle(integers);
for (Integer randNum : integers) {
System.out.print(randNum + "\t");
}
System.out.println();
} else {
System.out.println("Please enter M less or equal to N");
}

Categories

Resources