Nothing will print when run. Where's the error?
In this project you will simulate two games. In the first game, roll one die four times and record a "win" if a six is rolled at least once during the four rolls, otherwise record a "loss". In the second game, roll two die twenty-four times and record a "win" if two six's are rolled at least once during the twenty-four rolls, otherwise record a "loss". Your program should simulate running each game a million times and output the number of wins and losses for each game.
import java.util.Random;
public class Driver {
public static void main(String[] args) {
int win6 = 0;
int lose6 = 0;
int win24 = 0;
int lose24 = 0;
int n = 100000000;
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= 4; j++){
Random r = new Random();
int next = r.nextInt(1-6);
if (next == 6){
win6 = win6 + 1;
break;
}
}
lose6 = 100000000 - win6;
for (int u = 0; u <= 24; u++){
Random r = new Random();
Random t = new Random();
int next1 = r.nextInt(1-6);
int next2 = t.nextInt(1-6);
if (next1 == 6 && next2 == 6){
win24 = win24 + 1;
break;
}
}
lose24 = 100000000 - win24;
}
System.out.println(win6);
System.out.println(lose6);
System.out.println(win24);
System.out.println(lose24);
}
}
Related
The program I wrote simulates rolling dice and attempts to calculate the probability of rolling a six in 4 rolls. The issue I'm having is it always calculates 0.66 when it should be around 0.50 and I can't figure out why.
public class Die {
int outcome;
void roll() {
double x = Math.random();
x = 1.0 + (x * 6.0);
outcome = (int) Math.floor(x);
}
}
public class Application {
public static void main(String[] args) {
float sixesIn4 = 0F;
int sixesIn24 = 0;
double sixIn4Probability;
for (int k = 0; k < rolls; k++) {
for (int i = 0; i < 4; i++) {
die.roll();
if (die.outcome == 6) {
sixesIn4++;
}
}
}
sixIn4Probability = sixesIn4 / rolls;
System.out.println(sixIn4Probability);
}
}
Can anyone help me?
The probability of rolling at least one six in four rolls is 1-(5/6)**4, which is just over 0.5.
You are calculating the expected number of sixes from 4 rolls, which is 4*(1/6), 0.67.
You just need to increment your count once for each group of 4 rolls. The smallest change, without rewriting your whole code, is to add a break statement in your inner loop:
for (int i = 0; i < 4; i++) {
die.roll();
if (die.outcome == 6) {
sixesIn4++;
break;
}
}
That way you only count each group of 4 once, if it has a six in it, instead of counting the number of sixes you get from it.
There are a couple of problems in your code. Firstly, you are generating floating point random numbers and then converting to ints. Better to just generate ints. Secondly you are counting all 6s rolled, not just the sequence of rolls that result in at least 1 six.
Split out your 'at least 1 six' into a separate method:
private boolean atLeastOneSix() {
for (int i = 0; i < 4; i++) {
if (random.nextInt(6) + 1 == 6)
return true;
}
return false;
}
Then your counting becomes more obvious:
int sixCount = 0;
for (int t = 0; t < trials; t++) {
if (atLeastOneSix())
sixCount++;
}
double prob = 1.0 * sixCount / trials;
If you are comfortable with streams:
IntStream.range(4).map(i -> random.nextInt(6) + 1).anyMatch(r -> r == 6);
And
long sixCount = IntStream.range(trials).filter(i -> atLeastOneSix()).count();
You want to keep track of a boolean in each roll to determine if there are one or more sixes. My sample gives 0.526, which given your comments should be (close to) correct.
class Die {
int outcome;
void roll() {
double x = Math.random();
x = 1.0 + (x * 6.0);
outcome = (int)Math.floor(x);
}
}
public class Application {
public static void main(String[] args) {
int rolls = 1000;
Die die = new Die();
float sixesIn4 = 0F;
double sixIn4Probability;
boolean sixinRol;
for (int k = 0; k < rolls; k++) {
sixinRol = false;
for (int i = 0; i < 4; i++) {
die.roll();
if (die.outcome == 6) {
sixinRol = true;
}
}
if (sixinRol) sixesIn4 += 1;
}
sixIn4Probability = sixesIn4 / rolls;
System.out.println(sixIn4Probability);
}
}
For an assignment I am doing for one of my classes, we have to implement a Sieve of Eratosthenes. I have tried seven times to get a code that works and have tried incorporating numerous solutions I've researched. I finally have one that will output numbers. Unfortunately, it prints both composite and prime numbers, and doesn't print 2.
My code is as follows:
public class EratosthenesSieveAttempt6 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
int limit;
System.out.print("Please enter the highest number to check "
+ "(number must be greater than 2): ");
limit = keyboard.nextInt();
while (limit <= 2){
System.out.println("Error - number must be greater than 2.");
System.out.println("Please enter the highest number to check: ");
limit = keyboard.nextInt();
}
boolean[] numbers = new boolean[limit + 1];
int newPrime = 2;
for(int i = 0; i < limit + 1; i++){
numbers[i] = true;
}
for(int j = 1; j < limit + 1; j++) {
if (j % 2 == 0) {
numbers[j] = false;
}
for(int k = j + 1; k < limit + 1; k++) {
if(numbers[k] == true){
j = k;
System.out.println(k);
}
}
}
}
}
I'm suspecting that there is a problem with my loops. I fixed the i and j variables for my first two loops so that it would print out from 2 onward, the problem seems to be that it's not marking the composite numbers as false after I've initialized the array to true.
Thank you in advance for your help.
Here's an implementation of the Sieve of Eratosthenes I wrote the other day:
import java.util.BitSet;
public static BitSet composite(int max) {
BitSet composite = new BitSet(max);
max = composite.size();
for (int i = 4; i < max; i += 2) composite.set(i, true);
for (int i = 9; i < max; i += 6) composite.set(i, true);
int p = 5;
while (p*p < max) {
if (!composite.get(p)) {
for (int i = p*p; i < max; i += p*2) composite.set(i, true);
}
p += 2;
if (p*p >= max) break;
if (!composite.get(p)) {
for (int i = p*p; i < max; i += p*2) composite.set(i, true);
}
p += 4;
}
return composite;
}
Notes:
BitSet allocates 64-bit words, so the size may be larger than you requested (for example, if you ask it to go up to 1000, it will go up to 1024; that's the reason for max = composite.size() near the top)
Gets the 2's, 3's out of the way explicitly, and then
Relies on the fact that all primes larger than 3 are congruent to either 1 or 5 mod 6; this is the reason the final loop alternates between adding 2 and 4
It returns a BitSet that tells you which numbers are composite. One way to extract just the primes from it would be:
public static int[] primes(BitSet composite) {
int size = composite.size() - 2 - composite.cardinality();
int[] primes = new int[size];
int index = 0;
for (int i = 2; i < composite.size(); i++) {
if (!composite.get(i)) primes[index++] = i;
}
return primes;
}
import java.util.Random;
public class RollingDice {
public static void main(String[] args){
int numSides = 6;
Random ranGen = new Random();
for (int i =1; i <= 20; i++){
if (ranGen.nextInt(numSides) == 3) {
System.out.println("A 3 has been rolled!");
}
}}}
this is my code so far. It prints the message every time the number 3 is rolled. I am new to coding, so please bear with me. What i want to do next is store the numbers of times 3 is rolled so when the loop exits, it displays the final count of the number of times 3 was actually rolled in that process. That making the end result be some number which represents the number of times the number 3 was rolled by the system.
Thanks!
-Sail
Define a count.
int count = 0;
Increase count each time you encounter a roll of 3. Inside of the loop, if you roll a 3:
count = count + 1;
Print count outside of the loop.
System.out.printf("A 3 was been rolled %d times.\n", count);
Random ranGen = new Random();
int numberOfThrees = 0;
for (int i =1; i <= 20; i++){
if (ranGen.nextInt(numSides) == 3) {
++numberOfThrees;
}
}
System.out.println(numberOfThrees);
Like this:
import java.util.Random;
public class RollingDice {
public static void main(String[] args){
int numSides = 6;
int threes = 0;
Random ranGen = new Random();
for (int i =1; i <= 20; i++) {
if (ranGen.nextInt(numSides) == 3) {
System.out.println("A 3 has been rolled!");
threes++
}
}
System.out.println("A 3 has been rolled " + threes + " times!");
}}
Actually, what you are recording is the number of 4's that have been rolled, since nextInt returns a number between 0 and 5.
You could simply have a counter
import java.util.Random;
public class RollingDice {
public static void main(String[] args){
int numSides = 6;
int cnt = 0; // <-- Declare a counter
Random ranGen = new Random();
for (int i =1; i <= 20; i++){
if (ranGen.nextInt(numSides) == 3) {
System.out.println("A 3 has been rolled!");
cnt++; // <-- increment counter
}
}
System.out.printf("A 3 has been rolled %d times!\n", cnt);
}
I am attempting to write a program in java that flips an imaginary coin and outputs the flips and then when a certain side has been flipped 3 times, it stops and tells you the number of times it flipped. My program doesn't seem to be working
My code is below:
import java.util.*;
public class FlipperThree {
public static void main(String[] args) {
boolean fin = false;
while(!fin){
System.out.println("Welcome to Flipper!");
int h = 0;
int hcount = 0;
int tcount = 0;
int ocount = 0;
String random;
String[] ht;
boolean done = false;
while(!done){
for(hcount<3||tcount<3){ht = new String[] {"Heads","Tails"};
Random r =new Random();
random = ht[r.nextInt(ht.length)];
System.out.println(random);
}
if (hcount!=3||tcount!=3){
if(random == ht[h]){
hcount++;
ocount++;
tcount = 0;
}else{
hcount = 0;
tcount++;
ocount++;
}
}else{
System.out.println("BINGO!That only took " + ocount+" flips to get 3 in a row!");
done = true;
}
}
}fin = true;
}
}
In general your program is much more complicated than necessary. You only need a single loop
You were using == to compare strings. Instead of random == ht[h] you should say random.equals(ht[h])
Instead of looping while either heads or tail counts are less than 3, you only want to keep looping while both are less than three. So instead of hcount!=3 || tcount!=3 it's hcount!=3 && tcount!=3
.
public class FlipperThree {
public static void main(String[] args) {
System.out.println("Welcome to Flipper!");
int h = 0;
int hcount = 0;
int tcount = 0;
int ocount = 0;
String[] ht = new String[] {"Heads","Tails"};
Random r =new Random();
while (hcount < 3 && tcount < 3) {
String random = ht[r.nextInt(ht.length)];
System.out.println(random);
if(random.equals(ht[h])){
hcount++;
ocount++;
tcount = 0;
}
else{
hcount = 0;
tcount++;
ocount++;
}
}
System.out.println("BINGO!That only took " + ocount+" flips to get 3 in a row!");
}
}
$ java FlipperThree
Welcome to Flipper!
Tails
Heads
Heads
Tails
Heads
Heads
Tails
Tails
Tails
BINGO!That only took 9 flips to get 3 in a row!
Remove the for and init ht once and remove your first while too and change || to &&:
import java.util.*;
public class FlipperThree {
public static void main(String[] args) {
System.out.println("Welcome to Flipper!");
int h = 0;
int hcount = 0;
int tcount = 0;
int ocount = 0;
String random;
String[] ht = new String[] {"Heads","Tails"};
boolean done = false;
while(!done){
Random r =new Random();
random = ht[r.nextInt(ht.length)];
System.out.println(random);
if (hcount!=3 && tcount!=3){
ocount++;
if(random == ht[h]){
hcount++;
tcount = 0;
}else{
hcount = 0;
tcount++;
}
}else{
System.out.println("BINGO!That only took " + ocount+" flips to get 3 in a row!");
done = true;
}
}
}
You can achieve this with much simpler code when you realize that you just need to keep track of the number of consecutive coin faces. It doesn't matter what face it is:
/**
* return:
* the number of coin tosses until you get the same face n consecutive times
*/
static int numTossesUntilNConsecutiveFaces(int n) {
Random toss = new Random();
// This counts the number of consecutive faces following a given face
// For example:
// for sequence 1 0, numConsecutive == 0
// for sequence 1 1, numConsecutive == 1
// for sequence 0 0 0, numConsecutive == 2
int numConsecutives = 0;
int numTosses = 0;
// Initialize the lastCoin value as -1, so the first coin won't be equal to it
int lastCoin = -1;
do {
// The result of the toss will be 0 or 1 (head or tails)
int coin = toss.nextInt(2);
if (coin == lastCoin) {
// If the current coin is the same as the last coin, increment the counter
numConsecutives++;
} else {
// If it is different, reset the counter
numConsecutives = 0;
}
// Make this coin the last coin
lastCoin = coin;
numTosses++;
// Stop when the number of consecutives is n - 1.
// For n == 3, that is when the last three numbers were 1 1 1 or 0 0 0
} while (numConsecutives < n - 1);
return numTosses;
}
Then you just need to call:
int tosses = numTossesUntilNConsecutiveFaces(3);
public class FlipperThree {
public static void main(String[] args) {
System.out.println("Welcome to Flipper!");
int previousFlip = -1;
int continuousFlip = 0;
int totalFlips = 0;
String[] ht = new String[] {"Heads","Tails"};
Random r = new Random();
while (continuousFlip < 3) {
int r = r.nextInt(ht.length);
totalFlips++;
System.out.println(ht[r]);
if(previousFlip == r){
continuousFlip++
} else {
continuousFlip = 1;
previousFlip = r;
}
}
System.out.println("BINGO!That only took " + totalFlips +" flips to get 3 in a row!");
}
}
Just wanted to show a shorter version. Whole point is that you don't need to keep track of BOTH the heads or tails, you just need to keep track of how much you've flipped the same number consequtively. Very minor optimization concerning real world performance, but still an improvement :)
I tried to create a simple lottery program. Here is a problem: it still prints same numbers. For example I got 33 21 8 29 21 10 as output. Everytime when random number is generated, code checks if that number is already generated, then it creates a new random number but after that it doesn't check again. I couldn't find a way to do that.
public static void main(String[] args)
{
int[] lottery = new int[6];
int randomNum;
for (int i = 0; i < 6; i++)
{
randomNum = (int) (Math.random() * 50); //Random number created here.
for (int x = 0; x < i; x++)
{
if (lottery[i] == randomNum) // Here, code checks if same random number generated before.
{
randomNum = (int) (Math.random() * 50);//If random number is same, another number generated.
}
}
lottery[i] = randomNum;
}
for (int i = 0; i < lottery.length; i++)
System.out.print(lottery[i] + " ");
}
There are 2 problems with your code:
you check if lottery[i] and randomNum are the same, it should be lottery[x]
when you re-generate a random number, you don't check it against the first numbers in lottery.
Here is a corrected version:
public static void main(String[] args) {
int[] lottery = new int[6];
int randomNum;
for (int i = 0; i < 6; i++) {
randomNum = (int) (Math.random() * 50); // Random number created here.
for (int x = 0; x < i; x++) {
if (lottery[x] == randomNum) // Here, code checks if same random number generated before.
{
randomNum = (int) (Math.random() * 50);// If random number is same, another number generated.
x = -1; // restart the loop
}
}
lottery[i] = randomNum;
}
for (int i = 0; i < lottery.length; i++)
System.out.print(lottery[i] + " ");
}
You are changing the random number while you are checking it. You need to pick one random number and check whether it is present or not.
BTW A shorter approach is to use a shuffle.
// give me all the number 1 to 50
List<Integer> list = IntStream.range(1, 51).boxed().collect(Collectors.toList());
// shuffle them.
Collections.shuffle(list);
// give me the first 6
System.out.println(list.subList(0, 6));
A simple solution, between the first (who could be very abstract for a not Java programmer) and the 2nd (not assuring the unicity of the number list).
Collection<Integer> liste = new ArrayList<Integer>();
for (int i = 0; i < 6; i++)
{
Boolean ap = false;
while (!ap)
{
Integer randomNumber = (int) (Math.random() * 50);
if (! liste.contains(randomNumber)){
liste.add(randomNumber);
ap = true;
}
}
}
for (Integer liste1 : liste) {
System.out.print(liste1+" ");
}
try this one, it creates 12 x (6 out of 45)
public static void main(String[] args) {
SecureRandom random = new SecureRandom();
for (int i = 0; i < 12; i++){
Integer[] tipp = new Integer[6];
int n = 0;
do {
int r = random.nextInt(45) + 1;
if (Arrays.asList(tipp).indexOf(r)<0){
tipp[n]= r;
n++;
}
} while (n<=5);
Arrays.sort(tipp);
System.out.println(Arrays.toString(tipp));
}
}
public static void main(String[] arg) {
int[] lottery = new int[6];
int randomNum;
c1:
for (int i = 0; i < 6; i++) {
randomNum = (int) (Math.random() * 50); // Random number created here.
if(randomNum == 0) {
continue c1;
}
for (int x = 0; x < i; x++) {
if (lottery[x] == randomNum ) // Here, code checks if same random number generated before.
{
randomNum = (int) (Math.random() * 50);// If random number is same, another number generated.
x = -1; // restart the loop
}
}
lottery[i] = randomNum;
}
for (int i = 0; i < lottery.length; i++)
System.out.print(lottery[i] + " ");
}
This is the object class for making a ticket, it will create ONE ticket with ascending values at which whatever parameters you choose. This program won't run until you have a main method that you call. Make sure to import TreeSet.
import java.util.TreeSet;
public class TicketMaker{
private int numbersPerTicket;
private int lowestNumber;
private int highestNumber;
TicketMaker(){
numbersPerTicket=0;
lowestNumber=0;
highestNumber=0;
}
TicketMaker(int numbersPerTicket,int lowestNumber,int highestNumber){
if(numbersPerTicket > 0 && lowestNumber >= 0 && highestNumber >= lowestNumber){
this.numbersPerTicket=numbersPerTicket;
this.lowestNumber=lowestNumber;
this.highestNumber=highestNumber;
}
}
public boolean printTicket(int numbersPerTicket,int lowestNumber,int highestNumber){
if(numbersPerTicket > 0 && lowestNumber >= 0 && highestNumber >= lowestNumber){
if(numbersPerTicket > highestNumber){
System.out.println("Error not in-bounds");
return false;
}
int rand;
int count=0;
System.out.println("[Ticket Printed]");
TreeSet<Integer> set = new TreeSet<>();
do{
rand = (int)(Math.random()*highestNumber)+lowestNumber;
set.add(rand);
count++;
}while(set.size() != numbersPerTicket);
System.out.println(set);
return true;
}
else{
System.out.println("Error not in-bounds");
return false;
}
}
public boolean isValidTicketData(int numbers,int lowest,int highest){
if(lowest != 1){
if(highest == numbers)
return false;
}
if(numbers <= highest){
if(numbers > 0 && lowest >= 0 && highest >= lowest)
return true;
}
return false;
}
}