Why is my basic rumor simulation program not working? [closed] - java

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 3 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
My assignment
I have been tasked with attempting to code this program in Java. I've coded a program I think should work, but no matter what I input as the argument it says everyone has heard the rumor in every situation. I think it has something to do with skipping my while loops and me miswriting something else later on...? I'm completely lost, and because my attempts to troubleshoot what is being executed and what isn't have been failing I don't really know how to fix it. My attempt at coding the problem is below. I've tried to put in a lot of notes to help anyone trying to help me follow along, though I'm not sure if I have out everything down in the right etiquette; sorry if I messed up!
public class ProgrammingProblem1 {
public static void main(String[] args) {
int people = Integer.parseInt(args[0]) ;
//Obtains how many people not including Alice are at the party
boolean[] guests;
double averageheard = 0.0;
// This double will be used at the end to determine on average how many people heard the rumor.
double totalheard = 0.0;
// This double is used to help calculate how many people heard the rumor over all the iterations. Keeps track of the total people who knew the rumor throughout the permutations.
double percentsuccess = 0.0;
// This double will be used at the end to determine the percent of how many times the rumor was heard by everyone against how many loops there were.
double rumorsuccess = 0;
// This keeps track of how many times the rumor went all the way around.
double rumorfail = 0;
// This keeps track of how many time the rumor did not make it all the way around.
guests = new boolean[people];
//Fills the array with as many slots as there are people at the party. Guests is the array that stores if someone has heard the rumor or not.
int runtime = Integer.parseInt(args[1]);
// Guests is to figure out how many guests besides Alice are at the party and set them in an array, and Runtime is to figure out how many simulations you are meant to run.
if (people < 1 || runtime < 0){
//This is to check if the arguments were entered correctly.
System.out.println("You entered the arguments incorrectly. The amount of people at the party besides Alice must be at least two and the simulation must be run at least once.");
}else {
for ( int i = 0; i < runtime ; i++) {
// This is for doing however many iterations through are desired.
int heard = 0;
// This variable will be used at the end to determine if everyone has heard the rumor.
int current = 0 ;
// This ensures that we start with our first person ,"Bob", as the progintor of the rumor. Current is whoever is currently telling the rumor to someone else.
for (int l = 0; l < people; l++){
guests[l] = false; }
guests[0] = true ;
// This ensures that Bob already knows the rumor.
int next = (int)(Math.random() * people) ;
// This randomly selects the first person Bob asks about it. Next is the person we are telling the rumor to
while (current == next) {
// This makes sure that the guest we are doing isn't talking to themselves
next = (int)(Math.random() * people );
}
while ( !guests[next] ) {
// This makes the loop go on until the canidate the person it would tell has already heard it
guests[next] = true;
// This line makes whoever was just told the rumor now knows the rumor
int last = current;
// This keeps track of who the last person who said the rumor was
current = next;
// This is making the person we just told the rumor to our new rumor teller.
next = (int)(Math.random() * people);
// This finds a new person to be told the rumor
while (current == next || last == next ){
// This ensures that the person we tell the rumor to next will not be the person telling the rumor to or the person who told them the rumor.
next = (int)(Math.random() * people); }
}
for ( int j = 0; j < people; ++j) {
// This is to determine how many people heard the rumor before it was terminated.
if ( guests[j] == true){
heard = heard + 1;
}
}
if ( heard == people){
//This if statement will add a counter to rumorsuccess if every person was told the rumor, and to rumorfail if everyone didn't hear it.
rumorsuccess = rumorsuccess + 1;
}
else{
rumorfail = rumorfail + 1; }
totalheard = totalheard + heard;
//This is to tally up how many people heard the rumor in total.
}
percentsuccess = (rumorsuccess / (rumorsuccess + rumorfail)) * 100 ;
// This calculates the percent of times the rumor went all the way around to everyone
averageheard = (totalheard / runtime) ;
// This calculates the average amount of times the rumor made its way around
System.out.println("Steven Mikels 20782");
System.out.println("The amount of people in the room besides Alice are: " + people + ". The amount of times the simulation was run is: " + runtime);
System.out.println("The rumor was heard by everyone in the room " + percentsuccess + " percent of the time. The average amount of people who heard the rumor was: " + averageheard);
}
}
}
EDIT 1: I have updated the code to accommodate my updating of the == related error. I have a few new issues now that the code calculates how many people heard on average correctly, though the percentage of times everyone has succeeded doesn't seem to be working. Entering "3" and then any other number into the command line correctly gives 100% of times gone through everyone hears it. Unfortunately, entering any number of people greater than 3 means the code have 0% chance to go all the way around, which is false. Additionally, entering "2" as the first number seems to make the program stall out command prompt. After some testing, it seems the variable rumorfail and rumorsuccess are always equal to each other.
EDIT 2: I'm fairly certain that I've managed to fix my problem; the variables rumorfail and rumorsuccess needed to be a double! It was rounding the number up or down, resulting in the 0% or 100% marks. Unfortunately, I'm still have an issue where my program won't allow two to be the amount of people or else it freaks out. I'm testing for more reasons on why that may be right now, but didn't want people working on the other issue since it is already solved! Strangely, 0 executes the statement correctly and prints that an invalid number has been inputted, but 1 shares the same problem that 2 did.

