I was asked a question regarding to find the common divisors between two numbers. I was able to figure out the logical approach using " Sieve of Eratosthenes " and I was dry running my code. But my code was giving an unexpected output in the sense that it was able to figure out the no. of common divisors between two numbers. For the 1st input but for the rest it is somehow continuing with the previous value of "inner loop j" at which it was stopped for the 1st test case ; for other test cases.
Logical approach --> if a prime no. is a factor of given two nos. then we'll check that for every multiple of the prime no.(using array of primes[] and converting the value of multiple of primes[]=0 ) whether some of them are multiples of both the numbers or not and if yes then we'll increase the value by 1.
My question is - am using BufferedReader in the wrong way or there is some error in the code itself
Question Link-> https://www.geeksforgeeks.org/common-divisors-of-two-numbers/
Input Format
The first line of the input contains a single integer
T
denoting the number of test cases.
The description of
T
test cases follows.
The first line of each test case contains two integers
A
and
B
.
Output Format
For each test case, output the number of common divisors between the given pair on a seperate line.
Constraints
1
≤
T
≤
10
^2
1
≤
A
,
B
≤
10
^9
Example
Input
3
100000 100000
12 24
747794 238336
Expected Output
36
6
2
try{
long primes[]=new long[1000005];
for(int i=2;i<=100000;i++){
primes[i]=1;
}
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int t = Integer.parseInt(br.readLine());
for(int k=0;k<t;k++){
String s = br.readLine();
String s2[] = s.split(" ");
long a = Long.parseLong(s2[0]);
long b = Long.parseLong(s2[1]);
long min = Math.min(a,b);
long max= Math.max(a,b);
System.out.println("Value of max = "+max);
System.out.println("Value of min = "+min);
long count=1;
for(int i=2;i*i<=min;i++){
if(primes[i]==1){
System.out.println("Value of i = "+i);
if(max%i==0 && min%i==0){
count++;
}
for(int j=i;j*i<=min;j++){
if(primes[i*j]==1){
primes[i*j]=0;
System.out.println("Value of j = "+j);
if((max%(i*j)==0) && (min%(i*j)==0)){
count++;
}
}
}
}
}
System.out.println(count);
}
}catch(Exception e){
return;
}
My output for different values of input -
Value of max = 24
Value of min = 12
Value of i = 2
Value of j = 2
Value of j = 3
Value of j = 4
Value of j = 5
Value of j = 6 <------
Value of i = 3
Value of j = 3
6
Value of max = 40
Value of min = 20
Value of i = 2
Value of j = 7 <------
Value of j = 8
Value of j = 9
Value of j = 10
Value of i = 3
Value of j = 5
3
Value of max = 100
Value of min = 20
Value of i = 2
Value of i = 3
2
How can I figure out the mistake? I am new in using BufferedReader?
Your algorithm is wrong. BufferedReader is working fine.
Take a simple example, say a=131, b=262, your program will return 1 as an answer but the correct answer would be 2 (1 & 131). Why is this happening?
Simply because your program misses to check for all those primes which are > sqrt(min) and are factors of both numbers.
To rectify this you need to check for the divisibility with those primes in a linear manner at the end as below but this will be inefficient.
for (int i=2; i<=min; i++)
if (primes[i] == 1 && (max%(i)==0) && (min%(i)==0))
++count;
Also, for the correct working of above, you need to mark the i-th number as composite by primes[i]=0 during each i-th iteration.
Also, initialization of primes array should be done during each test case as in the previous testcase, the primes array would have been modified.
primes[] = new long[1000005];
for(int i=2; i<=100000; i++)
primes[i] = 1;
For an efficient approach, please refer to the GFG article you shared.
Related
Considering two variables:
"n" is any arbitrary value.
"i" is the number of times a value is increased in a sum before it reaches the value of "n".
So for instance if the value n = 344 is chosen, then i = 26 because:
26 + 25 + 24 + ... + 3 + 2 + 1 = 351
26 is how many times the variable "i" gets added together in a descending order before it either is equal to n = 344 or the first time it surpasses.
public class Trstuff{
public static void main (String [] arg) {
int n = 4;
int i = computeIndex(n);
System.out.print(i);
}
public static int computeIndex(int n) {
int i = 1;
int sum = 0;
for(i = 1; sum <= n; i++) {
sum = sum + i;
}
return i;
}
}
My goal is to choose any "n" value and then have the program return the variable "i" to me.
As my program stands, I thought it should be correct, but somehow it's not. Here is the example with n = 4.
The result should be that "i = 3" because:
1 + 2 = 3
1 + 2 + 3 = 6
So the ascending value of "i" in the loop is added 3 times before the loop supposedly should stop because of the expression "sum <= n" in the loop.
However, when I run the program it returns the value 4 instead. I simply cannot figure out what is wrong and why my program gives me 4 instead of the correct answer, 3?
Read the for loop as follows:
for every value of i while sum smaller or equal to n, add i to sum and increment i
The last part of the line and increment i is executed after the sum of sum + i, but before the next check which checks if sum is smaller or equal to n, with as result that i always is one larger than expected.
The solution could be to use a different exit (different solutions exist):
public static int computeIndex(int n) {
int i = 1;
int sum = 0;
while true {
sum = sum + i;
if sum<n {
i++;
} else break;
}
return i;
}
the sum of p consecutive integers starting at 1 is p*(p+1)/2
so basically you need to solve x^2+x-2*n = 0, with solution
x = 0.5*(sqrt(1+8n)-1)
When given 4 numbers, how do i find which 3 numbers out of the 4 will give the greatest sum.
So if given 3 2 5 5, i want java to sum 3 5 5 for a total of 13
I have been searching for about 20 minutes and all i find is how the find the highest number of the 4 numbers. I know i absolutely can just write 16 lines of code comparing the 16 different combinations but i was hoping someone could point me in a faster direction.
First find the smallest number.
So for 3 2 5 5 it would be 2. Make sure you store this.
Thus, the numbers to sum are 3, 5 and 5
To get the total sum you need to add all the numbers together so:
3 + 2 + 5 + 5 = 15
And then minus the smallest number from the sum. So 15-2 which equals 13
First find the greatest of the four numbers and keep it aside.
Then find the greatest of the remaining three numbers and keep it aside.
Then find the greatest of the remaining two numbers and keep it aside.
Then sum up the numbers kept aside and display the result.
public static void main(String args[]) {
int[] vals = new int[4];
vals[0] = 3;
vals[1] = 2;
vals[2] = 5;
vals[3] = 5;
int result = sum4(vals);
System.out.println("Sum of x+y = " + result);
}
private static int sum4(int[] nums)
{
int retVal = 0;
int lowest = Integer.MAX_VALUE;
for (int i=0; i<nums.length; i++)
{
if (nums[i] < lowest)
lowest = nums[i];
retVal += nums[i];
}
retVal -= lowest;
return retVal;
}
I've been working on a few array examples. with some success along alone the way. I've been working on this code for the pass few days and just cant understand the purpose of this increment in the loop body. it usually makes since when it is isolated but this time i have no idea what it does.
Count the occurrences of integers between 1 and 10
Scanner input = new Scanner(System.in);
int[] count = new int[10];
System.out.println("Enter the integers between 1 and 10: ");
// Read all numbers
// 2 5 6 5 4 3 9 7 2 0
for (int i = 0; i < count.length; i++)
{
int number = input.nextInt();
count[number]++; //this is the one that perplexes me the most
}
//Display result
for (int i = 0; i < 10; i++)
{
if (count[i] > 0)
{
System.out.println(i + " occurs " + count[i]
+ ((count[i] == 1) ? " time" : " times"));
}
}
count[number]++; //this is the one that perplexes me the most
It increments the value in the array count at index number. Perhaps, splitting it may help understand:
int tmp = count[number];
tmp = tmp + 1;
count[number] = tmp;
i.e. The value of count[number] will be incremented after the execution of the the statement count[number]++;.
Also a note on how post-increment works.
If it were used as:
int value = count[number]++;
then value will have the old value at count[number] and the increment will be done after the execution of the statement.
Hello i am having a tough time trying to write a function that can create an array that holds integers, that equal my simple math problem.
my problem is not adding integers into the array but finding the correct integers that could add up to a math problem.
for example i have a simple math problem like: 10 + 10 = ? we know it equals 20
so i want my array to hold up to ten integers, that when added all together equal 20.
this is what i have been trying in code but not getting the results i want.
while (totalCount != answer
&& count < setCount) {
randomNumber = rand.nextInt((int) answer / 2) + 1;
if(count < setCount) {
sumOfBalloons.add(randomNumber);
totalCount += randomNumber;
count++;
}
if(totalCount > answer) {
count = 0;
totalCount = 0;
sumOfBalloons.clear();
}
}
i am trying to find random numbers that add up to the math problems answer so i can draw them on balloons. problem is i can never get ten numbers to equal the answer in my while loop.
does anyone know some way of doing something like this?
need array to hold 3 - 10 integers that equals my math problems answer.
** update on code thanks to the advice i received i managed to fix my while loop now it looks like this
had to post like this cause my rep is very low. sorry.
while (totalCount != answer) {
randomNumber = rand.nextInt((int) answer / 2) + 1;
if(totalCount + randomNumber > answer) {
randomNumber = rand.nextInt((int) answer - totalCount) + 1;
}
if(count + 1 == setCount) {
randomNumber = answer - totalCount;
}
if(count < setCount) {
sumOfBalloons.add(randomNumber);
totalCount += randomNumber;
count++;
}
if(totalCount > answer
|| totalCount == answer
&& count < setCount
|| totalCount != answer
&& count == setCount) {
count = 0;
totalCount = 0;
sumOfBalloons.clear();
}
}
this is what i got in my console from this code
Total count = 10
Total totalCount = 20
sumOfBalloons 0 = 2
sumOfBalloons 1 = 3
sumOfBalloons 2 = 3
sumOfBalloons 3 = 2
sumOfBalloons 4 = 1
sumOfBalloons 5 = 4
sumOfBalloons 6 = 2
sumOfBalloons 7 = 1
sumOfBalloons 8 = 1
sumOfBalloons 9 = 1
I think there are a few options here re: generating random numbers that sum to 20.
Here's one possible solution:
Create an array of length 4, for example.
Generate random number between 1 and 6 for each of the first 3 indices of your array.
At this point you'll have an array of the form: { 4, 5, 2, _ } (where our 4th element hasn't been chosen yet).
Sum our first 3 elements: 4 + 5 + 2 = 11. Determine 4th element by calculating 20 - current_total (11) = 9.
Set myArray[3] = 9;
A few things to note:
You may need to modify the range of possible random numbers ( 1-6 ) I've given. Consider what happens if the array we generate turns out to be { 2, 1, 2, _ }...then there's no digit that will ensure the elements sum to 20.
Another option is to use an arrayList instead of an array. The benefit to this is that you can keep adding elements to your arrayList until you either hit 20 (then you're done) or go over (in which case you delete the most recent element and begin adding again). You also won't need (or be able) to know the length of your arrayList in advance.
The homework problem is the user enters a number. Then you have to write a program that reverses that order. So if the user enters 7364 you have to write a program that presents 4637 on the next line. I think I've figured out the solution but I'm not sure how to write it.
Since the last number is the first number in reverse order that means that if someone enters 7364 that means i want to get 4637. I have to write a program that multiplies 4 by 1000, 6 by 100, 3 by 10 and 7 by 1 then add those up to get 4637. I'm not not 100% sure how to do it. What's messing me up is how to multiply one number by 1000, the next by 100, the next by 10 and the next by 1 then add those up.
import acm.program.*;
public class ReverseNumber extends ConsoleProgram{
public void run(){
int n = readInt("please enter any positive number: ");
int total = 0;
while ( n > 0){
total = total + n % 10; <----?
n = n * 1000; <----?
}
println("the reverse order is" + total);
}
}
The easiest way to do it using library.
System.out.println(new StringBuilder(String.valueOf(i)).reverse());
Try this:
while( n != 0 )
{
reverse = reverse * 10;
reverse = reverse + n%10;
n = n/10;
}
Logic is to get a single digit in each iteration starting from unit place, until all digits are encountered.
n is the input no.
reverse is the variable where reverse of n is stored after while is finished.
% operator when used with 10, gives you the digit at unit place.
/ operator when used with 10, goves you all the digits except the digit at unit place.
When n = 7364 and reverse = 0
in 1st iteration, loop will look like:
while(7364 != 0) // true
{
reverse = 0 * 10; // reverse = 0
reverse = 0 + 7364%10 // reverse = 4
n = 7364/10 // n = 736
}
in 2nd iteration:
while(736 != 0) // true
{
reverse = 4 * 10; // reverse = 40
reverse = 40 + 736%10 // reverse = 46
n = 736/10 // n = 73
}
in 3rd iteration:
while(73 != 0) // true
{
reverse = 46 * 10; // reverse = 460
reverse = 460 + 73%10 // reverse = 463
n = 73/10 // n = 7
}
in 4th iteration:
while(7 != 0) // true
{
reverse = 463 * 10; // reverse = 4630
reverse = 4630 + 7%10 // reverse = 4637
n = 7/10 // n = 0
}
in 5th iteration:
while(0 != 0) // false and loop ends
{
...
}
and we have reverse = 4637.
Well, to reverse the number the simplest solution would be to convert it to a string get the first letter and append it at the end until you reach the last letter or number in this case. Also, you can do pretty much the same with the multiplication part. Get the numbers one by one as a string convert it back to int then multiply and add.
EDIT: if you cant do it using strings. here is a somewhat mathematical solution.
int num = 123456; // any number than you want to reverse
string revnum = ''; // the reversed number
int temp = 0;
do {
temp= (temp*10)+(num%10);
num = (int)(num/10);
}while(num>0){
revnum = revnum + temp;
}
This should work:
total = 0;
while (n > 0) {
total = total * 10 + n % 10;
n = n / 10;
}
println("the reverse order is " + total);
You don't have to know how many digits there are in the original number, you're iterating through all of them anyway. Here's what happens:
When you get a new digit (n % 10), you multiply the result by 10 and add it to it. This way, you offset the digits in the result.
Then you eliminate the last digit (the one you added in the step before) from the original number by doing n / 10.
Do you have to represent it with an int? A String seems more natural?
If you stick with the int, you need to keep track of the factor to multiply with: which means another variable that you multiply by 10 each iteration.
Convert the Int to String, then put it in a StringBuffer
then use .reverse()
I wouldn't want to add the codes because there are many samples for this.
Like this one.
After that, you could convert it again to String.
public class value{
public static void main(String[] args){
int n=Integer.parseInt(args[0]);
int t=0;
do{
t=n%10;
System.out.print(t);
n=n/10;
}while(n>0);
}
}