I am very beginner on Java, still getting passion about.
I have been given this exercise: "Write a simulator program that flips a coin: One thousand times then prints out how many time you get tails and how many times you get heads"
That is what i have tried to do so far.
import java.util.Random;
import java.util.regex.Pattern;
public class coin {
public static void main( String [] args ) {
Random r = new Random();
Pattern tail = Pattern.compile("Tail+");
Pattern head = Pattern.compile("Head+");
String flips = "";
for (int i = 0; i < 1000; i++) {
flips += r.nextInt(100) % 2 == 0 ? "Head" : "Tail";
}
String[] heads = head.split( flips );
String[] tails = tail.split( flips );
//Display
System.out.println("Times head was flipped:" + heads.length);
System.out.println("Times tail was flipped:" + tails.length);
}
}
The program seems to be working, but it is giving me always an almost pair amount of heads and tails, which the total exceed 1000, at least by 1 or more.
Please, someone has any solution of this? Where am I wrong?
Thanks
Rather than appending the result in a String and then splitting the string and counting the occurence of "Head"/"Tail" you can just keep track of the count in separate variables :
int headCount = 0;
int tailCount = 0;
for (int i = 0; i < 1000; i++) {
if(r.nextInt(100) %2 == 0)
{
headCount++;
}
else
{
tailCount ++;
}
System.out.println("Times head was flipped:" + headsCount);
System.out.println("Times tail was flipped:" + tailCount);
}
A coin has two sides, so I really don't see why you would ask the random generator to generate a number between 0 and 100 (exclusive). Between 0 and 2 (exclusive) would be much more logical.
Also, you're being asked to count. Appending strings and then splitting to get the final value is quite a complex and inefficient way to count. You should use an integer instead. Each time you get a 1 from your random, increment a counter. In the end, you have the number of times 1 was returned, and the number of 0 is thus 1000 - this number.
Random r = new Random();
int heads = 0;
for (int i = 0; i < 1000; i++) {
int side = random.nextInt(2);
if (side == 1) {
heads++;
}
}
System.out.println("Times head was flipped:" + heads);
System.out.println("Times tail was flipped:" + (1000 - heads));
It could even be simplified to the follwoing (although this simplification makes the code a bit harder to understand):
Random r = new Random();
int heads = 0;
for (int i = 0; i < 1000; i++) {
heads += random.nextInt(2);
}
System.out.println("Times head was flipped:" + heads);
System.out.println("Times tail was flipped:" + (1000 - heads));
I had similar question for my assessment and I tried below code and it worked. May be its not appropriate way of doing.
I am happy to receive feedback! thanks.
for (int i = 1; i < 1000; i++) {
flips += r.nextInt(100) % 2 == 1 ? "Head" : "Tail";
}
Related
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);
}
}
}
}
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'm having a problem with average distance in this exercise. It should be close to the sqrt of N steps, but it's lower. Can you help me to find out where is my mistake?
2D random walk.
A two dimensional random walk simulates the behavior of a particle moving in a grid of points.
At each step, the random walker moves north, south, east, or west with probability 1/4,
independently of previous moves. Determine how far away (on average) the random walker is from the starting point after N steps.
(Theoretical answer: on the order of sqrt(N).)
public class RandomWalk{
public static void main(String[] args){
int N = Integer.parseInt(args[0]);
double nextStep = 0;
double averageDistance = 0;
int COUNT = 1000;
for (int j = 0; j < COUNT; j++){
int moveWest = 0;
int moveEast = 0;
int moveSouth = 0;
int moveNorth = 0;
double distance = 0;
for (int i = 0; i < N; i++){
nextStep = Math.random()*4;
if (nextStep <= 1) ++moveWest;
else if (nextStep <= 2) ++moveEast;
else if (nextStep <= 3) ++moveSouth;
else if (nextStep <= 4)++moveNorth;
}
moveEast = moveEast - moveWest;
moveNorth = moveNorth - moveSouth;
distance = Math.sqrt((moveEast * moveEast) + (moveNorth * moveNorth));
averageDistance += distance;
System.out.println("Walker is " + distance + "\t steps away of from the starting point");
//System.out.println("Sqrt of N is " + Math.sqrt(N));
}
System.out.println("Average distance is " + averageDistance/COUNT + " steps away of from the starting point");
}
}
I ran a few tests on your code with aforementioned change of ranges <0,1),<1,2),<2,3), <3,4) making them even.
And you do it like that:
if (nextStep < 1) ++moveWest;
else if (nextStep < 2) ++moveEast;
else if (nextStep < 3) ++moveSouth;
else if (nextStep < 4)++moveNorth;
Notice <= becoming <.
100000 trials of 100 steps each gave those resutls:
Average distance is 8.873435509749317 steps away of from the starting point
W=2498906
E=2501447
N=2500022
S=2499625
,
where W,E,N,S are summed steps for given direction during all the trials.
They look fine.
Running such a test case for a couple of times reveals that there is no preferable direction. You might use other methods to get random numbers, but that would be testing generators, not your case. Your code looks ok from my point of view.
Sentence from the problem statement also gives you a clue:Theoretical answer: on the order of sqrt(N).
I think this line won't work :
nextStep = Math.random()*4;
the explanation is a logical one. I think it would be better to use Integers for your purpose because you want to calculate with steps, wich is a static unit. Well thats opinion based, but I recommend to count the full number of steps instead of tracking partial steps.
try this instead:
Random rand = new Random();
nextStep = rand.nextInt(4)+1; //random numbers {1,2,3,4}
Furthermore since nextInt() generates random Integer values you need to use the == operator instead of <= in your if/else statements.
if (nextStep == 1) ++moveWest;
else if (nextStep == 2) ++moveEast;
else if (nextStep == 3) ++moveSouth;
else if (nextStep == 4)++moveNorth;
regards to Tom (not me, the one in the comments!)
Task : Unfair die(6 sides) is being rolled n times. Probability of 1 is p1, probability of 2 is p2 and so on. Write a computer program, that for given n (n<100), the probability of set (p1,p2,p3,p4,p5,p6) and $x \in [n,600n]$ would find the probability of sum of dice values is less than x. Program cannot work more than 5 minutes. This is an extra question that will give me extra points, but so far nobody has done it. I quess beginner computer scientist like me can learn from this code also, since i found 0 help with bias dice in the web and came up with roulette like solution. I kind of wanted to show the world my way also.
I have 2 solutions - using geometrical and statistical probability.
My question is: 1) Is it correct when i do it like this or am i going wrong somewhere ?
2) Which one you think gives me better answer geometric or statistical probability ?
My intuition says it is geometric, because it is more reliable.
i think it is correct answer that my code is giving me - more than 0.99..... usually.
I wanted somebody to check my work since i'm not sure at all and i wanted to share this code with others.
I prefer Java more since it is much faster than R with loops, but i gave R code also for statistical , they are very similar i hope it is not a problam.
Java code :
import java.util.ArrayList;
public class Statistical_prob_lisayl2_geometrical {
public static double mean(ArrayList<Double> a) {
double sum=0;
int len = a.size();
for (int i = 0; i < len; i++) {
sum = sum + a.get(i);
}
return (sum/len);
}
public static double geom_prob(double p1,double p2,double p3,double p4,double p5,double p6){
ArrayList<Double> prob_values = new ArrayList<Double>();
int repeatcount = 1000000;
int[] options = {1,2,3,4,5,6};
int n = 50;
double[] probabilities = {p1,p2,p3,p4,p5,p6};
for (int i = 0 ; i < repeatcount ; i++ ) { // a lot of repeats for better statistical probability
int sum = 0; //for each repeat, the sum is being computed
for (int j = 0; j < n ; j++ ) { // for each repeat there is n cast of dies and we compute them here
double probability_value=0; // the value we start looking from with probability
double instant_probability = Math.random(); // we generate random probability for dice value
for (int k = 0; k < 6; k++ ) { // because we have 6 sides, we start looking at each probability like a roulette table
probability_value = probability_value + probabilities[k]; // we sum the probabilities for checking in which section the probability belongs to
if (probability_value>instant_probability) {
sum = sum + options[k]; // if probability belongs to certain area , lets say p3 to p4, then p3 is added to sum
break; // we break the loop , because it would give us false values otherwise
}
}
}
double length1 = (600*n)-n-(sum-n); //length of possible x values minus length of sum
double length2 = 600*n-n;
prob_values.add( (length1/length2) ); // geometric probability l1/l2
}
return mean(prob_values); // we give the mean value of a arraylist, with 1000000 numbers in it
}
public static double stat_prob(double p1,double p2,double p3,double p4,double p5,double p6){
ArrayList<Double> prob_values = new ArrayList<Double>();
int repeatcount = 1000000;
int[] options = {1,2,3,4,5,6};
int n = 50;
double[] probabilities = {p1,p2,p3,p4,p5,p6};
int count = 0;
for (int i = 0 ; i < repeatcount ; i++ ) {
int sum = 0;
for (int j = 0; j < n ; j++ ) {
double probability_value=0;
double instant_probability = Math.random();
for (int k = 0; k < 6; k++ ) {
probability_value = probability_value + probabilities[k];
if (probability_value>instant_probability) {
sum = sum + options[k];
break;
}
}
}
int x = (int)Math.round(Math.random()*(600*n-n)+n);
if( x>sum ) {
count = count + 1;
}
}
double probability = (double)count/(double)repeatcount;
return probability;
}
public static void main(String[] args) {
System.out.println(stat_prob(0.1,0.1,0.1,0.1,0.3,0.3));
System.out.println(geom_prob(0.1,0.1,0.1,0.1,0.3,0.3));
}
}
R code:
repeatcount = 100000
options = c(1,2,3,4,5,6)
n = 50
probabilities = c(1/10,1/10,1/10,1/10,3/10,3/10)
count = 0
for (i in 1:repeatcount) {
sum = 0
for (i in 1:n) {
probability_value=0
instant_probability = runif(1,0,1)
for (k in 1:6){
probability_value = probability_value + probabilities[k]
if (probability_value>instant_probability) {
sum = sum + options[k]
break
}
}
}
x = runif(1,n,600*n)
x
sum
if ( x> sum ) {
count = count + 1
}
}
count
probability = count/repeatcount
probability
Is this what you are trying to do??
n <- 50 # number of rolls in a trial
k <- 100000 # number if trials in the simulation
x <- 220 # cutoff for calculating P(X<x)
p <- c(1/10,1/10,1/10,1/10,3/10,3/10) # distribution of p-side
X <- sapply(1:k,function(i)sum(sample(1:6,n,replace=T,prob=p)))
P <- sum(X<x)/length(X) # probability that X < x
par(mfrow=c(1,2))
hist(X)
plot(quantile(X,probs=seq(0,1,.01)),seq(0,1,.01),type="l",xlab="x",ylab="P(X < x)")
lines(c(x,x,0),c(0,P,P),col="red",lty=2)
This makes sense because the expected side
E(s) = 1*0.1 + 2*0.1 + 3*0.1 + 4*0.1 + 5*0.3 + 6*0.3 = 4.3
Since you are simulating 50 rolls, the expected value of the total should be 50*4.3, or about 215, which is almost exactly what it is.
The slow step, below, runs in about 3.5s on my system. Obviously the actual time will depend on the number of trials in the simulation, and the speed of your computer, but 5 min is absurd...
system.time(X <- sapply(1:k,function(i)sum(sample(1:6,n,replace=T,prob=p))))
# user system elapsed
# 3.20 0.00 3.24
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)