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;
}
Related
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 ++;
}
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.
I have created a program which compares different search methods which search for a random int value 0-999 from a sorted array which is 0-999. I have created a binary search which works perfectly and after doing this I decided to try to create a search which, instead of splitting the values into half, splits them into 1/3 and 2/3 depending.
So basically if I have
{1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
and I was looking for 10 I would go from above to
{6,7,8,9,10,11,12,13,14,15}
to
{10,11,12,13,14,15}
to
{10,11}
then
simple {10} and return the index of this value.
I currently have:
int loopTotal3 = 0;
for(int y = 0; y < 1000; y++){
System.out.println("Reference1");
int first = 0;
int last = array0Through999.length - 1;
int third = (array0Through999[0] + array0Through999[999]) / 3;
int findThis3 = rand.nextInt(1000);
int loop3 = 0;
while(first <= last){
System.out.println("Reference2");
loop3++;
if (array0Through999[third] < findThis3){
System.out.println("Reference3");
first = third + 1;
}
else if(array0Through999[third] == findThis3){
System.out.println("Reference4");
break;
}
else{
System.out.println("Reference5");
last = third-1;
}
third = (first + last) / 3;
}
loopTotal3 = loopTotal3 + loop3;
}
int loopAverage3 = loopTotal3 / 1000;
System.out.println("The average number of times for a Binary Search is: " + loopAverage3 + "\n");
The code is currently getting stuck running through the first if statement and I am not positive of why.
Any ideas about my issue or if this logic is close to correct?
Using the same algorithm on a smaller data set, I can see an issue. Use an array with only 3 members: 0 1 2. Try to find 2. Third will get stuck on 1, and never get up high enough to find 2.
This will infinitely loop never getting third up to 2. You may be hitting a similar window somewhere else in the code. Because it enters the first if, it does first = third + 1 which yields first = 2. third=(first+last)/3=4/3=1.
import java.util.Random;
public class weqfgtqertg {
public static void main(String args[]) {
int array0Through999[] = {0,1,...,999};
int loopTotal3 = 0;
Random rand = new Random();
for(int y = 0; y < 1000; y++){
//System.out.println("Reference1");
System.out.println(y);
int first = 0;
int last = array0Through999.length - 1;
int third = (first + last) / 3;
int findThis3 = rand.nextInt(1000);
int loop3 = 0;
while(first <= last) {
//System.out.println("Reference1");
loop3++;
if (array0Through999[third] < findThis3){
//System.out.println("Reference3");
first = third+1;
}
else if(array0Through999[third] == findThis3){
//System.out.println("Reference4");
break;
}
else{
//System.out.println("Reference5");
last = third-1;
}
int calc = last - first;
third = first + (calc/3);
}//end while
loopTotal3 = loopTotal3 + loop3;
}//end for
int loopAverage3 = loopTotal3 / 1000;
System.out.println("The average number of times for a Tertiary Search is: " + loopAverage3);
}
}
It has been a while since I posted this question but I finally got around to solving my issue. Here is the correct code for anyone who may stumble upon this.
edit: The array includes the "..." to make this not obnoxious to read or put out onto the screen. I had all 0-999 within my array hard coded.
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.
This is the question I've been assigned:
A so-called “star number”, s, is a number defined by the formula:
s = 6n(n-1) + 1
where n is the index of the star number.
Thus the first six (i.e. for n = 1, 2, 3, 4, 5 and 6) star numbers are: 1, 13, 37,
73, 121, 181
In contrast a so-called “triangle number”, t, is the sum of the numbers from 1 to n: t = 1 + 2 + … + (n-1) + n.
Thus the first six (i.e. for n = 1, 2, 3, 4, 5 and 6) triangle numbers are: 1, 3, 6, 10, 15, 21
Write a Java application that produces a list of all the values of type int that are both star number and triangle numbers.
When solving this problem you MUST write and use at least one function (such as isTriangeNumber() or isStarNumber()
or determineTriangeNumber() or determineStarNumber()). Also you MUST only use the formulas provided here to solve the problem.
tl;dr: Need to output values that are both Star Numbers and Triangle Numbers.
Unfortunately, I can only get the result to output the value '1' in an endless loop, even though I am incrementing by 1 in the while loop.
public class TriangularStars {
public static void main(String[] args) {
int n=1;
int starNumber = starNumber(n);
int triangleNumber = triangleNumber(n);
while ((starNumber<Integer.MAX_VALUE)&&(n<=Integer.MAX_VALUE))
{
if ((starNumber==triangleNumber)&& (starNumber<Integer.MAX_VALUE))
{
System.out.println(starNumber);
}
n++;
}
}
public static int starNumber( int n)
{
int starNumber;
starNumber= (((6*n)*(n-1))+1);
return starNumber;
}
public static int triangleNumber( int n)
{
int triangleNumber;
triangleNumber =+ n;
return triangleNumber;
}
}
Here's a skeleton. Finish the rest yourself:
Questions to ask yourself:
How do I make a Triangle number?
How do I know if something is a Star number?
Why do I only need to proceed until triangle is negative? How can triangle ever be negative?
Good luck!
public class TriangularStars {
private static final double ERROR = 1e-7;
public static void main(String args[]) {
int triangle = 0;
for (int i = 0; triangle >= 0; i++) {
triangle = determineTriangleNumber(i, triangle);
if (isStarNumber(triangle)) {
System.out.println(triangle);
}
}
}
public static boolean isStarNumber(int possibleStar) {
double test = (possibleStar - 1) / 6.;
int reduce = (int) (test + ERROR);
if (Math.abs(test - reduce) > ERROR)
return false;
int sqrt = (int) (Math.sqrt(reduce) + ERROR);
return reduce == sqrt * (sqrt + 1);
}
public static int determineTriangleNumber(int i, int previous) {
return previous + i;
}
}
Output:
1
253
49141
9533161
1849384153
You need to add new calls to starNumber() and triangleNumber() inside the loop. You get the initial values but never re-call them with the updated n values.
As a first cut, I would put those calls immediatly following the n++, so
n++;
starNumber = starNumber(n);
triangleNumber = triangleNumber(n);
}
}
The question here is that "N" neednt be the same for both star and triangle numbers. So you can increase "n" when computing both star and triangle numbers, rather keep on increasing the triangle number as long as its less the current star number. Essentially you need to maintain two variable "n" and "m".
The first problem is that you only call the starNumber() method once, outside the loop. (And the same with triangleNumber().)
A secondary problem is that unless Integer.MAX_VALUE is a star number, your loop will run forever. The reason being that Java numerical operations overflow silently, so if your next star number would be bigger than Integer.MAX_VALUE, the result would just wrap around. You need to use longs to detect if a number is bigger than Integer.MAX_VALUE.
The third problem is that even if you put all the calls into the loop, it would only display star number/triangle number pairs that share the same n value. You need to have two indices in parallel, one for star number and another for triangle numbers and increment one or the other depending on which function returns the smaller number. So something along these lines:
while( starNumber and triangleNumber are both less than or equal to Integer.MAX_VALUE) {
while( starNumber < triangleNumber ) {
generate next starnumber;
}
while( triangleNumber < starNumber ) {
generate next triangle number;
}
if( starNumber == triangleNumber ) {
we've found a matching pair
}
}
And the fourth problem is that your triangleNumber() method is wrong, I wonder how it even compiles.
I think your methodology is flawed. You won't be able to directly make a method of isStarNumber(n) without, inside that method, testing every possible star number. I would take a slightly different approach: pre-computation.
first, find all the triangle numbers:
List<Integer> tris = new ArrayList<Integer>();
for(int i = 2, t = 1; t > 0; i++) { // loop ends after integer overflow
tris.add(t);
t += i; // compute the next triangle value
}
we can do the same for star numbers:
consider the following -
star(n) = 6*n*(n-1) + 1 = 6n^2 - 6n + 1
therefore, by extension
star(n + 1) = 6*(n+1)*n + 1 = 6n^2 + 6n +1
and, star(n + 1) - star(n - 1), with some algebra, is 12n
star(n+1) = star(n) + 12* n
This leads us to the following formula
List<Integer> stars = new ArrayList<Integer>();
for(int i = 1, s = 1; s > 0; i++) {
stars.add(s);
s += (12 * i);
}
The real question is... do we really need to search every number? The answer is no! We only need to search numbers that are actually one or the other. So we could easily use the numbers in the stars (18k of them) and find the ones of those that are also tris!
for(Integer star : stars) {
if(tris.contains(star))
System.out.println("Awesome! " + star + " is both star and tri!");
}
I hope this makes sense to you. For your own sake, don't blindly move these snippets into your code. Instead, learn why it does what it does, ask questions where you're not sure. (Hopefully this isn't due in two hours!)
And good luck with this assignment.
Here's something awesome that will return the first 4 but not the last one. I don't know why the last won't come out. Have fun with this :
class StarAndTri2 {
public static void main(String...args) {
final double q2 = Math.sqrt(2);
out(1);
int a = 1;
for(int i = 1; a > 0; i++) {
a += (12 * i);
if(x((int)(Math.sqrt(a)*q2))==a)out(a);
}
}
static int x(int q) { return (q*(q+1))/2; }
static void out(int i) {System.out.println("found: " + i);}
}