Rolling two dice and obtaining the average of count - java

I'm writing a java program that simulates rolling two dices and incrementing a counter whenever both dices do not have the same face. After a number of rolls, i want to print out the average of the count.
int i = 0;
int count = 0;
double average = 0;
int j = 0;
while (i<1000) {
int dice1 = getRandom(1,6);
int dice2 = getRandom(1,6);
if (dice1 != dice2) {
count++;
}
while (j!= 1000) {
average = (count/j);
j++;
}
i++;
}
System.out.println(average)
The program doesn't give me the average as I'm quite sure the nested while loop is written wrongly?
the getRandom() function returns a random value between 1 to 6 since a dice can have 6 values.
private static int getRandom(int n1, int n2){
int retVal = 0;
retVal = n1 + (int) Math.floor(Math.random() * (n2 - n1 + 1));
return retVal;
}
I'm a beginner at java, would appreciate some help on this.

Your logic should be:
Make some number of dice rolls, and record the number of non equal rolls, and the total number of rolls
Then take the average outside of the loop
Something like this:
static final int NUM_ROLLS = 1000;
for (int i=0; i < NUM_ROLLS; ++i) {
int dice1 = getRandom(1,6);
int dice2 = getRandom(1,6);
if (dice1 != dice2) {
count++;
}
}
double average = 1.0*count / NUM_ROLLS;
System.out.println(average)
Note carefully that in the division multiplies by 1.0, to force double precision division.
The biggest problem I saw in your code is that you were taking the average inside the loop, which doesn't make sense, because your tally of non equal rolls has not yet finished.

Name your variables better.
Instead of i, call it rolls
Instead of count, call it nonmatching.
Then you'll see that you have this third, unnecessary variable called j which is really not providing anything to the solution (except being a main part of the source of your current problem).
Naming variables in a way that they provide you value is a hard thing. Get started on it early, it will save you more time when rereading your code than any other skill.
For pointers, read up on "intentional naming" which means, "naming the variable how you intend to use it" and not the obvious "naming it the way you intended to name it" (I swear I heard a developer describe it that way to me /shudder/)
Yes, you can do the calculation once, outside of the loop, too. But you'd get the right answer if you started with the right inputs.

Related

How to write a java program that computes the value of e^x

