Randomly generating numbers until they divide exactly - java

I ran into a little problem here. Basically my program below is just generating two random numbers and divide both of them.
Before that I insert a statement whereby if num1 is not divisible by num2, then num2 has to generate a number between 1 to "num1" until it is divisible.
But in the end it keeps giving me a number which is not divisible (or basically giving decimal points). I tried looking for an example in the Internet and understood so well with the modulus operator. Where did I go wrong here? I just want both numbers to be divisible that's all.
Below is my code:
int num1, num2, real_ans;
Random randomGenerator = new Random();
num1 = randomGenerator.nextInt(100) + 1;
num2 = randomGenerator.nextInt(100) + 1;
if (num1%num2!=0) {
do {
num2 = randomGenerator.nextInt(num1) + 1
} while(num1%num2==0);
}
real_ans = num1 / num2;

Change the do/while loop to:
do{
num2 = randomGenerator.nextInt(num1) + 1
} while(num1 % num2 != 0);
(note the !=).
This loops until the numbers divide exactly.

you are iterating with the condition that if num1 is divisible by num2, keep iterating. Change the condition to do{...}while (num1%num2 != 0);.
You should be able to find a number that can divide num1 with that code. The only case it still won't work is when num1 is prime, so I suggest you check if num1 is prime and only generate num2, when num1 is not prime.

Related

Calculating sum of odd numbers between two user inputs

I am trying to calculate the sum of the odd numbers between two user inputted numbers.
This is the code I have so far:
import java.util.Scanner;
class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("#1: ");
int num1 = s.nextInt();
System.out.print("#2: ");
int num2 = s.nextInt();
int sum = 0;
for (int i = num1; i <= num2; i += 2) {
sum = sum + i;
}
System.out.print(sum);
}
}
When I input 3 and 11, it outputs 35, which is correct.
However, with 4 and 20, it outputs 108, which is not correct. It should instead be 96.
Where have I gone wrong in the code?
You need to check if the first number is even or odd first, because if it is even, it is going to sum the even numbers instead of odd ones since you are increasing "i" by 2 after every iteration. Try adding the line below before the for loop.
if(num1%2==0){num1++);
Explanation
Your loop sums the even numbers if you start with an even number.
Check your code:
for (int i = num1; i <= num2; i += 2)
Assume num1 is even, e.g. 4. Then your loop starts with i = 4. And then you continue with += 2, so you end up with 6, 8, 10, ..., i.e. the even numbers.
Solution
You can simply fix it by patching num1 before your loop.
// Put this before your loop
if (num1 % 2 == 0) { // checks if num1 is even
num1++;
}
This way you will start with 5 then, and then get 7, 9, 11, ....
To sum a range of numbers:
Take the average of the first number and the last number, and multiply by the number of numbers.
But, first you need to make sure you lower and upper bounds are odd numbers. This is actually what is the problem with the code in the question.
Once that is done, calculate the average number, and the number of numbers:
public static long sumOddNumbers(int min, int max) {
long minOdd = (min % 2 == 1 ? min : min + 1); // Round up to odd number
long maxOdd = (max % 2 == 1 ? max : max - 1); // Round down to odd number
if (minOdd > maxOdd)
return 0;
// average = (minOdd + maxOdd) / 2
// count = (maxOdd - minOdd) / 2 + 1
// sum = count * average
return ((maxOdd - minOdd) / 2 + 1) * (minOdd + maxOdd) / 2;
}
Test
System.out.println(sumOddNumbers(3, 11)); // prints: 35
System.out.println(sumOddNumbers(4, 20)); // prints: 96
This can be done easily with a mathematical formula. But based on your question I presume you want to use a loop so here goes.
An odd number has the low order bit set to 1.
If the number is already odd, resetting that bit has no effect so it is still odd.
But setting that bit for an even number makes it the next higher odd number.
So use the bitwise OR operator.
3 | 1 = 3
4 | 1 = 5
And do the following:
int start = 4;
int end = 20;
int sum = 0;
for (int i = (start | 1); i <= end; i += 2) {
sum += i;
}
System.out.println(sum);
If you want to use streams in Java 8+ you can do it this way.
int sum = IntStream.rangeClosed(start, end).filter(i -> i & 1 == 1).sum();
And the formula I was talking about is the following, derived using simple series summation.
For ints, start and end
start |= 1; // ensure start is next odd number
end = (end | 1) - 2;// ensure end is last odd - 2
int sum = ((start + end) * ((end - start) / 2 + 1)) / 2;
If the two numbers are natural numbers, you can apply the formula:
Sum of odd natural numbers from m to n = sum of natural odd numbers up to n - sum of natural odd numbers up to m
= (n/2)^2 - (m/2)^2
where n is an even number or the next even number in case it is an odd number
In the program:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("#1: ");
int num1 = Math.abs(s.nextInt());
System.out.print("#2: ");
int num2 = Math.abs(s.nextInt());
System.out.println("Sum of natural odd numbers from "+num1+" to "+num2+" = "+sumNaturalOddOfRange(num1,num2));
num1 = 5;
num2 = 15;
System.out.println("Sum of natural odd numbers from "+num1+" to "+num2+" = "+sumNaturalOddOfRange(num1,num2));
num1 = 5;
num2 = 16;
System.out.println("Sum of natural odd numbers from "+num1+" to "+num2+" = "+sumNaturalOddOfRange(num1,num2));
num1 = 6;
num2 = 15;
System.out.println("Sum of natural odd numbers from "+num1+" to "+num2+" = "+sumNaturalOddOfRange(num1,num2));
}
static int sumNaturalOddOfRange(int num1, int num2) {
if(num2%2==1)
num2++;
return (int)(Math.pow(num2 / 2, 2) - Math.pow(num1 / 2, 2));
}
}
A sample run:
#1: 10
#2: 20
Sum of natural odd numbers from 10 to 20 = 75
Sum of natural odd numbers from 5 to 15 = 60
Sum of natural odd numbers from 5 to 16 = 60
Sum of natural odd numbers from 6 to 15 = 55
**Here is the answer**
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.print("#1: ");
int num1 = s.nextInt();
System.out.print("#2: ");
int num2 = s.nextInt();
int sum = 0;
if (num1%2==0) {
num1++;
}
for (int i = num1; i <= num2; i++) {
sum +=i;
}
System.out.print(sum);
}