Off the bat i see a couple typos:
Youre while statement
while ( guests[next] = false ) { is missing a "="
it should be written like this guests[next] == false or !guests[next]
you also did the same thing in this if statement if ( guests[j] = true){
it should be guests[j] == true
The reason for this extra "=" is that "==" is the comparing operator, and "=" is the operator to set something equal to, so when you do if(x=1) your checking wheter not x CAN be set equal to 1, not if it is equal to 1;
Otherwise your code looks like it would run and calculate, just fix these syntax errors.

Related

Reseting number java [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed last year.
Improve this question
So i got problem in java to determine who the last kid who got the candy, n is how many children, m is how many candy, and s is the number of kid who got the first candy.
so basically if n =4, m=6, and s =2 the answer is 3, because all started from 2(number of kid who got the first candy)->3->4 and restart to 1->2->3 and 3 is the last kid who got the candy.
the code run perfectly but i encounter bug at n = 3333, m =3333, and s = 1
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
int s = in.nextInt();
int total = m%n;
int jaw = total+s-1;
System.out.print(jaw);
}
I assume the "bug" you're mentioning is that jaw is 0, right? That's because 3333%3333 will be 0 and thus 0 + s - 1 will be 0 as well (0+1-1 = 0).
You're on the right track, i.e. m % n would tell you how many pieces of candy are left after everyone got a fair/equal share.
Now you just distribute the "rest" (total) which means you "add" it to "first child" (s). Let's say this is c = s + total, so c is the last child that got anything. You subtract -1 because if you add anything the "cursor" advances to the next child and thus you want to track back.
However, what if you didn't have anything to distribute? Then the last child that got anything was the one before the first, which in case of 4 children and starting at 1 would be the 4th. Your calculation results in 0 which basically would express this.
Another problem you might face with your code is that if you start at the last child (say 4) and have 2 pieces of candy to distribute, then you'd get the "5th" child instead of the "1st" to be the last to get something: 2 + 4 - 1 = 5.
So how do you solve that?
Add jaw %= n to handle the "overflow" (if you start at the last child and distributed 2 more pieces of candy, the first would get it)
Check if jaw == 0 in which case the solution would be jaw = n (the last child got the last candy)
The problem is that you arrive at person 0 , who does not exist.
3333%3333 = 0
then 0 + 1 - 1 = 0
As we are in a loop 0 is the last person of the previous turn ie person number m.
We solve this by saying that, if the result is zero we return m.
import java.util.Scanner;
class sweets {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int m = in.nextInt();
int s = in.nextInt();
int total = m%n;
int jaw = total+s-1;
if(jaw == 0){
jaw = m;
}
System.out.print(jaw);
}
}
You need to consider whenever m%n==0.
In that case jaw= n-s+1;
Just need to add an if statement to include it.

What would cause a for loop to decrement when it's supposed to increment?

I wrote a method to calculate how long ago a father was twice as old as his son and in how many years from now this would be true. Unexpectedly, it returns "-2 years ago" for an 8-year-old father and a 3-year-old son. Equally unexpectedly, it returns "-1 years from now" for a 3-year-old father and a 2-year-old son. I am not concerned about how to improve the code because I already know how to do this. Instead, I am puzzled about why the for loop counter appears to be decrementing when it's supposed to increment.
Here is my code.
public class TwiceAsOld {
public static void twiceAsOld (int currentFathersAge, int currentSonsAge) {
int yearsAgo;
int yearsFromNow;
int pastFathersAge = currentFathersAge;
int pastSonsAge = currentSonsAge;
int futureFathersAge = currentFathersAge;
int futureSonsAge = currentSonsAge;
for (yearsAgo = 0; pastFathersAge != 2 * pastSonsAge; yearsAgo++) {
pastFathersAge--;
pastSonsAge--;
}
System.out.println("The father was last twice as old as the son " + yearsAgo + " years ago.");
for (yearsFromNow = 0; futureFathersAge != 2 * futureSonsAge; yearsFromNow++) {
futureFathersAge++;
futureSonsAge++;
}
System.out.println("The father will be twice as old as the son in " + yearsFromNow + " years from now.");
}
public static void main(String[] args) {
twiceAsOld(8, 3);
twiceAsOld(3, 2);
}
}
With twiceAsOld(8, 3), the for loop's increment appears to have reversed itself to count down from 0 instead of up. With twiceAsOld(3, 2), the -1 might stand for an error indicating that the father has never been twice as old as his son and never will be. What I don't understand is what would cause a for loop to start decrementing the i value when it's supposed to increment. I was expecting the counter to increment indefinitely until the program ran out of memory.
I already know how to improve this program, but I am curious about how the counter in a for loop can decrease when it's supposed to increase. Can anybody explain this?
(UPDATE: Thanks everyone for your answers. I can't believe I forgot about integer overflow. I tried making the variables longs instead of integers, but this made the program even slower. Anyway, now I realize that the counter was incrementing all along until it overflew and landed at a negative value.)
It became negative because that is what happens in Java when an int calculation overflows.
Take a look at
https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.18.2
It says that
If an integer addition overflows, then the result is the low-order bits of the mathematical sum as represented in some sufficiently large two's-complement format. If overflow occurs, then the sign of the result is not the same as the sign of the mathematical sum of the two operand values.
Didn't you notice that your program runs quite slowly? :)
For the (8, 3) years ago case, your for loop keeps looping and looping, trying to find a year that the father is twice as old, but as we know, the father will only become twice as old in the future, but not in the past. The for loop doesn't know this and it will try very hard to find such a year. It tries so hard that yearsAgo is incremented past the max value of int. This causes an overflow, and the value of yearsAgo will "wrap back around" to the minimum value of int, which is a negative number. And then this negative number will get incremented many many times, until -2.
The same goes for the other case.
To fix this, you can add if statements to check if the results are negative:
public static void twiceAsOld (int currentFathersAge, int currentSonsAge) {
int yearsAgo;
int yearsFromNow;
int pastFathersAge = currentFathersAge;
int pastSonsAge = currentSonsAge;
int futureFathersAge = currentFathersAge;
int futureSonsAge = currentSonsAge;
for (yearsAgo = 0; pastFathersAge != 2 * pastSonsAge; yearsAgo++) {
pastFathersAge--;
pastSonsAge--;
}
// Here!
if (yearsAgo >= 0) {
System.out.println("The father was last twice as old as the son " + yearsAgo + " years ago.");
}
for (yearsFromNow = 0; futureFathersAge != 2 * futureSonsAge; yearsFromNow++) {
futureFathersAge++;
futureSonsAge++;
}
if (yearsFromNow >= 0) {
System.out.println("The father will be twice as old as the son in " + yearsFromNow + " years from now.");
}
}
You can also stop the loop when it reaches negative values to make your program faster:
for (yearsAgo = 0; pastFathersAge != 2 * pastSonsAge && yearsAgo >= 0; yearsAgo++) {
When I debug your code I can see that yearsAgo is incrementing without bound, causing pastFathersAge and pastSonsAge to go into negatives. This is causing negative integer overflow. This happens because your condition pastFathersAge != 2 * pastSonsAge is never met (rather, never NOT met). Not until your futureFathersAge has gone all the way through the negatives, back into positives, and finally settles on -2.
The moral of the story is to make certain that your terminating condition for your loop can always can be met. Don't use !=, use >= or <= instead.

Counter Loop - Java [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Closed 4 years ago.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Improve this question
Edit: I have found a way to work with CompareTo to help with this problem, but for some reason I cannot get the count down to work.
It's a negative number that needs to get more negative to meet the requirements, but I am missing something here. When I execute the down section it closes the program. So to me this means that I have something messed up and the program isnt seeing the problem and closing.
We are supposed to:
Ask the user for an integer then ask the user if he/she wants to count
up or down. Display a table of numbers where the first column contains
the counter, the second column contains the counter plus 10, and the
third column contains the counter plus 100. Make it so each number
takes up 5 spaces total.
If counting up, the first column should contain numbers 1 through the
user input; If counting down, the first column should contain numbers
-1 through the the negative of the user input;
Do user input validation on the word "up" and "down". Allow for any
case.
import java.util.Scanner;
public class ps1 {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
//Comparision string already declared
String up = "up";
String down = "down";
//initialize the counters sum
int sum = 0;
//ask the user for a number
System.out.println("Enter an ending value");
int num1 = keyboard.nextInt();
keyboard.nextLine();
System.out.println("Count up or down?");
String input = keyboard.nextLine();
while (input.equalsIgnoreCase(up) || input.equalsIgnoreCase(down)) {
System.out.println("Count up or down?");
input = keyboard.nextLine();
}
if (input.compareToIgnoreCase(up) == 0) {
if (num1 >= 0)
for (int c = 1; c <= num1; c++) {
sum = sum + c;
System.out.printf("%5d%5d%5d\n", c, c + 10, c + 100);
else
System.out.println("Up numbers must be positive");
if (input.compareToIgnoreCase(down) == 0) {
for (int c1 = -1; c1 <= num1; c1--) {
sum = sum + c1;
System.out.printf("%5d%5d%5d\n", c1, c1 + 10, c1 + 100);
}
}
}
}
}
I see you have figured out core logic. BTW, your code will not compile, there is a syntax error.
Your code would look like this:
print(a a+10 a+100)
I know that it's not valid syntax but you would be able to figure out the correct way to write the code.
To print data properly, you will need following:
https://dzone.com/articles/java-string-format-examples
I would recommend visualizing the output first. In your case, it would look like following: (_are spaces)
Enter an ending value: 2
Direction: Up
____1___11__101
____2___12__102
Also, think about error cases. What will happen in following:
Enter an ending value: -10
Direction: Up
Error: Improper data
You are allowing user to enter a positive num1 and count down using for (int counter1 = -1; counter1 >= num1; counter1--). This makes no sense as counter1 >= num1 resolves to -1 >= 1 which is never true. When direction is down the number must be negative and when direction is up the number must be positive.
You might need to loop until user provides a valid direction. Currently you go down for any input that is not up. A possible solution would be to:
String input;
do {
input = keyboard.nextLine();
} while (!input.equalsIgnoreCase("up") && !input.equalsIgnoreCase("down"));
Please use shorter variable names. counter1 is scoped just to the for loop block so call it i. It's easier to read.
Whichever editor you are using configure auto formatting :)

Implementing Java code for a betting game on coin-flips [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I have looked all over this website and other websites trying to figure how to do this with the knowledge that my teacher has provided me.
Basically the program is supposed to be a user input system where you can make bets on a head or tails coin flipping game.
So far, I've had no luck in what to do. Not asking someone to finish it for me, but to help me in the right direction.
Thank you in advance.
Here is my code so far:
package Homework6;
import java.util.Scanner;
import java.lang.Math;
public class CoinFlip {
public static void main(String[]args){
Scanner input = new Scanner(System.in);
int money = 10;
double flip = Math.random();
String heads = "heads";
String tails = "tails";
int bet = input.nextInt();
while(bet < 0 || bet > money){
if(true){
System.out.println("How much do you want to bet?");
input.next();
}
}
System.out.println("Guess if the coin will be heads or tails.");
String guess = input.next();
String coin;
if (flip <0.5) coin = heads;
else coin = tails;
if(guess == coin){
int correct = money + bet;
System.out.println("The flip was"+ coin);
System.out.println("You win" + bet);
System.out.println("")
}
}
}
To fix the possible infinite loop:
do{
System.out.println("How much do you want to bet?");
bet = input.nextInt();
}
while(bet > 0 && bet > money);
You can drop the if statement since it's not really needed. You will however need to declare the variable bet to have the correct scope.
if(guess.equals(coin)) // proper way of checking Strings
Use this form for checking the value of the guess vs the coin.
A few notes for you (since you're starting out and still a student):
1) Your while loop is a little bit poorly constructed. That System Out will constantly be printing to the screen until there is some input. And that if statement is essentially doing no conditional checking. It is always true.
2) You never originally prompt the user for how much they want to bet. You're only prompting them after they've input a value. So when you originally hit play, the console is just blank. But really it's waiting for some input.
3) Your if statement for changing the coin state is a little extraneous.
4) The user's amount of money is never actually updated, and the output at the end could be a little more informative.
5) What if someone wins the first one and wants to play again? They probably want to keep that bank growing! So you could encompass the entire thing inside of a do/while that runs while bank > 0.
6) You should only use the == operator when comparing primitive types. Pretty much all other times, use Object.equals(object);
I know you didn't ask someone to complete it for you, but this site works best by sharing information. Below should work for you, I've commented it extensively. Hopefully this can teach some things beyond just this homework assignment.
public static void main(String[] args)
{
// Setup some initial variables
int bank = 10;
double flip = Math.random();
// Instantiate a new Scanner object
Scanner input = new Scanner(System.in);
// Let the user bet until they run out of money in the bank
do
{
// Ask the user how much money to wager
System.out.println("How much do you want to bet?");
int bet = input.nextInt();
// The bet was invalid
while(bet < 0 || bet > bank)
{
System.out.println("Invalid bet (" + bet + "). Minimum bet = 0. Maximum bet = " + bank);
bet = input.nextInt();
}
// Ask the user for which side
System.out.println("Heads or tails?");
String guess = input.next();
// The coin is either heads or tails, so it can always start as tails. If the value goes under .5, change it to heads. If not, it remains the same, "tails".
String coin = "tails";
if (flip < 0.5)
{
coin = "heads";
}
// Tell the user the result, regardless of win or lose
System.out.println("The flip was " + coin);
// Update the user's bank and inform them of the new value
if(guess.equalsIgnoreCase(coin)) // this allows for any form of HeaDs or TaILs
{
bank += bet;
System.out.println("You win " + bet);
System.out.println("Your bank contains " + bank);
}
else
{
bank -= bet;
System.out.println("You lose " + bet);
System.out.println("Your bank contains " + bank);
}
}
while(bank > 0);
// Goodbye message
System.out.println("Thanks for playing!");
// Don't forget to close your Scanner object!
input.close();
}
Alright, since you are having so much trouble with this, I will lay it out how I achieved this.
You need a couple variables, I used these below, taken from your code.
Scanner input = new Scanner(System.in);
int money = 10;
String heads = "heads";
String tails = "tails";
int bet = 0;
String guess;
String coin;
You then need a loop. You have a while loop already, and that will do, BUT your conditional is incorrect as I see it. You are testing bet < 0 || bet > money which I read as "If you bet less than no money or bet more money that you have, enter this loop" I believe you want the opposite of that. I also added if you ran out of money.
while(bet > 0 || bet < money || money <= 0)
Now for the inside of the loop. Here, you want to do a couple things in a certain order.
Ask how much they want to bet, read it in the appropriate variable.
Ask what their guess is, read it in the appropriate variable.
Use your if statement you have to determine if the flip was heads or tails, But I got rid of the flip variable, and used Math.random() < 0.5 directly.
Check their guess vs the flip. If they were correct, do what you need to do, i.e. add bet to money and display some sort of message.
If they were wrong, do what you need to do, i.e. subtract bet from money, display some message.
Then your program will start over.