I'm trying to figure out how to answer this question for my Java class, using only while loops:
Write an application that computes the value of mathematical constant e^x by using the following formula. Allow the user to enter the number of terms to calculate. e^x = 1 + (x/1!) + (x^2/2!) + (x^3/3!) + ...
I can't figure out how I would do this without also asking the user for a value for x? Below is the code that I created for calculating x with the number of terms and just the number 1 for the exponent of each fraction. Any help is appreciated
import java.util.Scanner;
public class FactorialB {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int counter = 0;
float answer = 0;
System.out.print("Enter number of terms: ");
int n = scanner.nextInt();
while (counter < n) {
double factorial = 1;
int factCounter = counter;
while (factCounter > 1) {
factorial = factCounter * factorial;
factCounter--;
}
answer += 1 / factorial;
counter++;
}
System.out.printf("e = %f%n", answer);
}
}
Firstly the question you seem to be asking:
There is no way to make a program that will give e for a specific number unless you ask the user for that number.
However it might be that they just want you to make a method that provides the solution (if it were called) independently of user input. (because the code to get user input isn't very interesting, what is interesting is how you reach the result).
An alternative way to provide x and n are for instance passing them as commandline arguments. (args[] in your main would be a way to provide them)
I would create a separate method that receives x and n that covers the main calculation:
e^x = 1 + (x/1!) + (x^2/2!) + (x^3/3!) + ...
And separate methods that cover 'calculating a single term (x^1/1!), (x^2/2!), etc' and 'factorialize(n)'
public void calculatePartialE_term(int x, int n) {
if (n == 0) {
return 1; // this will allow you to use a while loop, covers the n = 0 case
} else {
// removed the implementation, but basically do
// x^n/n! here for whatever value of n this term is calculating.
}
}
public int calcualteNFactorial(int n) {
// assert n >= 1
// use a while loop to calculate n factorial
}
the benefit of doing this in a separate methods is that you can prove / verify the working of calculatePartialE_term or calcualteNFactorial independently of one another.
now you can simply write a while loop based on x and n to do something like
public int calculateE_to_x(int x, int n) {
int current = 0;
int sum = 0;
while (current <= n) {
sum += calculatePartialE_term(x, current);
}
}
I wouldn't expect your teacher to expect you to show code that handles user input but even if that is the case it will be easier for them to verify your work if the actual work (of calculating) is done in a separate method.

How to calculate the sum of values generated by a loop

I am an extreme beginner at this, so the answer might be obvious and staring me in the face. I need to add together three numbers generated by a loop. The numbers are random (btw 1 and 6) and taken from another method. I can't seem to figure out how to use any of the values generated by the loop once it terminates.
It's for a homework assignment where we're supposed to simulate a dice-rolling game, and part of the assignment is to add together three dice rolls in order to display the score. I assume I'm supposed to add together the three rolls in order to get the score, but I 1) don't know where to add them together (inside of the loop? outside of it, and how do I in that case retrieve the values from the loop?), and 2) don't even know if just saying that score = roll+roll+roll is the right way to go about it. I feel like have missed something somewhere.
int score = getScore();
System.out.println(score);
}
static int diceRoll () {
int range = (6-1) + 1;
double roll = Math.random() * range;
return (int)roll + 1;
}
public static int getScore () {
int score = 0;
int roll = 0;
int i = 1;
for (i=1; i<=3; i++) {
roll = diceRoll();
//I added this in order to make sure that the first part works
System.out.print(roll + " ");
}
score = roll+roll+roll;
return score;
In an ideal world this would display three random numbers between (and including) 1 and 6 (which it does), as well as the sum of these three numbers (e.g for 2, 4, 6, score would be 12).
It checks out sometimes, but most of the time it returns completely random numbers. I suspect that this is the completely wrong way of doing it, but I can't really think of what to do.
Code with comments
static void main(String[] args) {
int score = getScore();
System.out.println(score);
}
static int diceRoll() {
int min = 1;
int max = 6;
return ((int)(Math.random() * ((max - min) + 1)) + min);//it'll return values between 1 and 6
}
public static int getScore() {
int score = 0;
int roll = 0;
for (int i = 1; i <= 3; i++) {
roll = diceRoll();//you first need save the returned value
score = score + roll; //at this point you accumulate the returned values
System.out.print(roll + " ");
}
return score;
}

For loop, running a 1000 times the program, average number of rolls required to get snake eyes in JAVA

So I posted my question earlier and thought I was all good, but I messed up and realized I had understood the question completely wrong.
I do not need to calculate the average of snake eyes over 1000 dice rolls, but the average of number of rolls to get a snake eyes, over a 1000 play.
I am a little lost in how to accomplish that.
I tried this:
public class RollDiceforloop {
public static void main(String[] args) {
int die1, die2, snakeye, rolls, game;
snakeye = 0;
die1 = 0;
die2 = 0;
rolls = 0;
for (game = 0; game < 1000; game++) {
die1 = (int)(Math.random()*6)+1;
die2 = (int)(Math.random()*6)+1;
if (die1 != 1 && die2 != 1); {
rolls +=1;
}
if (die1 == 1 && die2 == 1) {
snakeye +=1;
rolls +=1;
}
}
float average = snakeye / (float) rolls;
TextIO.putln(""+snakeye+" Snake Eyes over "+game+" games, with an average of "+average+" rolls required to get a Snake Eye.");
}
}
But I am not getting the correct result. I am a bit lost on how to accomplish this. Help please?
A way to simply calculate the number of throws it took you to get a Snakeeyes would be the following:
int count = 0;
for (int i = 0; i < 1000; ++i)
{
int result = 0;
while (result != 2)
{
result = (int) (Math.random() * 6) + (int) (Math.random() * 6) + 2;
++count;
}
}
System.out.println(count / 1000.d);
Running should get you a result of round about 36, which is basically the expected value as you have a chance of 1/36 on each throw to get a Snakeeyes, so in theory on the long run you will get one every 36 throws.
However, this is kinda skewed math. Does this tell you that after 37 throws without a Snakeeyes your die are inbalanced? Or that if you get a Snakeeyes after 2 rolls you are cheating somehow?
No, obviously not.
This is where math comes into the equation. Let me say this first, there is no way to calculate the exact number of throws it's going to take you to get a Snakeeyes. What we can do is calculate a probability based on a confidence.
A confidence here is basically saying:
I want a chance of x% to get a snakeeyes.
x is the confidence. With the confidence you can use the simple formula of
1 - (35 / 36) ^ n > x and solve this for n to get a number of throws that with the given confidence will give you one or more snakeeyes. Note that 35/36 is the chance to not get a snakeyes but anything else.
So let's say we really really want that snakeeyes. We take a confidence of 99.9%.
With the formula this gets us n = 246. So we need 246 throws to get a 99.9% chance of at least one snakeeyes.
How about us gambling a bit more. We say that we are fine with just a 50% chance of getting a snakeyes. So with that we get n = 25.
Which is actually below our calculated value.
So what am I trying to say with that? You can obviously do an experiment with a big enough number of tries and in the end you will always get to the expected value of the throw (this is actually called the "Law of large numbers"). This however holds no value in determining how many throws you actually need to get a snakeeyes. It's just calculating the expected value. Which is something that doesn't really need an experiment for die.
So the method
return 36;
would actually be good enough here.
You got your logic a bit wrong. You need to do N amount of test(games) and every test has to wait until a snakeeye appears and count the necessary rolls. You could say you need to wait while no snakeeye appeared. To calculate the average you need to store the result of every test.
Example:
public static void main( String[] args )
{
int dice1;
int dice2;
// The amount of tests
final int SIZE = 10000000;
// store all results we got from a single test
int[] result = new int[SIZE];
// loop through the tests
for(int i = 0; i < SIZE;i++)
{
// initialize counter for every test
int rolls = 0;
do
{
// roll counter increases
rolls++;
dice1 = (int)(Math.random()*6)+1;
dice2 = (int)(Math.random()*6)+1;
// check if condition is met.
}while(dice1 != 1 || dice2 != 1);
// store the result of the test
result[i] = rolls;
}
// calculate the average amount of rolls necessary
double avg = Arrays.stream( result ).sum() / (double)SIZE;
System.out.println( avg );
}
Now my rolls required doesn't even compute.
public class RollDiceforloop3 {
public static void main(String[] args) {
int die1, die2, game, rolls;
rolls = 0;
for (game = 0; game < 1000; game++)
{
die1 = 0;
die2 = 0;
while (die1 != 1 || die2 != 1)
{
die1 = (int)(Math.random()*6)+1;
die2 = (int)(Math.random()*6)+1;
rolls +=1;
}
}
double average = rolls / (double) game;
TextIO.putln("The average number of rools required to get Snake Eyes is "+average+", after running the program 1000 times.");
}
}
If understood your code, I think you may wanna start counting over when achieved the snake eye, and increase the number of rolls otherwise. Also you probably want to increase the counter when only one of the rolls is equal to one. This two things may be polluting your result.
if (die1 == 1 && die2 == 1) {
snakeye ++;
rolls = 0;
} else {
rolls ++;
}

How can I generate a random number greater or less than a previous random number?

I am currently in a Java 1 class, and made a number guessing game for fun. Basic take input, tells you if it's too high or low, then lets you guess again. I thought it would be interesting to make it so the computer guesses as well, then compares your guesses to its. I have all of the generation and comparing working, but it continues to guess numbers without taking the greater/less than into account, which I want to add. I have:
public static void autoPlay(int num){
Random rand = new Random();
int guess1 = rand.nextInt(100) + 1;
int counter = 0;
while(guess1 != num){
counter++;
int guess = rand.nextInt(100) + 1;
int initialHigh = 100;
int initialLow = 0;
// I want it to guess smart and recognize if it were too high or too low, and generate a number between there
if(guess1 > num){
int newGuess = rand.nextInt(initialHigh - guess1) + 1;
}else if(guess1 < num){
int newGuess2 = rand.nextInt(initialLow + guess1) + 1;
}
initialLow = guess;
initialHigh = guess;
guess1 = guess;
System.out.printf("%3d", guess1);
}
System.out.println("It took " + counter + " guesses to get the correct number");
}
I can't tell what is wrong with my math in the if statement, or if theres just something I can call to do that.
If you want to avoid duplicates, then generate the appropriate numbers and shuffle it (for a full random function):
List<Integer> values = IntStream.range(0, /* max */).collect(Collectors.toList());
Collections.shuffle(values);
int guesses = values.indexOf(/* some number */) + 1;
The list would be fully randomly ordered, so you'd guess in order of the randomized list, thus the index is the number of guesses (-1, since it's 0-indexed)
The problem with your code is that you are just using the same bounds for the random number. You generate new bounds here:
if(guess1 > num){
int newGuess = rand.nextInt(initialHigh - guess1) + 1;
}else if(guess1 < num){
int newGuess2 = rand.nextInt(initialLow + guess1) + 1;
}
But you don't use them at all, you just reuse the values you had before:
initialLow = guess;
initialHigh = guess;
guess1 = guess;
System.out.printf("%3d", guess1);
You must use the values produced by newGuess and newGuess2 (althought you don't need these two variables, declare one of them outside the if and just assign a value to it inside the if). Then you will be using updated values.
I also noticed that you created many variables that store the same value, such as guess and guess1, which you don't need, you just need to declare one of them and reuse later (so you can save memory : ) ).
Also, I see a problem in setting initialHigh and initialLow both as guess, why would you want that?
Try to review your code logic and clean up some variables, some of them are duplicated.
But, in summary, I think the problem is that you are generating new bounds but you are not using them.
Let me know if this helped you and remember to upvote/select this answer as correct if it did : ). If you still have questions, post again.