I need to display prime numbers between two numbers

I have a school assignment where I need to prompt the user for two numbers and display all the prime numbers in between I can't figure it out for the life of me. Here is my code, all it does is end as soon as I enter the two numbers.
public static void pg150Exersize1B() {
Scanner input = new Scanner(System.in);
int num, counter, num2;
System.out.println("Enter your low number");
num = input.nextInt();
System.out.println("Enter your high number");
num2 = input.nextInt();
counter = num;
while (num != num2) {
counter++;
if (num % counter == 0) {
if (counter == num) {
System.out.println(counter);
num++;
} else {
num++;
}
} else{
num++;
}
}
}
The first step in solving any coding-problem would be to transform the textual task into a basic code structure.
As an example, we can translate the task into the following main-routine:
display all prime numbers between two given numbers
could be translated to
print all numbers in a given range, if they are prime
which can be translated to the following pseudocode:
for i in [lower,upper]
if isPrime(i)
print(i)
This pseudocode can be translated pretty simple into the correct java-code.
Now we're missing one additional piece: the function isPrime(...). So let's apply the same pattern:
check, if a given number is prime
add some mathematical knowledge:
a number n is prime, if it's not divisible by any number in range [2,n)
and we wind up with
check, if a given number n isn't divisible by any number in the range [2,n)
I'll leave figuring the rest out to you.
Thanks for being honest and making clear this is homework.

Java loops and zero divisor

I am creating a program that will calculate two numbers. My issue is 0 will be an illegal input to the program but instead of asking again for two numbers.
The program continues to run without giving an error, or giving any answer when ZERO is imputed, it's suppose to ask the user to input two different numbers again.
I've done all the code and it mostly works and there is no visible error.
import java.util.*;
import java.util.Scanner.*;
public class MinilabLoopLogic
{
public static void main(String[ ] args)
{
int num1, num2, divisor, total;
Scanner kb = new Scanner(System.in); //you do it!
System.out.print("Please enter 2 integers (separated by spaces): ");
num1 = kb.nextInt();
num2 = kb.nextInt();
System.out.println("\n\nThis program will generate numbers BETWEEN "+ num1 + " " + num2);
System.out.println("\nPlease enter the integer your output should be divisible by: ");
divisor = kb.nextInt();
while (divisor == 0)
{
divisor = kb.nextInt();
}
System.out.println("\n\n----------------------------------------");
//Be able to handle 1st number smaller
// OR 2nd number smalle
//Use the modulus operator to check if a number is divisible
if (num1 < num2)
{
for (total = num1+1; total < num2; total++ )
{
if (total % divisor == 0)
{
System.out.println(total);
}
}
}
else
{
for (total = num1 - 1; total > num2; total--)
{
if (total % divisor == 0)
{
System.out.println(total);
}
}
}
}
}//end main()
Your problem lies in your while loop looking for the divisor:
System.out.println("\nPlease enter the integer your output should be divisible by: ");
divisor = kb.nextInt(); // gets your divisor
while (divisor == 0) //if it is illegal, e.g. 0
{
divisor = kb.nextInt(); // waits for more divisor input
}
You should output a string to tell the user what the problem is. say:
divisor = kb.nextInt(); // gets your divisor
while (divisor == 0) //if it is illegal, e.g. 0
{
System.out.println("\nYou can't divide by 0. Try again!: ");
divisor = kb.nextInt(); // waits for more divisor input
}
Also, if you want them to have to re-enter the num1 and num2 then scanner input has to happen in that while loop.
You added the following in an edit:
The program continues to run without giving an error, or giving any answer when ZERO is imputed, it's suppose to ask the user to input two different numbers again.
That is because you just loop back to get another value when a zero is entered, without writing any new prompt text.
It also only gets a new divisor number, not "two different numbers". If you looped back to before "Please enter 2 integers", it'd actually end up prompting for all 3 numbers again.

