I am writing a program in which the random method generates a random number between 1 and 100, and then the user guesses what the number is.
Everything in the code I built works fine so far, except the part where the program also calculates the number of user guess attempts.
I know the general idea of how to get the user attempt count: create a count-tracking variable and then increment it with each user entry. Now matter how or where I apply the count-tracking variables, the number of user attempts is always 2, even though there are far more actual attempts. I Googled this issue, and tried different ideas from results (ex: put count++ into every "if/else" statement), but nothing works.
Can anyone tell what is wrong with my code, and why it is always showing 2 as number of user attempts? Thank you in advance for any help.
System.out.println("Enter a number between 0 and 100: ");
int randomDigit = (0 + (int) (Math.random() * 101));
while (true) {
Scanner scr = new Scanner(System.in);
int guess = scr.nextInt();
int guessCount = 0;
guessCount++;
guessCount = guessCount + 1;
if ((guess < 0) || (guess > 100)) {
System.out.println("You entered an invalid number. \nPlease enter a valid number.");
} else if (guess > randomDigit) {
System.out.println("Your guess is too high. \nPlease enter another guess.");
} else if (guess < randomDigit) {
System.out.println("Your guess is too low. \nPlease enter another guess.");
} else if (guess == randomDigit) {
System.out.println("Congradulations, you found the number! It is " + randomDigit
+ ".\nThe number of attempts it took you to guess the correct answer is: " + guessCount + ".");
break;
}
}
The above code always has 2 as number of user attempts.
Move this line:
int guessCount = 0;
Outside the loop, as you are constantly repeating the initialization of the variable, and thus, not actually counting it.
When you use a counter, always define it outside your while/for loops.
Good luck
Related
The Task
Design and implement an application that reads an integer value and prints out the sum of all EVEN integers between 2 and its input value, inclusive. Print an error message if the input value is less than 2. Prompt accordingly.
Note: the lesson was on while loops, not other loops such as for loop etc
The Issue
I have everything working, however something about how I have written this feels wrong. I currently have a while loop while(programOn) to keep the program running. without this while loop, if the user enters a number < 2, the user is asked to try again, however if the user tries again, the program exits instead of running the new input into the program. So, I created the while loop to force the program open until the user types an acceptable input.
- something about this feels hacky and incorrect i would really appreciate some validation on my method.
public static void main(String[] args){
int inputNumber;
int sum = 0;
boolean programOn = true;
Scanner scan = new Scanner(System.in);
System.out.println("Please Type a number no smaller than 2");
inputNumber = scan.nextInt();
//include the original input to sum
sum = inputNumber;
while(programOn){
if(inputNumber < 2){
System.out.println("you need a number greater than or equal to 2, try again");
inputNumber = scan.nextInt();
sum = inputNumber;
}else{
//from the number chosen divide until you reach 0
while(inputNumber != 0){
//subtract one from the number
inputNumber = (inputNumber - 1);
if((inputNumber % 2 == 0) && (inputNumber != 0)){
System.out.println(inputNumber);
//add the input to the sum
sum += inputNumber;
}
}
System.out.println("The sum is " + sum);
programOn = false;
}
}
}
That's because the validation is done by an if condition. What you need here is a while loop that keeps asking for inputs as long as user's input is less than 2, below is the code snippet that does this:
Scanner scan = new Scanner(System.in);
System.out.println("Please Type a number no smaller than 2");
int inputNumber = scan.nextInt();
while(inputNumber < 2){
System.out.println("you need a number greater than or equal to 2, try again");
inputNumber = scan.nextInt();
}
System.out.println(inputNumber);
Okay, so the problem isn't necessarily the actual code because it works, but rather the logic. The problem is how many guesses will it take the computer to get the number your thinking? Between 1-100 it will always guess your number in 7 tries no matter what it is as long as it's between 1-100. The next question is what about 1-50, I figured out that it will only take 5 tries to always guess your number.
import java.util.Scanner;
public class ThinkofaNumber {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("Guess a number between 1 and 100");
System.out.println();
int input = 0;
//guess is equal to half the highest number
int guess = 50;
//low is equal to the lowest
int low = 1;
//high is equal to the highest number
int high = 101;
int tries = 1;
while (input != 2) {
System.out.println("Is your number " + guess + "?");
System.out.println("1: No, my number is lower");
System.out.println("2: Yes, that is my number");
System.out.println("3: No, my number is higher");
System.out.println();
input = in.nextInt();
if (input == 1) {
high = guess;
guess = low + (guess - low) / 2;
tries++;
} else if(input == 3) {
low = guess;
guess = guess + (high - guess) / 2;
tries++;
}
}
System.out.println("Your number is " + guess + "!");
if (tries == 1) {
System.out.println("It took 1 try to guess " + guess);
} else {
System.out.println("It took " + tries + " guesses to get " + guess);
}
}
}
The problem is the question then goes on to ask how many do you think the maximum number of guesses would be if the number was between 1 and 400? What if it were between 1 and 800? Between 1 and 1600? I think it's trying to get me to find a pattern or a algorithm but I don't see it. What do you guys think?
The algorithm you are talking about is a binary search algorithm. https://en.wikipedia.org/wiki/Binary_search_algorithm
It is a binary search algorithm as Wojciech said. The number 7 comes from the following log2 (100) = 6.6 round up to 7.
So you can do log base 2 to find the number of guesses
Just to provide a little more breakdown from #Wael's answer.
More discussion on the binary search algorithm can be found here and in this answer we know that 2N+1-1 gives us the range (1..X) for any number of guesses N.
So we can further break this down by saying:
2N+1-1 = 800
2N+1 = 801
log2801 = N+1
log2801 -1 = N
i.e. 8.646 = N, N = 9
So it will take a maximum of 9 guesses to guess a number between 1 and 800.
I should also point out that 2N+1-1 is the worst case, and so when trying to find the number of guesses for a given input, it will vary depending on the input.
The question is:
Write a program that prompts the user to enter an integer and displays whether the number is a multiple of 4 or not. The program stops reading integers, when the user inputs a negative value. It shows at the end the total number of values entered which are multiple of 4.
Here is my progress so far:
Scanner input = new Scanner(System.in);
System.out.println("Enter an integer: ");
int n;
while ((n = input.nextInt()) >= 0) {
if ( n%4 == 0) {
System.out.print(n + " is a multiple of 4");
}
else {
System.out.print(n + " is not a multiple of 4");
}
}
My problem is that I don't how to let the loop to keep executing until the user types in 0.
change the line
while((n = input.nextInt()) >= 0)
to
while((n = input.nextInt()) != 0)
This will keep the loop running until a zero is entered
Actually, 0 isn't a negative number, so you don't need to stop at 0. Your code is correct!
I am a Java newbie and have been working on this program for about a month. My program is a graduation planner that shows the student how much time and money it would take to finish a college degree. I would like my program to be able to recognize that the minimum # of CUs could be < than 12 if the student only has 6 or so CUs left until graduation, but I also need it to recognize if I enter a letter or negative number which I somehow managed to pull off at the top of the code. I tried to use sum == sum which isn't giving me the desired output. I think I need to put the while (loop) somewhere in there.
package gradplanner13;
import java.util.ArrayList;
import java.util.Scanner;
public class GradPlanner13 {
public static void main(String[] args) {
int sum = 0;
Scanner input = new Scanner(System.in);
ArrayList<Integer> array = new ArrayList<>();
boolean loop = true;
System.out.println("Enter the individual CUs for your remaining courses. Enter 0 when done entering your individual CUs.");
while (loop) {
System.out.print("Enter CUs for individual course then press enter: ");
if (!input.hasNextInt()) {
input.nextLine();
System.out.println("Only positive numbers are valid inputs. Please try again. ");
continue;
}
if (!input.hasNextInt()) {
input.nextLine();
System.out.println("Only postive numbers are valid inputs. Please try again.");
continue;
}
int check = input.nextInt();
input.nextLine();
if (check == 0) {
loop = false;
continue;
} else if (check < 0) {
System.out.println("CU values must be positive. Try again.");
continue;
}
array.add(check);
}
for (Integer CUs : array) {
sum += CUs;
}
System.out.println("Total number of CUs for all courses: " + sum);
double rounded = 0;
do {
System.out.print("How many CUs you are planning to take each term: ");
rounded = input.nextInt();
if (sum == sum) {
break;
}
if (rounded < 12 || rounded > sum) {
System.out.println("Take each term with a minimum of 12 CUs or the CUs you have left to complete your program if less than 12 : ");
}
} while (rounded < 12 || rounded > sum);
double numTermsToCompletion = Math.ceil(sum / rounded);
System.out.println("Number of terms to completion: " + numTermsToCompletion);
System.out.println("Tuition cost based on number of terms to completion: $" + (numTermsToCompletion * 2890));
System.out.println("Number of months to completion: " + (numTermsToCompletion * 6));
}
}
The below code is the section that I think I am having trouble with because I need it to recognize that sometime a student may not have the minimum (12) CUs left and I would like it to check to make sure the minimum is met or recognize that less than the minimum is left and still process the input. I tried to reuse while (loop) cause I know that part of the program responds correctly when I try to enter a letter or negative number at the beginning of the code, but I obviously was not implementing the loop correctly when I tried to put it on the below code, the program runs but doesn't produce anything when it gets to that point in the code. It just runs and doesn't produce any errors. In summary, I would appreciate some assistance getting my code to realize that a student may not have the minimum CUs left (12) and may need < than that to graduate, but also not accept negative numbers or letters as input.
do {
System.out.print("How many CUs you are planning to take each term: ");
rounded = input.nextInt();
if (sum == sum) {
break;
}
if (rounded < 12 || rounded > sum) {
System.out.println("Take each term with a minimum of 12 CUs or the CUs you have left to complete your program if less than 12 : ");
}
} while (rounded < 12 || rounded > sum);
So I moved sum == sum and I am a little closer to where I need to be. I still need to do some research because I am how getting the statement that tells me that I need to have a minimum of 12, but it still gives me the correct output.
do {
System.out.print("How many CUs you are planning to take each term: ");
rounded = input.nextInt();
if (rounded < 12 || rounded > sum) {
System.out.println("Take each term with a minimum of 12 CUs or the CUs you have left to complete your program if less than 12 : ");
}
if (sum == sum) {
break;
}
} while (rounded < 12 || rounded > sum);
This is the output:
Total number of CUs for all courses: 8
How many CUs you are planning to take each term: 8
Take each term with a minimum of 12 CUs or the CUs you have left to complete your program if less than 12 :
Number of terms to completion: 1.0
Tuition cost based on number of terms to completion: $2890.0
Number of months to completion: 6.0
BUILD SUCCESSFUL (total time: 12 seconds)
Ok. From the recommendations I have received, I rethought the process and rewrote some of the code and it works a lot better. The problem now is if the user enters 0 from the beginning, this is the output:
Enter the individual CUs for each individual remaining course. Enter 0 when done entering your individual CUs for each course.
Enter CUs for individual course then press enter: 0
Total number of CUs for all courses: 0
Number of terms to completion: 1
Tuition cost based on number of terms to completion: $2890
Number of months to completion: 6
BUILD SUCCESSFUL (total time: 2 seconds)
If you have 0 CUs left, you shouldn't have any terms left. It looks like I need to either change where my loop is false, or do something similar like I did here:
if (sum >= 12) {
do {
System.out.print("How many CUs you are planning to take each term? Minimum of 12 CUs required per term: ");
numOfCUs = input.nextInt();
} while (numOfCUs < 12);
numTermsToGraduation = (int) Math.ceil(sum / (double) numOfCUs);
Below is the complete new code:
System.out.println("Enter the individual CUs for each individual remaining course. Enter 0 when done entering your individual CUs for each course.");
package gradplanner13;
import java.util.ArrayList;
import java.util.Scanner;
public class GradPlanner13 {
public static void main(String[] args) {
int sum = 0;
Scanner input = new Scanner(System.in);
ArrayList<Integer> array = new ArrayList<>();
boolean loop = true;
// Student enters the individual credits for each course remaining in their degree program
System.out.println("Enter the individual CUs for each individual remaining course. Enter 0 when done entering your individual CUs for each course.");
// loop checks to make sure inputs are positive numbers
while (loop) {
System.out.print("Enter CUs for individual course then press enter: ");
if (!input.hasNextInt()) {
input.nextLine();
System.out.println("Only positive numbers are valid inputs. Please try again. ");
continue;
}
if (!input.hasNextInt()) {
input.nextLine();
System.out.println("Only postive numbers are valid inputs. Please try again.");
continue;
}
int check = input.nextInt();
input.nextLine();
if (check == 0) {
loop = false;
continue;
} else if (check < 0) {
System.out.println("CU values must be positive. Try again.");
continue;
}
// Calculates inputs from user
array.add(check);
}
for (Integer CUs : array) {
sum += CUs;
}
System.out.println("Total number of CUs for all courses: " + sum);
int numOfCUs = 0;
int numTermsToGraduation = 0;
if (sum >= 12) {
do {
System.out.print("How many CUs you are planning to take each term? Minimum of 12 CUs required per term: ");
numOfCUs = input.nextInt();
} while (numOfCUs < 12);
numTermsToGraduation = (int) Math.ceil(sum / (double) numOfCUs);
} else {
numOfCUs = sum;
numTermsToGraduation = 1;
}
System.out.println("Number of terms to completion: " + numTermsToGraduation);
System.out.println("Tuition cost based on number of terms to completion: $" + (numTermsToGraduation * 2890));
System.out.println("Number of months to completion: " + (numTermsToGraduation * 6));
}
}
From what I could tell, you are trying to use "sum == sum" to tell you if the input value is an negative number or a letter. This is not correct, as sum==sum will always return true.
For checking if it is a number is positive, you should just use sum > 0.
As for checking if its actually a letter, and not a number, this is handled by your scanners when you check if the input is a number (hasNextInt).
It looks like you are using if (sum == sum) {...} to error check the value of sum. That is not what you want to do, because it is always going to equate to true. What you want to do is use a try {...} catch (InputMismatchException e) {...}. In your case, it would be set up as follows:
...
System.out.println("Enter the individual CUs for your remaining courses. Enter 0 when done entering your individual CUs.");
int exception = 1;
while (exception = 1) {
try {
int someNum = input.nextInt();
...
}
catch (InputMismatchException e) {
exception = 1;
System.out.println("Please enter the correct data type!");
}
}
...
At the first moment the InputMismatchException is thrown, the program will execute the code in the catch block.
I have an application a number guess game, users have to guess a number between 0 and 100, when they guess right the program asks them if they would like to play again when their done play I display the least number of guesses in a game and the greatest number of guess in a game. Right now all i get is the sum of all their guesses in the when using the "Math.min(,)"?
How do I get the minimum function to work??? the function code is in further below.
leastNumGuesses = Math.min(leastNumGuesses,guesses);
double rightNum = Math.random() *100;
int randomNum = (int) rightNum; //convert the random number to int
int tries = 0; //single game gussess output
int numberOfGames = 0;
int allTries = 0; //accumalates all tries(sum of all tries)
int guesses = 0; // guesses of all games combined
int gameGuesses = 0;
int leastNumGuesses = 100;
int mostNumGuesses = 0;
while (choice.equalsIgnoreCase("y"))
{
System.out.println();
int guess = getIntWithinRange(sc,"Enter the Number: ", 0, 100);
tries++;
guesses++;
gameGuesses++;
if (guess == randomNum)
{
numberOfGames++;
System.out.println("You got it in " + tries + " tries.");
leastNumGuesses = Math.min(leastNumGuesses,gameGuesses);
if (tries <=3)
System.out.println("Great work! You are a mathematical wizard.");
else if (tries > 3 && tries <= 7)
System.out.println("Not too bad! You've got some potential.");
else if (tries > 7)
System.out.println("What took you so long? Maybe you should take some lessons.");
System.out.println();
System.out.println("Would you like to play again (y/n):");
choice = sc.nextLine();
while (!choice.equalsIgnoreCase("n") && !choice.equalsIgnoreCase("y"))
{
System.out.println("Error! entry must be \"y\" or \"n\".");
System.out.println("Would you like to play again (y/n):");
choice = sc.nextLine();
}
if (choice.equalsIgnoreCase("y"))
{ // reset the random number & tries
rightNum = Math.random() *100;
randomNum = (int) rightNum;
tries=0;
gameGuesses++;
}
else if (choice.equalsIgnoreCase("n"))
{
allTries += guesses;
int averageNumGuess = allTries / numberOfGames;
System.out.println("Bye - Come back again");
System.out.println("Number of Games Played: " + numberOfGames);
System.out.println("Average Number of Guesses: " + averageNumGuess);
System.out.println("Least Amount of Guesses In a Single Game: " + leastNumGuesses);
}
}
It seems that you're changing what you want guesses to stand for in the middle of the program.
Remember that guesses is the total number of guesses over all games played, and that leastNumGuesses is initially set to 100. In most cases, you will find that guesses < leastNumGuesses, and thus the Math.min(guesses, leastNumGuesses) function will return guesses.
To fix: use variable other than guesses, for example, gameGuesses to keep track of how many guesses were made in a game. Then, Math.min(,) will behave as you expect.