Calculating Least Common Multiple (how do I know when there isn't one?)

The code below was my first attempt at a LCM (lowest common multiple) calculator with a user interface (UI code not shown) written months ago. I know there are simpler ways to write this, but I'd like help understanding why sometimes THIS specific code is not finding a common multiple (with most number sets it works fine).
When a user inputs almost any number set, the app spits out the correct LCM. But when the number set 1,234 / 2,345 / 5,432 / 4,321 is used, the app initially was stopping when x hit 536,870,912. This was because the result of x * mult was a number that couldn't be held by the int primitive. After changing x to a double and casting result = (int) (mult * x), the code continues to function as expected but seems to increment x indefinitely.
public static void compare(){
result = 0;
int mult = 0;
double x = 1;
int[] nums = UserInterface.getNums();
// finds highest number in user-input set
for(int i = 0; i < nums.length; i ++){
if (nums[i] > mult) mult = nums[i];
}
// finds lowest common multiple
for(int i = 0; i < nums.length;){
if((mult * x) % nums[i] == 0){
result = (int) (mult * x);
i++;
}
else{
result = 0;
x++;
i = 0;
}
}
}
We know the LCM of your test set must be less than or equal to 67,920,681,416,560.
In java the int datatype has a max value of 2^31-1 = 2,147,483,647 so you are obviously going to get an overflow. You can change your code to use long throughout this has a max value of 2^64-1=18,446,744,073,709,551,615 so it should be sufficient for your calculation. If you need bigger values then look at the BigInteger class.
In javascript things are more complicated. All numbers are floating point so you loose accuracy. This probably mean the condition
if((mult * x) % nums[i] == 0)
is never satisfied so your loop never quits.
Your algorithm is very basic, there are much better algorithms out there, elclanrs has one above and see https://en.wikipedia.org/wiki/Least_common_multiple for some hints.
Also you should change the title of the question. As it stands it make no sense as any set of numbers must have a LCM.

Categories