This question already has answers here:
How do I generate random integers within a specific range in Java?
(72 answers)
Closed 6 years ago.
I'm making a game where the user must solve a simple subtraction but the result must be a positive whole number. I managed to do everything but for some reason the answer is sometimes negative and I'm not sure how to fix it
import java.util.Random;
import java.util.Scanner;
public class Subtraction {
public static void main(String[] args) {
Random r = new Random();
final int MAX = 10;
// get two random numbers between 1 and MAX
int num1 = r.nextInt(MAX) - 1;
int num2 = r.nextInt(MAX) - 1;
int total = (num1 - num2);
// display a question
System.out.printf("What is your answer to %d - %d = ?%n", num1, num2);
// read in the result
Scanner stdin = new Scanner(System.in);
int ans = stdin.nextInt();
stdin.nextLine();
// give an reply
if (ans == total) {
System.out.println("You are correct!");
} else {
System.out.println("Sorry, wrong answer!");
System.out.printf("The answer is %d + %d = %d%n", num1, num2, (num1 - num2));
}
}
}
Two possible solutions: Just change your total line with a condition to subtract the larger one from the smaller one (unless they're the same, in which case you'll get 0)
int total = (num1 > num2) ? (num1 - num2) : (num2 - num1);
Or just use the absolute value:
int total = java.lang.Math.abs(num1 - num2);
Change the printf as well:
System.out.printf("What is your answer to %d - %d = ?%n", (num1 > num2) ? num1 : num2, (num1 > num2) ? num2 : num1);
The conditionals are just making sure that the bigger number comes before the smaller number, or if they happen to be equal, that they are both listed.
Check out http://www.cafeaulait.org/course/week2/43.html for a more thorough explanation of the ? operator.
Generate your first value with room at the bottom for a second value to be subtracted, and the second one from a range bounded by the first:
int num1 = r.nextInt(MAX - 1) + 2; // produces values from 2 to MAX, inclusive
int num2 = r.nextInt(num1 - 1) + 1; // produces values from 1 to (num1 - 1), inclusive
The first number will always be strictly larger than the second, by construction, so the difference will always be a positive integer.
Well, with two random numbers in the same range, in random order, either cold be larger and the subtraction could be negative. Either fix how you get the numbers, or fix how they are ordered, or fix how you get their difference; any of these will do the job.
The code at the very heart of your program is wrong:
// get two random numbers between 1 and MAX
int num1 = r.nextInt(MAX) - 1;
int num2 = r.nextInt(MAX) - 1;
r.nextInt(MAX) returns a number between 0 (inclusive) and MAX (exclusive). Your code subtracts one from it, so you get a number in the range [−1, MAX−2].
Since you want it to be a simple subtraction where all numbers are in the range [1, MAX], you have to generate them that way. The general form of the subtraction is:
result = num1 − num2
This equation has the following constraints:
1 <= result <= MAX
1 <= num1 <= MAX
1 <= num2 <= MAX
result < MAX, since otherwise num2 would have to be 0
1 < num1, since otherwise the result would become negative
num2 < MAX, since otherwise result would have to be larger than MAX
This leaves the following allowed ranges:
1 <= result <= MAX − 1
2 <= num1 <= MAX
1 <= num2 <= MAX − 1
num2 <= num1 - 1
To generate these numbers, the code has to look like this:
int num1 = randomBetween(2, MAX);
int maxNum2 = Math.min(MAX - 1, num1 - 1);
int num2 = randomBetween(1, maxNum2);
Now what is randomBetween? You have to define it:
randomBetween(min, max) ≡ r.nextInt(max + 1 - min) + min
Together, this is:
int num1 = r.nextInt(MAX + 1 - 2) + 2;
int maxNum2 = Math.min(MAX - 1, num1 - 1);
int num2 = r.nextInt(maxNum2 + 1 - 1) + 1;
int result = num1 - num2;
assert 1 <= result && result <= MAX;
Since you know the result must be positive, I would start with the result
int total = r.nextInt(MAX) + 1;
int num2 = r.nextInt(MAX - total + 1);
int num1 = total + num2;
This way you can be sure that num1 - num2 will always be positive.
package optinalTest;
import java.util.Scanner;
import java.util.concurrent.ThreadLocalRandom;
public class Subtraction {
public static void main(String[] args) {
for (int i = 0; i < 10; i++) {
randomNumber();
}
}
private static void randomNumber() {
// get two random numbers between 1 and MAX
int num1 = ThreadLocalRandom.current().nextInt(10000, 9999998);
int num2 = ThreadLocalRandom.current().nextInt(num1 + 1, 9999999);
int total = (num2 - num1);
// display a question
System.out.printf("What is your answer to %d - %d = ?%n", num2, num1);
// read in the result
Scanner stdin = new Scanner(System.in);
int ans = stdin.nextInt();
stdin.nextLine();
// give an reply
if (ans == total) {
System.out.println("You are correct!");
} else {
System.out.println("Sorry, wrong answer!");
System.out.printf("The answer is %d - %d = %d%n", num2, num1, (num2 - num1));
}
}
}
Related
I'm making a program where you put in two integers, and the program finds the greatest common divisor between the two numbers.
It runs fine, except it prints "1" as the GCD, even when the two numbers should have a different GCD. (Example: 4 & 64. GCD should be 4, but 1 still gets printed.) I can't figure out what's wrong with my code.
For those who want to answer using one method instead, I can't: It's an assignment that requires me to use two different methods in the same program. Please help?
Thanks for reading, and have a good week.
Here my code:
import java.util.Scanner;
public class greatestCommonDivisorMethod {
public static void main(String[] args)
{
Scanner input = new Scanner(System.in);
//Number entry prompts
System.out.print("Please enter first integer: ");
int num1 = input.nextInt();
System.out.print("Please enter second integer: ");
int num2 = input.nextInt();
//Result printed
System.out.println("The greatest common divisor of " +num1+ " and " +num2+ " is " +gcd(num1, num2)+".");
}
public static int gcd(int num1, int num2) {
int gcd = 1;
int k = 2;
while (num1 <= k && k <= num2)
{
if (num1 % k == 0 && num2 % k == 0)
gcd = k;
k++;
}
return gcd;
}
}
while (num1 <= k && k <= num2)
{
if (num1 % k == 0 && num2 % k == 0)
gcd = k;
k++;
}
It looks like you accidentally switched num1 and k in your while loop.
The while condition should probably have k<=num1 instead of num1<=k
Assign your return to a variable then print it
int answer = gcd(num1, num2);
then when printing cast to String or use toString method.
System.out.println("The greatest common divisor of " +answer.toString());
Part 1:
Given 4 integers, output their product and their average, using integer arithmetic.
Ex: If the input is:
8, 10, 5, 4
the output is:
1600 6
Note: Integer division discards the fraction. Hence the average of 8, 10, 5, 4 is output as 6, not 6.75.
Note: The test cases include four very large input values whose product results in overflow. You do not need to do anything special, but just observe that the output does not represent the correct product (in fact, four positive numbers yield a negative output; wow).
Submit the above for grading. Your program will fail the last test cases (which is expected), until you complete part 2 below.
Part 2:
Also output the product and average, using floating-point arithmetic.
Output each floating-point value with three digits after the decimal point, which can be achieved as follows:
System.out.printf("%.3f", yourValue);
Ex: If the input is 8, 10, 5, 4, the output is:
1600. 6
1600.000 6.750
Note that fractions aren't discarded, and that overflow does not occur for the test case with large values.
What I have,
import java.util.Scanner;
public class LabProgram {
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
int num1;
int num2;
int num3;
int num4;
num1 = scnr.nextInt();
num2 = scnr.nextInt();
num3 = scnr.nextInt();
num4 = scnr.nextInt();
double average_arith = (num1+num2+num3+num4)/4.0;
double product_arith = num1*num2*num3*num4;
int result1 = (int) average_arith;
int result2 = (int) product_arith;
System.out.printf("%d %d\n",result2,result1);
System.out.printf("%.3f %.3f\n",product_arith,average_arith);
}
}
So When I input example numbers everything checks out except overflow,
input: 100000 200000 300000 500000
Expected output:
-1679818752 275000
3000000000000000000000.000 275000.000
My output:
-1679818752 275000
-1679818752.000 275000.000
Any help please?
The result of multiplying two ints is an int. So here, you multiply the inputted numbers as ints (which causes them to overflow), and only then promote the result to a double. In order to get a non-overlowing result, you need to have at least one of the operands in each multiplication as a double. Since the * is left-associative, casting num1 to a double should do the trick:
double product_arith = ((double) num1) * num2 * num3 * num4;
-- Here ----------------^
I just did this lab too!
Mureinik has it right BUT I made a second product variable just for the overflow, and used the first one for the int. Does that make sense?
try using this code
int average;
average = (num1 * num2 * num3 * num4);
int product;
product = (num1 + num2 + num3 + num4) / 4;
double product2;
double average2;
average2 = ((double)num1 + num2 + num3 + num4 / 4.0);
product2 = ((double)num1 * num2 * num3 * num4);
Try this :)
Scanner scnr = new Scanner(System.in);
int num1;
int num2;
int num3;
int num4;
num1 = scnr.nextInt();
num2 = scnr.nextInt();
num3 = scnr.nextInt();
num4 = scnr.nextInt();
int average;
average = (num1 * num2 * num3 * num4);
int product;
product = (num1 + num2 + num3 + num4) / 4;
double product2;
double average2;
average2 = ((double)num1 + num2 + num3 + num4);
product2 = ((double)num1 * num2 * num3 * num4);
System.out.printf("%d %d\n", average, product);
System.out.printf("%.3f %.3f\n", product2, average2 / 4.0 );
I'm asking the user to enter two random numbers(i.e 1 10) then I have to add them up inclusively, so (1 10) would be 55.
public int sum(int num1, int num2) {
int counter; //just a variable until I clean this up and get it to work
questions++;
if (num1 < num2) {
int difference = num2-num1;//difference between the given numbers
int holder = 0;
while (holder <= difference) {
holder ++;
num1 += num1;
}
counter = num1;
}
}
This is the chunk of code I have been testing. This gives me 256 when I run 1 and 10.
if (num1 < num2)
{
int answer = num1;
while (num1 <= num2)
{
answer = answer + num1++;
}
retrun answer;
}
Java 8 variant:
IntStream.rangeClosed(Math.min(num1, num2), Math.max(num2, num1)).sum()
What it does:
Create range of ints that contains all numbers from num1 to num2 inclusively
we need to make sure that left border always less than right one, otherwise range will be empty. That's why I've used min() and max()
Add all the numbers together.
Beware though:
Certain combinations of numbers produce a sum that's higher than Integer.MAX_VALUE, and this will cause the sum to overflow and possibly produce negative values.
This can be accounted for by using slightly different version, that's slightly less performant:
IntStream.rangeClosed(Math.min(num1, num2), Math.max(num2, num1))
.mapToObj(BigInteger::valueOf)
.reduce(BigInteger.ZERO, BigInteger::add);
public int sum(int num1, int num2) {
int result = 0;
while(num1<=num2) {
System.out.println("num1 is: "+num1);
result = result + num1;
num1++;
}
return result;
}
Please note the print line within the loop to display the progress of the while.
I'm guessing you're doing this as a programming exercise, so using a loop is the whole point of the task. However, if you just wanted code that gave you the right answer you could use the arithmetic series formula:
public int sum(int num1, int num2) {
if (num1 <= num2) {
return (num2 - num1 + 1) * (num1 + num2) / 2;
}
return 0;
}
The question is to Write a program that sorts three integers. The integers are entered from the input dialogs and stored in variables num1, num2, and num3, respectively. The program sorts the numbers so that num1 <= num2 <= num3.
actually I do that but the result is available only to 1 ,2 and 3 numbers !
When I enter any different number it doesn't show me the result I want it !
here is my code..
import javax.swing.JOptionPane;
public class number order {
public static void main(String[] args) {
int num1;
int num2;
int num3;
String n = JOptionPane.showInputDialog(null, "input NUM 1 " );
num1 = Integer.parseInt(n);
String u = JOptionPane.showInputDialog(null, "input NUM 2 " );
num2 = Integer.parseInt(u);
String m = JOptionPane.showInputDialog(null, "input NUM 3 " );
num3 = Integer.parseInt(m);
if (num1<=num2&& num2<=num3)
System.out.println( num1+"<="+ num2+"<="+num3 );
if(num2<=num1&&num1<=num3)
System.out.println(num2+"<="+num1+"<="+num3);
if (num3<=num1&&num1<=num2)
System.out.println(num3+"<="+num1+"<="+num2);
// TODO code application logic here
}
}
The problem is that you check only three out of six possible arrangements of those three numbers. Also note that, even for those three, you are not actually sorting the numbers, but only printing them in sorted order, i.e., you are never reassigning the variables num1, num2, and num3.
Just as an alternative to checking all the possible arrangements of the three numbers or implementing a full sorting algorithm, you can also compare and swap pairs of numbers. This way, you get away with far fewer comparisons while still being able to sort all permutations of three numbers.
if num1 > num2, swap num1 and num2
if num2 > num3, swap num2 and num3
if num1 > num2, swap num1 and num2 again
After those three swaps, the numbers are in sorted order.
Of course, if you have more than three numbers this gets impractical, and you should rather implement a full sorting algorithm (for exercise) or go with one of the builtins, like Arrays.sort (for real life).
You haven't checked all cases:
1 < 2 < 3
1 < 3 < 2
2 < 1 < 3
2 < 3 < 1
3 < 1 < 2
3 < 2 < 1
However to check all case like that is not to useful.
an sorted array would be more easy:
int arr[3]={num1,num2,num3}
java.utils.Arrays.sort(arr);
println(arr[0] + "<=" + arr[1] + "<=" + arr[2]);
int[] all = new int[]();
num1 = Integer.parseInt(n);
all[0] = num1;
num2 = Integer.parseInt(u);
all[1] = num1;
num3 = Integer.parseInt(m);
all[2] = num1;
for(int i=0; i <all.length ;i++){
if(i!=0 && all[i]< all[i-1]){
temp = all[i-1];
all[i-1] = all[i];
all[i] = temp;
}
}
all will have sorted array
or more simply
2 steps
1)add all to a array.
2) call Arrays.sort(array)
how about
int min = min(min(num1,num2),num3);
int max = max(max(num1,num2),num3);
int mid = num1 + num2 + num3 - min - max;
System.out.println(min+"<="+mid+"<="+max);
if(num1 < num2){ if(num3 < num1) System.out.println("num2 > num1 > num3");}
else{ if(num2 < num3) System.out.println("num3 > num2 > num1"); else System.out.println("num1 > num2 > num3");}
Sort in descending order.
Hope it helps.
import java.util.Scanner;
import java.util.Random;
public class Lab04b
{
public static void main(String []args)
{
Random generator = new Random ();
Scanner scan = new Scanner(System.in);
int num1;
int num2;
int num3;
System.out.println("Enter X:");
num1 = scan.nextInt();
System.out.println("Enter Y:");
num2 = scan.nextInt();
num3 = generator.nextInt(num2) + num1;
System.out.println("3 random integers in the range " + num1 + ".." + num2 + " are: " + num3);
}
}
I am stuck on how to get 3 random integers between the x and y range. Y being the biggest integer.
The trick is finding the difference between x and y. Here is what you need to do -
int diff = Math.abs(num1 - num2);
num3 = generator.nextInt(diff) + Math.min(num1, num2);
Just do it 3 times and you get your 3 numbers.
From the docs
nextInt(int n)
Returns a pseudorandom, uniformly distributed int value between 0
(inclusive) and the specified value (exclusive), drawn from this
random number generator's sequence.
so random.nextInt(Y) would give you numbers 0..Y, I guess you are missing how to get the lower bound correctly.
X + random.nextInt(Y-X) does the trick.
Read the documentation. The nextInt(n) function returns an Integer in [0, n). So, in your case, you can use the formula min + nextInt(max-min), which will give you a number in [min, max).
Random generator = new Random();
int max = (x >= y ? x : y);
int min = (x < y ? x : y);
int aRandomNumber = min + generator.nextInt(max-min);
Firstly have a loop which will run 3 times, to generate 3 random numbers(as you said you need 3 random numbers, but you're just generating only 1).
Next, the pattern you've used to generate a random number seems to be flawed. You can use the below type 1 pattern to accomplish that.
min + Math.random() * ((max - min) + 1));
Or this type 2 pattern
rand.nextInt((max - min) + 1) + min;
So you can do something like this:-
for (int i = 0; i < 3; i++) {
// Type 1
num3 = num1 + (int)(Math.random() * ((num2 - num1) + 1));
// Type 2
// num3 = generator.nextInt((num2 - num1) + 1) + num1;
System.out.println("3 random integers in the range " + num1 + ".." + num2 + " are: " + num3);
}
P.S:- You need to first determine the max and min, yourself. I've just given the pattern and a sample.
import java.util.Scanner;
public class GenerateRandomX_Y_numbers {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter the numbers x and y: ");
int x = Math.abs(sc.nextInt()), y = Math.abs(sc.nextInt());//we need //non-negative integers, that is why we use here Math.abs. which means the //absolute value
print3RandomNumbers_between_x_and_y(x, y);
}
public static void print3RandomNumbers_between_x_and_y(int x, int y) {//here //I create a method with void type that takes two int inputs
boolean isTrue = (x < y);//according to our conditions X should less //than Y
if (isTrue) {//if the condition is true do => generate three int in the //range x .... y
int rand1 = (int) (Math.random() * (y - x) + 1);// y - x means our //range, we then multiply this substraction by Math.random()
int rand2 = (int) (Math.random() * (y - x) + 1);//the productof this //multiplication we cast to int type that is why we have
int rand3 = (int) (Math.random() * (y - x) + 1);//(int) before //(Math.random() * (y - x));
System.out.println("rand1 = " + rand1);//
System.out.println("rand2 = " + rand2);//
System.out.println("rand3 = " + rand3);//here print our result
} else
System.out.println("Error input: X should be less than Y. Try it again!");//if the condition is not true, i mean if x is not less than or equal //to Y, print this message
}
}