What is wrong with my code in my java yahtzee game?

I am writing code for a yahtzee game in java and I need to write a method which allows the user to choose which dice to keep and which dice to re-roll. The part I'm having trouble with is that the user must be able to choose more than one value to keep.
For example on the first roll they may choose to keep 3's, 5's, and a 6. This is what I have so far, but the correct dice are not being kept when I test it.
//keep method
public void keep(int[] keepThis) {
for(int i = 0; i < keepOrRollArray.length; i++) {
for(int p = 0; p < keepThis.length; p++) {
if(faceValueArray[i] == keepThis[p])
keepOrRollArray[p] = 'K';
}
}
}
//keep method tested after a roll
newDiceArray.roll();
int[] userValue = new int[2];
userValue[0] = 3;
userValue[1] = 4;
newDiceArray.keep(userValue);
System.out.println("Practice roll: " + "\n" + newDiceArray +"\n");
First off, I'm guessing that there is quite a bit more to your code than what you have posted. (Otherwise, your code is egregiously incomplete, not to put too fine of a point on it). Without this additional code, we can't really help much.
In the meantime, however, if what you have isn't "keeping" the correct dice, you might ought to try having five separate questions querying the user whether they want to keep each of the dice: "Do you want to keep dice #1", "Do you want to keep dice #2" etc. Then update your keepThis array appropriately.

Categories

Resources