Need to find position of maximum of three numbers - java

I am trying to find the position of the maximum of three numbers that the user inputs. I do not know how to find the position of this but I can find max of the numbers.
Here is the task:
Here is the method named getNumberOfMaxParam that takes three integer numbers and returns the position of the first maximum in the order of the method parameters.
UPDATE: I am trying to compare the int a.b.c but I get This method must return a result of type int error
Code:
import java.util.Scanner;
class App {
public static int getNumberOfMaxParam(int a, int b, int c) {
int firstMax = Math.max(a, b);
int highMax = Math.max(firstMax, c);
if (a == highMax) {
System.out.println("1");
} else if (b == highMax) {
System.out.println("2");
} else if (c == highMax) {
System.out.println("3");
} else {
return highMax;
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
final int a = scanner.nextInt();
final int b = scanner.nextInt();
final int c = scanner.nextInt();
System.out.print(getNumberOfMaxParam(a, b, c));
}
}
Now how do I find the position?

You can do this with the Stream api. You simply pass an array of values in the order you want. Then create an IntStream of the values and find the max. Then create an IntStream of the indices and find the first value in the array to see if it matches max, and return the index.
private static int getIndexOfMax(int... values) {
int max = IntStream.of(values).max().orElseThrow(IllegalStateException::new);
return IntStream.range(0, values.length)
.filter(index -> values[index] == max)
.findFirst().orElseThrow(IllegalStateException::new);
}
int index = getIndexOfMax(1, 2, 3);
assert index == 2;

**PS. It could be controversial if you supply same value for multiple inputs.**
public static int getNumberOfMaxParam(int a, int b, int c) {
int firstMax = Math.max(a, b);
int highMax = Math.max(firstMax, c);
return (highMax == a ? 1 : (highMax == b ? 2 : 3 );
}

Related

count no. of set bits of each number in a range and then sum it up

Count no. of set bits in each number in a range and then display the total sum.
Input-
2
1 1
10 15
Output-
1
17
I am getting time limit exceeded problem also I am not getting any output for the problem. Could anyone tell me the error in my code.Thank you
import java.util.*;
public class counBitsInRange {
public static void main(String args[]) {
Scanner sc = new Scanner(System.in);
int Q = sc.nextInt();
int[] res = new int[Q];
for(int i=0;i<Q;i++)
{
int a = sc.nextInt();
int b = sc.nextInt();
res[i] = countbits(a,b);
}
for(int j=0;j<res.length;j++)
{
System.out.println(res[j]);
}
}
private static int countbits(int a,int b)
{
int count=0;
for(int i=a;i<=b;i++)
{
while(i>0)
{
count+=(i&1);
i=i>>1;
}
}
return count;
}
}
Integer class has the method bitCount returning the number of one-bits, rewrite your method countbits using the java library class method like below:
private static int countbits(int a,int b)
{
int count=0;
for(int i=a;i<=b;i++)
{
count += Integer.bitCount(i);
}
return count;
}
Here is the bug: Both the for loop and the body inside while loop changes the i value, which sometimes makes the loop go forever. Keep them separate.
private static int countbits(int a,int b)
{
int count=0;
for(int j=a;j<=b;j++)
{
int i = j;
while(i>0)
{
count+=(i&1);
i=i>>1;
}
}
return count;
}
This is a problem:
for(int i=a;i<=b;i++)
No matter what you put inside that loop, it will not scale well to large ranges, and the ranges could be two billion long.
An alternative algorithm is:
Use a clever trick to count the total number of set bits in the range [0, b + 1] (exclusive of the endpoint)
Use the trick again to count the total number of set bits in the range [0, a]
The difference between them is the total number of set bits in the range [a, b + 1]
For example, in code:
static long countSetBitsInRange(int a, int b)
{
return countSetBitsUpTo(b + 1) - countSetBitsUpTo(a);
}
static long countSetBitsUpTo(int n)
{
int power = 1;
long cnt = n >> 1;
while ((1 << power) <= n)
{
long totalPairs = n >> power;
cnt += (totalPairs >> 1) << power;
if ((totalPairs & 1) != 0)
cnt += n & ((1 << power) - 1);
power++;
}
return cnt;
}
Based on a trick from Count total set bits in all numbers from 1 to n.

Recursion to find last index of common digit between two ints

I'm trying to implement a method that finds the highest index of common digit between two ints like so:
a = 2224 , b = 4222 the result would be index = 2, which means the index is in reverse. I managed to find the first common digit, but I'm having trouble finding the last common digit. This the method to find the first common digit:
private static int getLowestIndexWithSameDigit(int a, int b) {
if (a < 0 || b < 0)
throw new IllegalArgumentException("Ambos os argumentos devem ser positivos: " + a + " " + b);
else {
if (a % 10 == b % 10) {
return indice;
} else if (a / 10 != 0 && b / 10 != 0) {
indice++;
return getLowestIndexWithSameDigit(a / 10, b / 10);
} else {
return -1;
}
}
}
And the method to initialize index as 0 everytime getLowestIndexWithSameDigit is used:
private static void test_getLowestIndexWithSameDigit(int a, int b) {
try {
System.out.print("getLowestIndexWithSameDigit (" + a + ", " + b + ") = ");
indice = 0;
int res = getLowestIndexWithSameDigit(a, b);
System.out.println(res);
} catch (IllegalArgumentException e) {
System.out.println("Erro: " + e.getMessage());
}
}
I was trying to adapt this method in some way, but I don't think it's adaptable to find the last common digit. Any help is appreciated.
It might be simpler to convert the ints to Strings:
//you can overload method to support other primitives
private static int getHighestIndexWithSameDigit(int a, int b) {
String aS = String.valueOf(a);
String bS = String.valueOf(b);
return getHighestIndexWithSameDigit(aS, bS);
}
//helper method to set strat index
private static int getHighestIndexWithSameDigit(String aS, String bS) {
return getHighestIndexWithSameDigit(aS, bS, 1);
}
//recursively check first letter. First index is 1 - indicates first char from left
private static int getHighestIndexWithSameDigit(String aS, String bS, int index) {
int aLength = aS.length(), bLength = bS.length();
if((aLength == 0) || (bLength == 0)) { return -1;}
if(aS.charAt(0) == bS.charAt(0)) { return index; }
//remove first letters, update index
return getHighestIndexWithSameDigit(aS.substring(1, aLength),
bS.substring(1, bLength), ++index);
}
Test by System.out.println(getHighestIndexWithSameDigit(2224 , 4222) );
Edit:
The code posted assumed that the first index is 1 (1 base), where index of value 1 indicates the first digit from left.
If you meant to use 0 base index, counting from right two of the method should change slightly :
//helper method to set start index.
private static int getHighestIndexWithSameDigit(String aS, String bS) {
return getHighestIndexWithSameDigit(aS, bS, aS.length()-1);
}
//recursively check first letter. Index 0 - indicates last char
private static int getHighestIndexWithSameDigit(String aS, String bS, int index) {
System.out.println(aS +" "+ bS);
int aLength = aS.length(), bLength = bS.length();
if((aLength == 0) || (bLength == 0)) { return -1;}
if(aS.charAt(0) == bS.charAt(0)) { return index; }
return getHighestIndexWithSameDigit(aS.substring(1, aLength),
bS.substring(1, bLength), --index);
}
Getting the lowest or the highest should only be a matter of when you stop the loop, no?
The slightly rewritten version of your code below did the trick for me at least.
private static int getDatIndex(int a, int b, boolean getDatLow) {
int indice = -1;
int index = 0;
while (a/10 != 0 && b/10 != 0) {
if (a % 10 == b % 10) {
indice = index;
// If you want the lowest common digit index: stop the loop.
if (getDatLow) {
break;
}
}
a = a/10;
b = b/10;
index++;
}
return indice;
}

Using a comparator in Java

I am Having a tuple <Rank[0] , Rank[1]> and wanted to sort this in increasing order Rank[0] can be considered as first digit and Rank[2] as a second digit.
Here is my function:
Arrays.sort(S,new Comparator<Tuples>() {
public int compare(Tuples a, Tuples b) {
// TODO Auto-generated method stub
return (a.Rank[0]==b.Rank[0]) ? ((a.Rank[1]<b.Rank[1]) ? 1:0) :((a.Rank[0]<b.Rank[0])? 1:0);
}
});
The above thing is not giving be Sorted Array while it's C equivalent works i.e
int cmp(struct suffix a, struct suffix b)
{
return (a.rank[0] == b.rank[0])? (a.rank[1] < b.rank[1] ?1: 0):
(a.rank[0] < b.rank[0] ?1: 0);
}
Why My java Sorting is not working. Please Help
static class Tuples{
int[] Rank = new int[2];
}
What about something like this:
public int compare(Tuples a, Tuples b) {
int index = a.Rank[0] == b.Rank[0] ? 1: 0;
return a.Rank[index] - b.Rank[index];
}
A little easier to read in my opinion.
According to the documentation of the Comparator interface, the compare method must return 1, 0 or -1, that are:
0 = the objects are equal
-1 (or any negative integer) = the
object a is less than object b
1 (or any positive integer) = the
object a is greater than object b
So your method must be something like below:
public int compare(Tuples a, Tuples b) {
if(a.Rank[0]==b.Rank[0]){
if(a.Rank[1]==b.Rank[1]){ // a == b
return 0;
}else if(a.Rank[1]<b.Rank[1]){ // a < b
return -1;
}else{ // a > b
return 1;
}
}else{ // a != b
if(a.Rank[0]<b.Rank[0]){ // a < b
return -1;
}else{ //a > b
return 1;
}
}
}
Or in short (and ugly way) it would be like this:
public int compare(Tuples a, Tuples b) {
return (a.Rank[0]==b.Rank[0])?((a.Rank[1]==b.Rank[1])?0:((a.Rank[1]<b.Rank[1])?-1:1)):((a.Rank[0]<b.Rank[0])?-1:1);
}
As SqueezyMo stated in his answer case less and negative integer is missing. One can utilize subtraction to get compact code.
Arrays.sort(arr, new Comparator<Tuples>() {
public int compare(Tuples a, Tuples b) {
return a.Rank[0] == b.Rank[0] ? a.Rank[1] - b.Rank[1] : a.Rank[0] - b.Rank[0];
}
});
Naturally everything can be done using ternary operators, it drives maintainers crazy.
public static void main(String[] args) {
Tuples a = new Tuples();
a.Rank = new int[]{1, 2};
Tuples b = new Tuples();
b.Rank = new int[]{0, 1};
Tuples c = new Tuples();
c.Rank = new int[]{1, 3};
Tuples[] arr = {a, b, c};
Arrays.sort(arr, new Comparator<Tuples>() {
#Override
public int compare(Tuples a, Tuples b) {
return a.Rank[0] == b.Rank[0]
? a.Rank[1] == b.Rank[1]
? 0 : a.Rank[1] < b.Rank[1]
? -1 : 1 : a.Rank[0] > b.Rank[0]
? 1 : -1;
}
});
for (int i = 0; i < 3; i++) {
System.out.println(arr[i].Rank[0] + ":" + arr[i].Rank[1]);
}
}
static class Tuples {
public int[] Rank;
}

Java(BlueJ) Adding up all numbers between two integers

I'm creating a method to add up all numbers between two integers.
I currently have:
/**
* Add up all numbers between two integers
*/
public void Sum(int a,int b)
{
int result = 0;
while (a <=b)
{
result+=a;
a++;
}
System.out.println("The sum of all numbers is "+result);
}
This only works if a <= b. How do i also do it for if a > b ?
I have to use a while loop
The easiest way to do this is to reuse what you already have. Let's rename your method first:
public void sumMonotonic(int a, int b)
{
int result = 0;
while (a <=b) {
result+=a;
a++;
}
System.out.println("The sum of all numbers is "+result);
}
So sumMonotonic() only works if its first argument is no bigger than its second. But now we can define sum() like this:
public void sum(int a, int b)
{
if (a<=b)
sumMonotonic(a,b);
else
sumMonotonic(b,a);
}
This just invokes the other function with the arguments in the appropriate order.
Actually there's one other oddity that we might fix. It seems a little unidiomatic to have a sumMonotonic() method that does the printing. It would be better if it returned the sum, and if the sum() method did the printing. So we'd refactor it like this:
public int sumMonotonic(int a, int b)
{
int result = 0;
while (a <=b) {
result+=a;
a++;
}
return result;
}
public void sum(int a, int b)
{
int result;
if (a<=b)
result = sumMonotonic(a,b);
else
result = sumMonotonic(b,a);
System.out.println("The sum of all numbers is "+result);
}
public void Sum(int a,int b)
{
int result = 0;
if(a>b) //swap them
{
result=a;
a=b;
b=result;
result=0;
}
while (a <=b) {
result+=a;
a++;
}
System.out.println("The sum of all numbers is "+result);
}

Codility: Condition in comfort

While conducting the examination this was one of the task (which I could not solve):
They say a number A "comfort" to another number B if, when you convert both numbers to binary, all positions in B where there is a number 1 must be another 1 in the same position in A.
example:
B = 101
A = 111
In this case, the number A "comfort" to B, however
B = 101
A = 011
The Comfort condition is not met.
They gave me 3 unsigned numbers with 30 bits A, B and C, between 0 and 2 ^ 30. I must determine the amount of numbers in that range that meet the condition of "comfort" for at least one of those numbers.
expected worst-case time complexity is O (log (A) + log (B) + log (C));
I use the following code and it takes too long, most of all because it checks the binary number as an array and compare every cell. I assume there must be some way to make it faster (some math operation or idk :-( ).
public class Main {
public static void main(String[] args)
{
sol(905,5000,11111111); //I used any numbers
}
public static void sol(int A, int B, int C)
{
int min=Math.min(A, Math.min(B, C));
int max=(int) Math.pow(2, 30);
String binA=Integer.toBinaryString(A); binA=fillBin(binA);
String binB=Integer.toBinaryString(B); binB=fillBin(binB);
String binC=Integer.toBinaryString(C); binC=fillBin(binC);
String binMax=Integer.toBinaryString(max);
int conta=0;
for(int i=min;i<=max;i++)
{
String binT = Integer.toBinaryString(i);binT=fillBin(binT);
boolean failA=false;
boolean failB=false;
boolean failC=false;
for(int j=0;j<binT.length();j++)
{
if((binA.length()<j)&&(binB.length()<j)&&(binC.length()<j))
{
break;
}
if((!failA)||(!failB)||(!failC))
{
if((binA.length()<j)&&(binA.charAt(j)=='1') && (binT.charAt(j)!='1'))
{
failA=true;
}
if((binB.length()<j)&&(binB.charAt(j)=='1') && (binT.charAt(j)!='1'))
{
failB=true;
}
if((binC.length()<j)&&(binC.charAt(j)=='1') && (binT.charAt(j)!='1'))
{
failC=true;
}
}
else
{
break;
}
}
if((!failA)||(!failB)||(!failC))
{
conta++;
}
}
}
private static String fillBin(String binA)
{
String S=binA;
for(int i=0;i<(31-binA.length());i++)
{
S="0"+S;
}
return S;
}
}
If any of you already done this task before and see that there are some missing data , let me know , excuse my English (not my native language).
thank you very much
EDIT: This is the code with #Eran 's help:
public class BinaryTask
{
public void test(int A, int B, int C)
{
long timeStart, timeEnd;
timeStart = System.currentTimeMillis();
//Bunch of variables
String binaryA = Integer.toBinaryString(A); int zerosA=0;
String binaryB = Integer.toBinaryString(B); int zerosB=0;
String binaryC = Integer.toBinaryString(C); int zerosC=0;
String binaryAB =""; int zerosAB=0;
String binaryBC =""; int zerosBC=0;
String binaryAC =""; int zerosAC=0;
String binaryABC=""; int zerosABC=0;
//The long for the for
int Max = Math.max(binaryA.length(), Math.max(binaryB.length(), binaryC.length()));
//Creating: A|B, B|C, A|B and A|B|C that meet the confort condition
for(int i=0;i<Max;i++)
{
//Creating A|B
if((binaryA.length()>i)&&(binaryB.length()>i))
{
if((binaryA.charAt(i)=='1')||(binaryB.charAt(i)=='1'))
{
binaryAB="1"+binaryAB;
}
else //I also count this zero so i dont have the do another for later
{
binaryAB="0"+binaryAB; zerosAB++;
}
}
//Creating B|C
if((binaryB.length()>i)&&(binaryC.length()>i))
{
if((binaryB.charAt(i)=='1')||(binaryC.charAt(i)=='1'))
{
binaryBC="1"+binaryBC;
}else{binaryBC="0"+binaryBC; zerosBC++;}
}
//Creating A|C
if((binaryA.length()>i)&&(binaryC.length()>i))
{
if((binaryA.charAt(i)=='1')||(binaryC.charAt(i)=='1'))
{
binaryAC="1"+binaryAC;
}else{binaryAC="0"+binaryAC;zerosAC++;}
}
//Creating A|B|C
if((binaryA.length()>i)&&(binaryB.length()>i)&&(binaryC.length()>i))
{
if((binaryA.charAt(i)=='1')||(binaryB.charAt(i)=='1')||(binaryC.charAt(i)=='1'))
{
binaryABC="1"+binaryABC;
}else{binaryABC="0"+binaryABC; zerosABC++;}
}
}
//Counting the other amount of zeros
zerosA = countZeros(binaryA);
zerosB = countZeros(binaryB);
zerosC = countZeros(binaryC);
long confortA = (long) Math.pow(2, zerosA);
long confortB = (long) Math.pow(2, zerosB);
long confortC = (long) Math.pow(2, zerosC);
long confortAB = (long) Math.pow(2, zerosAB);
long confortBC = (long) Math.pow(2, zerosBC);
long confortAC = (long) Math.pow(2, zerosAC);
long confortABC = (long) Math.pow(2, zerosABC);
long totalConfort = confortA + confortB + confortC - confortAB - confortBC - confortAC + confortABC;
timeEnd = System.currentTimeMillis();
System.out.println("Total of confort for A "+A+" B "+B+" C "+C+" is " +totalConfort);
System.out.println("the task has taken "+ ( timeEnd - timeStart ) +" milliseconds");
}
private int countZeros(String binary)
{
int count=0;
for(int i=0;i<binary.length();i++)
{
if(binary.charAt(i)=='0')
{count++;}
}
return count;
}
}
To make a test, i did this:
public static void main(String[] args)
{
BinaryTask T = new BinaryTask();
int A = (int) Math.pow(2, 10);
int B = (int) Math.pow(2, 15);
int C = (int) Math.pow(2, 30);
T.test(A, B, C);
}
And this was the output:
Total of confort for A 1024 B 32768 C 1073741824 is 1073739776
the task has taken 1 milliseconds
Building on #alain's answer, comf(A) = 2^(number of zero bits in A) is the number of comforting numbers for A.
You need the number of comforting numbers for either A, B or C.
That's comf(A)+comf(B)+comf(C)-comf(A and B)-comf(B and C)-comf(A and C)+comf(A and B and C).
where comf(A and B) denotes the number of comforting numbers for both A and B.
and comf(A and B and C) denotes the number of comforting numbers for all A, B and C.
We know how to calculate comf(A), comf(B) and comf(C).
comf(A and B) = 2^(number of zero bits in A|B), since a number X comforts both A and B if and only if it has ones in all the bits for which either A or B has ones.
Similarly, comf(A and B and C) = 2^(number of zero bits in A|B|C).
Since all the calculations are bit operations on A,B and C, the running time is the lengths in bits of A, B and C, which is O (log (A) + log (B) + log (C)).
The condition for 'A comfort to B' is
B & A == B
You could just count the number n of 0 bits in B, and then you have 2^n or Math.pow(2, n) possibilities to build a 'comforting' number A.
Unfortunately, this doesn't work for 'comforting to at least one of three numbers', but it could be a starting point.
Are you sure the output Total of confort for A 1024 B 32768 C 1073741824 is 1073739776 is correct ?
I do agree with bitwise operation, with that I am getting different retult btw.
public static int solution(int A,int B,int C){
int total = 0;
int totalA=0,totalB=0,totalC=0;
//int max = Math.max(Math.max(A, B), C);
double limit = Math.pow(2,30);
for(int i=0;i<=limit;i++){
int no = A & i;
if(no == A){
total++;
totalA++;
//continue;
}
no = B & i;
if(no == B){
total++;
totalB++;
//continue;
}
no = C & i;
if(no == C){
total++;
totalC++;
//continue;
}
}
System.out.println("totalA: " + totalA + " totalB: " + totalB + " totalC: " + totalC);
total = totalA + totalB + totalC;
return total;
}
It gives me totalA: 536870912 totalB: 536870912 totalC: 1
1073741825

Categories

Resources