How do I return 0 if random number will be negative?

The num1, num2, are bounds of the random number, but I want the result to be 0 if num1 is greater than num2.
int num1 = 5
int num2 = 1
int num3 = 10
Random rand = new Random();
double num = 0;
for (int i = 0; i < num3; i++) {
int randNum = rand.nextInt((num2 - num1) + 1) + num1;
num = num + randNum;
// Adds the random number generated to num until it reaches the
// max amount of numbers generated.
}
num = num / num3;
if (num3 < 1 || num2 < num1){
return 0;
} else {
return num;
}
I thought the last if statement would work, but it keeps giving me an error that says the random number cannot be negative.
If the solution could be a little simple as I am only just starting on Java
Any help would be much appreciated, thanks
Because (according to Javadocs)
public int nextInt(int n)
Parameters: n - the bound on the random number to be returned. Must be
positive. Returns: the next pseudorandom, uniformly distributed int
value between 0 (inclusive) and n (exclusive) from this random number
generator's sequence Throws: IllegalArgumentException - if n is not
positive
Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive)
So you need to check first that (num2 - num1) > 0
You can simplify it by doing the num1 to num2 comparison first, and not messing around with any math if num1 is greater.
move this to the top:
if (num3 < 1 || num2 < num1){
return 0;
Looking at your code again it appears as num3 increases, your result approaches (num2-num1)/2. Just wondering what your are doing here?
You are not using num1 and num2 as bounds. If should be be
randNum = rand.nextInt(num1, num2);
also your conditional
if(num1 > num2)
should be first in your method.

Issue with Java simple arithmetic

I'm working on a small Java program, and somewhere, my calculations are going awry. My code is as follows:
import java.io.*;
import java.util.*;
import java.text.*;
public class NumManip
{
public static void main(String args[])
{
Scanner numGetter = new Scanner(System.in);
final int MULT_1 = 9;
final int MULT_2 = 12345679;
final int MULT_3 = 1000;
int poorHatedNumber;
System.out.print("Enter a digit between 1 and 9 that you dislike: ");
poorHatedNumber = numGetter.nextInt();
int num1 = poorHatedNumber * MULT_1, num2 = num1 * MULT_2;
long num3 = num2 * MULT_3;
System.out.println();
System.out.println(" " + poorHatedNumber);
System.out.println(" " + "x" + MULT_1);
System.out.println(" __");
System.out.println(" " + num1);
System.out.println(" x" + MULT_2);
System.out.println(" __");
System.out.println(" " + num2);
System.out.println(" x" + MULT_3);
System.out.println("____________");
System.out.println(num3);
}
}
I've tryed printing num1, num2, and num3 on the screen to see what the problem is, and num1 is right, num2 is right, and num3 is freaky. My input is 9, and the first calculation multiplies by 9 and gets 81. Then it multiplies that by 12345679 and gets 999999999, and then it multiplies by 1000 and gets -727380968. What's wrong with that last step? I'm REALLY new to Java, and I don't get the issue.
999999999 * 12345679 = 1.234567898765432e+16 which is way bigger than the maximum value of an int which is 2,147,483,647
Since Java uses 2-compliment method to store int number (meaning that the leftmost bit is turned on when the number is negative) this calculation "overflows" (carry-over) to the that bit which results in a negative result.
For calculation with such big numbers you should use BigDecimal
As num2 and num1 both are integer, so integer multiplication happened and it exceeds the max of integer value.
long num3 = (long)num2 * MULT_3;
I think you're resulting in a number bigger than the datatype can handle, and as the datatype is signed, it wraps around into the negatives.
Don't worry, it's not such a silly mistake really. The whole "numbers are usually a fixed size"-deal confuses just about everyone initially. Now that you know what's up, here's something even weirder. It's not really an answer to your question, but now that you've just seen an example of "bad overflow", you might find this interesting.
Consider an odd number x. There is a number y such that x * y == 1. That number y is called the modular multiplicative inverse, and it can easily be computed (see Hacker's Delight, exact division by a constant). This may seem really counter intuitive, because it essentially allows a weird kind "division" that only works if the number was an exact multiple of the divisor, and in general it allows you to "undo" a multiplication by an odd number. For example, if you have a = 3 * b, then b = -1431655765 * a - regardless of any overflow in either multiplication, so overflow need not be "destructive".

Categories