Here is the assignment:
For this program, there are two "parts". The first part will run the trials and determine how many caps each trial opens before finding a winning cap. Every trial (person) will be a winner. The number of caps opened by each trial is written to the file.
The second part of the program will read in the values and calculate the average. The average should be between 4.5 and 5.5 since there is a 1 in 5 chance of winning.
It compiles and runs, but the average is always 0.
My code:
int randNum = 0;
Random randNumList = new Random();
int counter = 0;
Scanner in = new Scanner(System.in);
System.out.println("How many trials will there be?");
int trials = in.nextInt();
int winner = 0;
PrintWriter outFile = new PrintWriter (new File("cap.txt"));
//run trials
for (int loop = 1; loop <= trials; loop++)
{
//select random number until 5 is selected
randNum = randNumList.nextInt(6);
for (randNum = randNumList.nextInt(6); randNum == 5; randNum++)
{
randNum = randNumList.nextInt(6);
counter++;
}
outFile.println(loop + " " + randNum);
}
outFile.close ( ); //close the file when finished
String token = " ";
Scanner inFile = new Scanner(new File("cap.txt"));
while (inFile.hasNext())
{
token = inFile.next();
if(token.equals("5"))
winner++;
}
double average = winner/counter;
System.out.println("The average number is " + average);
Apart from the int/int division accuracy problem which should be winner/(double)counter or (double)winner/counter try changing your inner for loop to a do while. In general, prefer while when you don't know the exact number of iterations.
Also, randNumList.nextInt(6) is [0-5], thus there are 6 possible outcomes -> there is a 1 in 6 chance of winning. To correct this, use randNumList.nextInt(5) + 1
for (int loop = 1; loop <= trials; loop++) {
//select random number until 5 is selected
do {
randNum = randNumList.nextInt(5) + 1;
counter++;
} while (randNum != 5);
outFile.println(loop + " " + randNum); //why here?? maybe you should add it below counter++;
}
also if(token.equals("5")) won't work, as you write (loop + randNum), it should work if you use outFile.println(randNum);
Your cap.txt file doesn't contain "5" => winner = 0 and average = 0/counter = 0 (always).
winner/counter returns an int not a double (integer division because both operands are integer so the result is truncated). Try this:
winner/(double)counter
That does return a double.
Related
Problem statement
Need to find the Arithmetic mean of numbers entered by user.
Constraints
We cannot ask user to define/share the number of "NUMBERS" user has planned to enter i.e. we cannot ask user to tell how many numbers he is going to enter.
If -1 is entered by user, the input should stop and Arithmetic mean should be displayed.
We are supposed to ask user only to enter the numbers for which Arithmetic mean is to be calculated. Like : User enters
2
4
7
10
-1
so we need to calculate arithmetic mean for 2,4,7,10 and display the result.
Code
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int sum = 0;
do {
System.out.println("Value is :" + n);
count++;
sum = sum + n;
}while ( n != -1);
}
It goes to infinite loop and I've also tried using if/else but i didn't work. Please assist.
For the input of :
3
9
4
-7
0
2
-1
The arithmetic mean should be calculated for 3,9,4,7,0,2,29 i.e. 1.8
Try this:
Scanner sc = new Scanner(System.in);
int sum = 0;
int count = 0;
int n = 0;
do {
System.out.println("Enter next number(-1 to exit): ");
n = sc.nextInt();
System.out.println("Value is :" + n);
if(n != -1)
{
count++;
sum = sum + n;
}
}while ( n != -1);
sc.close();
System.out.println("Mean is: " + (double) sum/count);
}
You needed to move your sc.nextInt(); into the loop so that you can keep entering in values. I also added an if statement so the -1 does not get used in the mean value.
You're reading "n" as input out of the while, then n has always the first value and the loop is infinite.
You just need to keep passing ints, otherwise n is forever the first value entered.
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int sum = 0;
do {
System.out.println("Value is :" + n);
count++;
sum = sum + n;
n = sc.nextInt();
}while ( n != -1);
I simply don't know where I'm getting it wrong. I've included the whole code. I'm trying to get the percentage part to display 30 distinct values, but it keeps displaying 29. Is there a simple fix to this and am I making this too complicated?
private static final Scanner
stdIn = new Scanner(System.in);
private static Random
rng;
public static void main (String[] args){
long
rngSeed;
int
numberOfFlips,
totalNumberOfRuns = 1,
run = 0;
boolean
theCoin,
tempVal = false;
System.out.println("Welcome to the coin flip analyzer.\n" +
"How many flips?");
numberOfFlips = stdIn.nextInt();
System.out.println("What do you want to seed the random number generator with?");
rngSeed = stdIn.nextLong();
int[]runLength = new int[50];
rng = new Random(rngSeed);
for (int i = 0; i < numberOfFlips; i++) {
theCoin = rng.nextBoolean();
if (i > 0 && theCoin != tempVal) {
if (i < 50) {
System.out.print(run + " ");
}
runLength[run - 1]++;
totalNumberOfRuns++;
run = 1;
}
else
run++;
if (theCoin) {
if (i < 50) {
System.out.print("H");
}
tempVal = true;
}
else {
if (i < 50) {
System.out.print("T");
}
tempVal = false;
}
}
System.out.print("...");
System.out.println();
System.out.println("There were a total of " + totalNumberOfRuns +
" distinct runs in the simulation.\nTheir breakdown follows.");
// run length table header line
System.out.println("[run length] = # (as percentage of all runs)");
// your code to display the count and frequency percentage of each run length
// should follow
for (int i = 0; i < runLength.length; i++) {
double percentageFreq = ((double) + (runLength[i]) / (totalNumberOfRuns) * 100);
if (runLength[i] > 0)
System.out.println("[" + (i+1) + "] = " + runLength[i] + " (" + String.format("%1.1f", percentageFreq) + " %)");
}
}
}
...............
Most Important Part of Outcome Using: 50 flips and a random seed value of 1200.
H1 T1 H1 T1 HHH3 TTTTT5 H1 T1 HHHH4 T1 HH2 T1 H1 T1 H1 T1 H1 T1 H1 TTT3 H1 TTT3 H1 TTTT4 H1 T1 HHH3 TT2 H1 T...
There were a total of 30 distinct runs in the simulation.
Their breakdown follows.
[run length] = # (as percentage of all runs)
[1] = 20 (66.7 %) (I need this to be 21 since the last value is "T").
[2] = 2 (6.7 %)
[3] = 4 (13.3 %)
[4] = 2 (6.7 %)
[5] = 1 (3.3 %)
...............
There are a few problems with your code. The ultimate reason why it's not working is that the final coin flip is not being counted.
The reason why your code is outputing There were a total of 30 distinct runs in the simulation. is because you start totalNumberOfRuns at the wrong value.
totalNumberOfRuns should start at 0 rather than 1.
Also notice how the end of the output for coin flips is T..., there should be a 1 following the T. You need to place that print statement at the end of the loop, otherwise it will only print the number from the previous iteration and simply not run at all for the final iteration.
Also, throughout your code you use magic numbers. E.g. if (i < 50), int[]runLength = new int[50]. Magic numbers are evil and you should never use them. An example of why magic numbers are evil: what if the user enters 100 when asked how many times the coin should be flipped? The code will not run properly in this case. Regardless even if you were not using a magic number here, these conditional statements are pointless because i will never be greater than 50 if you enter 50 for numberOfFlips.
I also am a bit bothered by the styling in your code. Please please please use curly braces even for blocks that are one line long. At the very least, at least be consistent with it. At some points you use curly braces for single-line if statements, but in one spot you don't use curly braces for a single-line else statement.
Also, your print statement where you output the frequencies is very messy. This is a perfect place to use System.out.printf, especially since you are already using String.format inside of the print method. The printf method is a beautiful thing and you should get comfortable with it. Here is what you should use:
System.out.printf("[%d] = %d (%1.1f%%)%n", i + 1, runLength[i], percentageFreq);
I got your code working, and I also cleaned it up a bit. Before you copy and paste this solution, I implore you to think about why my explanation above will fix your code, as well as what I did to clean up your code (e.g. rng should not be static)
Here you go :)
public class Main {
private static final Scanner stdIn = new Scanner(System.in);
public static void main(String[] args) {
int totalNumberOfRuns = 0;
int run = 1;
boolean theCoin, tempVal = false;
System.out.println("Welcome to the coin flip analyzer.\n"
+ "How many flips?");
int numberOfFlips = stdIn.nextInt();
System.out
.println("What do you want to seed the random number generator with?");
long rngSeed = stdIn.nextLong();
Random rng = new Random(rngSeed);
int[] runLength = new int[numberOfFlips];
for (int i = 0; i < numberOfFlips; i++) {
theCoin = rng.nextBoolean();
if (theCoin != tempVal) {
runLength[run - 1]++;
totalNumberOfRuns++;
run = 1;
} else {
run++;
}
if (theCoin) {
System.out.print("H");
tempVal = true;
} else {
System.out.print("T");
tempVal = false;
}
System.out.print(run + " ");
}
System.out.print("...");
System.out.println();
System.out
.println("There were a total of "
+ totalNumberOfRuns
+ " distinct runs in the simulation.\nTheir breakdown follows.");
// run length table header line
System.out.println("[run length] = # (as percentage of all runs)");
// your code to display the count and frequency percentage of each run
// length
// should follow
for (int i = 0; i < runLength.length; i++) {
double percentageFreq = ((double) +(runLength[i])
/ (totalNumberOfRuns) * 100);
if (runLength[i] > 0) {
System.out.printf("[%d] = %d (%1.1f%%)%n", i + 1, runLength[i],
percentageFreq);
}
}
}
}
So, I am working on this code for my AP Computer Science class, and I ran into a problem.
First, here is my code:
//loop counters
int counterOne = 0;
int counterElse = 0;
int loop = 1;
int iNum = 1000;
//create file
PrintWriter outFile = new PrintWriter(new File("newFile.txt"));
for (int counter = 1; counter <= iNum; counter++)
{
while (loop >= 1)
{
Random rand = new Random();
int iRand = rand.nextInt(5)+1;
if (iRand != 1)
{
counterElse++;
loop++;
}//end of if of if-else
else
{
counterOne++;
loop = 0;
}//end of else of if-else
}//end of while loop
int tries = counterElse+counterOne;
//int average = (tries + prevTriesSum) / counter
System.out.println("It took " + tries + " try/tries to win!");
//outFile.println("It tool an average of " + average + " tries to win.");
}//end of for loop
How do I calculate the average of the trials? As you can see from the end of my code, I commented out a line that I would want to calculate the average. This is because I don't know how to calculate prevTriesSum, which represents the sum of all of the other trials. Here is an example: Assume the loop runs six times, and with the first run, it takes 3 tries, 5 on the second run, 7 on the third, 11 on the fourth, 2 on the fifth, and 4 on the sixth (the most recent one. now tries = 4).
I would want prevTriesSum to equal 3 + 5 + 7 + 11 + 2 + 4.
How do I get the program to calculate that?
Your average is computed in integer arithmetic which means any fractional part is discarded. Consider using a floating point type for the average, and prefix the right hand side of the assignment with 1.0 * to force the calculation to occur in floating point.
You must not reinitialise the random generator in the loop, else you ruin its statistical properties. Do it once before you enter the loop.
Before the while loop, add
int prevTriesSum = 0;
Replace your commented int average = line with
prevTriesSum += tries;
And after the for loop add
double average = (prevTriesSum + 0.0) / counter;
outFile.println("It tool an average of " + average + " tries to win.");
As for the random number generator, Bathsheba is correct. You must move that above the for loop. Just move the declaration.
You'll also need to change your for loop slightly. As it stands, it will equal 1001 when the for loop terminates. Change it as follows:
for (int counter = 0; counter < iNum; counter++)
This will ensure that your average calculation is correct.
I am writing a program that reads a sequence of positive integers input by the user. User will only enter one integer at a time.Then it will compute the average of those integers. The program will end when user enters 0. (0 is not counted in the average).The program will print out the average once the program ends.
Question: My code stops working when I gets to the while loop hence it doesn't compute the input by user, hence prints out nothing. Why doesn't my while loop compute the average from the user's inputs? Appreciate your guidance :)
import java.util.Scanner;
public class AverageOfIntegers {
public static void main(String[] args) {
int integer;
double sum;
sum = 0;
double average;
Scanner input = new Scanner(System.in);
int count; count = 0;
average = 0;
System.out.println("Please enter an integer: ");
integer = input.nextInt();
while (integer != 0) {
count = count + 1;
sum = sum + integer;
average = sum / count;
}
System.out.println("Average = " + average);
}
}
This is because you are never actually summing over more than one integer. The user only ever enters one number. As a result your loop is essentially acting on just the one number. You need to put the input inside the while loop and save a running sum and count there. Something more like this
while (integer != 0) {
count += 1;
sum += integer;
average = sum / count;
integer = input.nextInt();
}
Explanation
First of all, when you define data types, you can set their default value in the definition. Ex:
double sum = 0;
vs
double sum;
sum = 0;
Secondly, sum = sum + integer; is the same as: sum += integer;
Thirdly, count = count + 1; is the same as: count += 1 OR (and better yet), count++;
As for your actual algorithm, there is one problem and one suggestion:
you are not changing integer's value after each loop. So, you can
either do that in the while condition: while ((integer =
input.nextInt()) != 0) { or, at the end of each loop:
while (integer != 0) {
count ++;
sum += integer;
average = sum / count;
integer = input.nextInt();
}
This is a suggestion for technically better code (in my opinion), but it looks better, is more intuitive and requires less calculations to calculate the average after the while loop is done instead of during. That way, you only calculate it once, where needed, vs. every loop, which is not needed.
________________________________________________________________________________
The Code (complete class)
public class AverageOfIntegers {
public static void main(String[] args) {
int integer;
double sum = 0;
double average = 0;
Scanner input = new Scanner(System.in);
int count = 0;
System.out.println("Please enter an integer: ");
// set integer = to the nextInt() while looping so it calculates properly
while ((integer = input.nextInt()) != 0) {
count ++;
sum += integer;
}
average = sum / count; // calculate the average after the while-loop
System.out.println("Average = " + average);
}
}
________________________________________________________________________________
Example input/output:
Please enter an integer:
5
10
15
0
Average = 10.0
So it did 5 + 10 + 15 = 30 (which is the sum), and then the average is 30 / 3 (30 is the sum, 3 is the count), and that gave you Average = 10.0.
You need to move integer = input.nextInt(); inside the loop, so your program will collect inputs in a loop. See the corrected version:
import java.util.Scanner;
public class AverageOfIntegers {
public static void main(String[] args) {
int integer = 0, count = 0;
double sum = 0.0, average = 0.0;
Scanner input = new Scanner(System.in);
System.out.println("Please enter an integer: ");
integer = input.nextInt();
while (integer != 0) {
count = count + 1;
sum = sum + integer;
System.out.println("Please enter an integer: ");
integer = input.nextInt();
}
average = sum / count;
System.out.println("Average = " + average);
}
}
The problem is that the input.nextInt() should be part of the loop. The way you wrote it, the code gooes into an infinite loop whenever the first input is non-zero. Instead, do:
while ((integer = input.nextInt()) != 0) {
count = count + 1;
sum = sum + integer;
average = sum / count;
}
In the loop:
while (integer != 0) {
count = count + 1;
sum = sum + integer;
average = sum / count;
}
This will only stops when integer is 0, but this variable is not changing in the loop, so it will never be 0 if it wasn't already in the first place.
According to what you said you want to do, you should probably repeat the call to integer = input.nextInt(); inside your loop, lke this:
System.out.println("Please enter an integer: ");
integer = input.nextInt();
while (integer != 0) {
count = count + 1;
sum = sum + integer;
System.out.println("Please enter an integer: ");
integer = input.nextInt();
}
average = sum / count;
Also, as others have said, you only need to compute the average once after the loop, so I moved it too.
Attached is the problem: http://puu.sh/42QtI/ea955e5bef.png
In terms of code, this is what I have so far
The question asks to "calculate the simulated percentage of three tails," which is the part I am stuck on. Could someone give me some insight on what to progress next?
public static boolean isThreeTails(){
Random rand = new Random();
int numberOfTosses = 3;
int numberOfHeads = 0;
int numberOfTails = 0;
for(int i = 1; i <= numberOfTosses; i++){
int value = rand.nextInt(2);
if(value == 0){
numberOfTails++;
}else{
numberOfHeads++;
}
}
if(numberOfTails == 3){
return true;
}
else{
return false;
}
}
double numTosses = 1000000; //choose whatever here
double threeTails = 0;
for(int i =0; i < numTosses; i++){
if(isThreeTails()){
threeTails++;
}
}
System.out.println("Theoretical probability of 3 Tails: " + (double) 1/8);
System.out.println("Actual results for " + numTosses + " tosses = " + threeTails/numTosses);
EDIT: Here, I am creating a counter for when there are triple tails. It would increment the numberOfTripleTails counter. If it rolls a "H", the numberOfTails would simply go back to zero. However, my code seems to only give '3' as an answer.
EDIT 2: Done!
Alright - you've run your simulation and you have your value for number of heads and number of tails. Now you'll need to run a few more.
Each time you run a simulation, increment a variable that tracks the total amount of times you've run it. If number of tails comes out to three, you increment another variable: let's call it successes.
The outcome to the problem are the successes over the total times the simulation was run.
The method that you have already written simulates three tosses. I've modified that method so that it is now a callable function isThreeTails()
public static boolean isThreeTails(){
Random rand = new Random();
int numberOfTosses = 3;
int numberOfHeads = 0;
int numberOfTails = 0;
for(int i = 1; i <= numberOfTosses; i++){
int value = rand.nextInt(2);
if(value == 0){
numberOfTails++;
}else{
numberOfHeads++;
}
}
if(numberOfTails == 3){
return true;
}
else{
return false;
}
}
Now you will want to call this method from the main method of ThreeTosses.java
double numTosses = 100; //choose whatever here
double threeTails = 0;
for(int i =0; i < numTosses; i++){
if(isThreeTails()){
threeTails++;
}
}
System.out.println("Theoretical probability of 3 Tails: " + (double) 1/8);
System.out.println("Actual results for " + numTosses + " tosses = " + threeTails/numTosses);
The question is saying, "in theory, you should get 3 tails 1/8th of the time". Now it's saying, "OK, you know the theory, now actually do this on a computer and see what you really get."
What you want to do is run this code a bunch of times and keep track of the number of times you got 3 tails. Take that number and divide it by the total number of times you ran the code. That should be the simulated percentage.
Just in case you can't tell, I'm saying to do this in code, not by manually running your current code over and over again. Here's some pseudo code:
threeTailsCount = 0
for i = 0; i < 1000; i++
if currentCodeReturns3Tails
threeTailsCount += 1;
print (threeTailsCount / 1000)