I need to write the following method: accepts two integer parameters and returns an integer. If either integer is not a 4 digit number than the method should return the smaller integer. Otherwise, the method should return a four digit integer made up of the smallest digit in the thousands place, hundreds place, tens place and ones place. We cannot turn the integers into Strings, or use lists, or arrays.
For example biggestLoser(6712,1234) returns 1212
For example biggestLoser(19,8918) returns 19
Here's how I've started to write it:
public static int biggestLoser(int a, int b){
if(a<9999 || b<9999){
if(a<b)
return a;
else if(b<a)
return b;
}
int at=a/1000;
int ah=a%1000/100;
int an=a%100/10;
int ae=a%10;
int bt=b/1000;
int bh=b%1000/100;
int bn=b%100/10;
int be=a%10;
if(at<bt && ah<bh && an<bn && ae<be)
return at*1000+ah*100+an*10+ae;
else if(at<bt && ah<bh && an<bn && be<ae)
return at*1000+ah*100+an*10+be;
else if(at<bt&& ah<bh && bn<an && ae<be)
else return at*1000+ah*100+bn*10+ae;
However, it looks like I'm going to have to write way too many if statements, is there a shorter way to write the code?
public static int biggestLoser(int a, int b) {
if (a < 1000 || a >= 10000 || b < 1000 || b >= 10000) {
return Math.min(a, b);
} else {
// both a and b are four digits
int result = 0 ;
int multiplier = 1 ;
for (int digit = 0; digit < 4; digit++) {
int nextDigit = Math.min(a % 10, b % 10);
result = result + nextDigit * multiplier ;
multiplier = multiplier * 10 ;
a = a / 10 ;
b = b / 10 ;
}
return result ;
}
}
How does this work? a % 10 is the remainder when a is divided by 10: in other words it is the least significant digit of a (the "ones place").
a = a / 10 performs integer division, so it divides a by 10 and ignores any fraction. So 1234 becomes 123, and on the next iteration 123 becomes 12, etc. In other words, it discards the "ones place".
So the first time through the loop, you look at the "ones" from a and b, find the smallest one, and add it to result. Then you drop the "ones" from both a and b. So what used to be the "tens" are now the "ones". The second time through the loop, you get the smallest "ones" again: but this was originally the smallest "tens". You want to add that to result, but you need to multiply by 10. This is the multiplier: each time through the loop the multiplier is multiplied by 10. So each time, you get the smallest "ones", multiply by the correct thing, add to the result, and then drop the "ones" from a and b.
Just for fun, here's an implementation that needs only one statement (and works if you replace "four digits" with any positive number of digits). You can ask your instructor to explain it ;).
public static final int NUM_DIGITS = 4 ;
public static final int MAX = (int) Math.pow(10, NUM_DIGITS) ;
public static final int MIN = MAX / 10 ;
public static int biggestLoser(int a, int b) {
return (a < MIN || a >= MAX || b < MIN || b >= MAX) ? Math.min(a, b) :
IntStream.iterate(1, multiplier -> multiplier * 10).limit(NUM_DIGITS)
.map(multiplier -> Math.min((a / multiplier) % 10, (b / multiplier) % 10) * multiplier )
.sum();
}
maybe it is stupid but try to take advantage of String ( .charAt(int index) )and Integer ( .parseInt( String value ) ) methods , maybe this example help you :
int x=145;
int y=826;
//to know which number have the biggest tens
String a=x+"";
String b=y+"";
if(Integer.parseInt(a.charAt(1)+"")>Integer.parseInt(b.charAt(1)+""))
{
System.out.println("The number which have the biggest tens is "+a);
}
else
{
System.out.println("The number which have the biggest tens is "+b);
}
Using String and StringBuilder
public class Test
{
public static void main(String []args)
{
System.out.println(biggestLooser(6712,1234));
}
public static int biggestLooser(int _a, int _b)
{
String a = String.valueOf(_a);
String b = String.valueOf(_b);
StringBuilder c = new StringBuilder();
if(a.length() < b.length()) return Integer.parseInt(a);
else if(b.length() < a.length()) return Integer.parseInt(b);
else if(a.length() >= 4 && b.length() >= 4)
{
for(int i = 4; i > 0; i--)
{
char ch = '\0';
if(a.charAt(a.length() - i) < b.charAt(b.length() - i))
ch = a.charAt(a.length() - i);
else ch = b.charAt(b.length() - i);
c.append(ch);
}
return Integer.parseInt(c.toString());
}
else return -1;
}
}
//ouput: 1212
Here is the simple answer
public static int biggestLoser(int a, int b) {
if (a < 1000 || b < 1000) {
if (a < b)
return a;
else
return b;
}
int val = 0;
ArrayList<Integer> data1 = new ArrayList<Integer>();
while (a > 0) {
data1.add(a % 10);
a /= 10;
}
Collections.reverse(data1);
ArrayList<Integer> data2 = new ArrayList<Integer>();
while (b > 0) {
data2.add(b % 10);
b /= 10;
}
Collections.reverse(data2);
val = ((data1.get(0) < data2.get(0)) ? data1.get(0) : data2.get(0))
* 1000
+ ((data1.get(1) < data2.get(1)) ? data1.get(1) : data2.get(1))
* 100
+ ((data1.get(2) < data2.get(2)) ? data1.get(2) : data2.get(2))
* 10
+ ((data1.get(3) < data2.get(3)) ? data1.get(3) : data2.get(3));
return val;
}
I'm trying to write a method that will calculate if two numbers are relatively prime for an assignment. I'm primarily looking for answers on where to start. I know there is a method gcd() that will do a lot of it for me, but the assignment is pretty much making me do it without gcd or arrays.
I kind of have it started, because I know that I will have to use the % operator in a for loop.
public static boolean relativeNumber(int input4, int input5){
for(int i = 1; i <= input4; i++)
Obviously this method is only going to return true or false because the main function is only going to print a specific line depending on if the two numbers are relatively prime or not.
I'm thinking I will probably have to write two for loops, both for input4, and input5, and possibly some kind of if statement with a logical && operand, but I'm not sure.
Well in case they are relatively prime, the greatest common divider is one, because - if otherwise - both numbers could be devided by that number. So we only need an algorithm to calculate the greatest common divider, for instance Euclid's method:
private static int gcd(int a, int b) {
int t;
while(b != 0){
t = a;
a = b;
b = t%b;
}
return a;
}
And then:
private static boolean relativelyPrime(int a, int b) {
return gcd(a,b) == 1;
}
Euclid's algorithm works in O(log n) which thus is way faster than enumerating over all potential divisors which can be optimized to O(sqrt n).
Swift 4 code for #williem-van-onsem answer;
func gcd(a: Int, b: Int) -> Int {
var b = b
var a = a
var t: Int!
while(b != 0){
t = a;
a = b;
b = t%b;
}
return a
}
func relativelyPrime(a : Int, b: Int) -> Bool{
return gcd(a: a, b: b) == 1
}
Usage;
print(relativelyPrime(a: 2, b: 4)) // false
package stack;
import java.util.Scanner; //To read data from console
/**
*
* #author base
*/
public class Stack {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
Scanner in = new Scanner(System.in); // with Scanner we can read data
int a = in.nextInt(); //first variable
int b = in.nextInt(); //second variable
int max; // to store maximum value from a or b
//Let's find maximum value
if (a >= b) {
max = a;
} else {
max = b;
}
int count = 0; // We count divisible number
for (int i=2; i<=max; i++) { // we start from 2, because we can't divide on 0, and every number divisible on 1
if (a % i == 0 && b % i==0) {
count++; //count them
}
}
if (count == 0) { // if there is no divisible numbers
System.out.println("Prime"); // that's our solutions
} else {
System.out.println("Not Prime"); //otherwise
}
}
}
I think that, this is the simple solution. Ask questions in comments.
I have a question regarding the CountDiv problem in Codility.
The problem given is: Write a function:
class Solution { public int solution(int A, int B, int K); }
that, given three integers A, B and K, returns the number of integers within the range [A..B] that are divisible by K, i.e.:
{ i : A ≤ i ≤ B, i mod K = 0 }
My code:
class Solution {
public int solution(int A, int B, int K) {
int start=0;
if (B<A || K==0 || K>B )
return 0;
else if (K<A)
start = K * ( A/K +1);
else if (K<=B)
start = K;
return (B-start+1)/K+ 1;
}
}
I don't get why I'm wrong, specially with this test case:
extreme_ifempty
A = 10, B = 10, K in {5,7,20}
WRONG ANSWER
got 1 expected 0
if K =5 then with i=10 A<=i<=B and i%k =0 so why should I have 0? Problem statement.
This is the O(1) solution, which passed the test
int solution(int A, int B, int K) {
int b = B/K;
int a = (A > 0 ? (A - 1)/K: 0);
if(A == 0){
b++;
}
return b - a;
}
Explanation: Number of integer in the range [1 .. X] that divisible by K is X/K. So, within the range [A .. B], the result is B/K - (A - 1)/K
In case A is 0, as 0 is divisible by any positive number, we need to count it in.
Java solution with O(1) and 100% in codility, adding some test cases with solutions for those who want to try and not see others solutions:
// Test cases
// [1,1,1] = 1
// [0,99,2] = 50
// [0, 100, 3] = 34
// [11,345,17] = 20
// [10,10,5] = 1
// [3, 6, 2] = 2
// [6,11,2] = 3
// [16,29,7] = 2
// [1,2,1] = 2
public int solution(int A, int B, int K) {
int offsetForLeftRange = 0;
if ( A % K == 0) { ++offsetForLeftRange; }
return (B/K) - (A /K) + offsetForLeftRange;
}
The way to solve this problem is by Prefix Sums as this is part of that section in Codility.
https://codility.com/programmers/lessons/3/
https://codility.com/media/train/3-PrefixSums.pdf
Using this technique one can subtract the count of integers between 0 and A that are divisible by K (A/K+1) from the the count of integers between 0 and B that are divisible by K (B/K+1).
Remember that A is inclusive so if it is divisible then include that as part of the result.
Below is my solution:
class Solution {
public int solution(int A, int B, int K) {
int b = (B/K) + 1; // From 0 to B the integers divisible by K
int a = (A/K) + 1; // From 0 to A the integers divisible by K
if (A%K == 0) { // "A" is inclusive; if divisible by K then
--a; // remove 1 from "a"
}
return b-a; // return integers in range
}
}
return A==B ? (A%K==0 ? 1:0) : 1+((B-A)/K)*K /K;
Well it is a completely illegible oneliner but i posted it just because i can ;-)
complete java code here:
package countDiv;
public class Solution {
/**
* First observe that
* <li> the amount of numbers n in [A..B] that are divisible by K is the same as the amount of numbers n between [0..B-A]
* they are not the same numbes of course, but the question is a range question.
* Now because we have as a starting point the zero, it saves a lot of code.
* <li> For that matter, also A=-1000 and B=-100 would work
*
* <li> Next, consider the corner cases.
* The case where A==B is a special one:
* there is just one number inside and it either is divisible by K or not, so return a 1 or a 0.
* <li> if K==1 then the result is all the numbers between and including the borders.
* <p/>
* So the algorithm simplifies to
* <pre>
* int D = B-A; //11-5=6
* if(D==0) return B%K==0 ? 1:0;
* int last = (D/K)*K; //6
* int parts = last/K; //3
* return 1+parts;//+1 because the left part (the 0) is always divisible by any K>=1.
* </pre>
*
* #param A : A>=1
* #param B : 1<=A<=B<=2000000000
* #param K : K>=1
*/
private static int countDiv(int A, int B, int K) {
return A==B ? A%K==0 ? 1:0 : 1+((B-A)/K)*K /K;
}
public static void main(String[] args) {
{
int a=10; int b=10; int k=5; int result=1;
System.out.println( a + "..." + b + "/" + k + " = " + countDiv(a,b,k) + (result!=countDiv(a,b,k) ? " WRONG" :" (OK)" ));
}
{
int a=10; int b=10; int k=7; int result=0;
System.out.println( a + "..." + b + "/" + k + " = " + countDiv(a,b,k) + (result!=countDiv(a,b,k) ? " WRONG" :" (OK)" ));
}
{
int a=6; int b=11; int k=2; int result=3;
System.out.println( a + "..." + b + "/" + k + " = " + countDiv(a,b,k) + (result!=countDiv(a,b,k) ? " WRONG" :" (OK)" ));
}
{
int a=6; int b=2000000000; int k=1; int result=b-a+1;
System.out.println( a + "..." + b + "/" + k + " = " + countDiv(a,b,k) + (result!=countDiv(a,b,k) ? " WRONG" :" (OK)" ));
}
}
}//~countDiv
I think the answers above don't provide enough logical explanation to why each solution works (the math behind the solution) so I am posting my solution here.
The idea is to use the arithmetic sequence here. If we have first divisible number (>= A) and last divisible number (<= B) we have an arithmetic sequence with distance K. Now all we have to do is find the total number of terms in the range [newA, newB] which are total divisible numbers in range [newA, newB]
first term (a1) = newA
last/n-th term (an) = newB
distance (d) = K
Sn = a1 + (a1+K) + (a1 + 2k) + (a1 + 3k) + ... + (a1 + (n-1)K)
`n` in the above equation is what we are interested in finding. We know that
n-th term = an = a1 + (n-1)K
as an = newB, a1 = newA so
newB = newA + (n-1)K
newB = newA + nK - K
nK = newB - newA + K
n = (newB - newA + K) / K
Now that we have above formula so just apply it in code.
fun countDiv(A: Int, B: Int, K: Int): Int {
//NOTE: each divisible number has to be in range [A, B] and we can not exceed this range
//find the first divisible (by k) number after A (greater than A but less than B to stay in range)
var newA = A
while (newA % K != 0 && newA < B)
newA++
//find the first divisible (by k) number before B (less than B but greater than A to stay in range)
var newB = B
while (newB % K != 0 && newB > newA)
newB--
//now that we have final new range ([newA, newB]), verify that both newA and newB are not equal
//because in that case there can be only number (newA or newB as both are equal) and we can just check
//if that number is divisible or not
if (newA == newB) {
return (newA % K == 0).toInt()
}
//Now that both newA and newB are divisible by K (a complete arithmetic sequence)
//we can calculate total divisions by using arithmetic sequence with following params
//a1 = newA, an = newB, d = K
// we know that n-th term (an) can also be calculated using following formula
//an = a1 + (n - 1)d
//n (total terms in sequence with distance d=K) is what we are interested in finding, put all values
//newB = newA + (n - 1)K
//re-arrange -> n = (newB - newA + K) / K
//Note: convert calculation to Long to avoid integer overflow otherwise result will be incorrect
val result = ((newB - newA + K.toLong()) / K.toDouble()).toInt()
return result
}
I hope this helps someone. FYI, codility solution with 100% score
Simple solution in Python:
def solution(A, B, K):
count = 0
if A % K == 0:
count += 1
count += int((B / K) - int(A / K))
return count
explanation:
B/K is the total numbers divisible by K [1..B]
A/K is the total numbers divisible by K [1..A]
The subtracts gives the total numbers divisible by K [A..B]
if A%K == 0, then we need to add it as well.
This is my 100/100 solution:
https://codility.com/demo/results/trainingRQDSFJ-CMR/
class Solution {
public int solution(int A, int B, int K) {
return (B==0) ? 1 : B/K + ( (A==0) ? 1 : (-1)*(A-1)/K);
}
}
Key aspects of this solution:
If A=1, then the number of divisors are found in B/K.
If A=0, then the number of divisors are found in B/K plus 1.
If B=0, then there is just one i%K=0, i.e. zero itself.
Here is my simple solution, with 100%
https://app.codility.com/demo/results/trainingQ5XMG7-8UY/
public int solution(int A, int B, int K) {
while (A % K != 0) {
++A;
}
while (B % K != 0) {
--B;
}
return (B - A) / K + 1;
}
Python 3 one line solution with score 100%
from math import ceil, floor
def solution(A, B, K):
return floor(B / K) - ceil(A / K) + 1
This works with O(1) Test link
using System;
class Solution
{
public int solution(int A, int B, int K)
{
int value = (B/K)-(A/K);
if(A%K == 0)
{
value=value+1;
}
return value;
}
}
I'm not sure what are you trying to do in your code, but simpler way would be to use modulo operator (%).
public int solution(int A, int B, int K)
{
int noOfDivisors = 0;
if(B < A || K == 0 || K > B )
return 0;
for(int i = A; i <= B; i++)
{
if((i % K) == 0)
{
noOfDivisors++;
}
}
return noOfDivisors;
}
If I understood the question correctly I believe this is the solution:
public static int solution(int A, int B, int K) {
int count = 0;
if(K == 0) {
return (-1);
}
if(K > B) {
return 0;
}
for(int i = A; i <= B; ++i) {
if((i % K) == 0) {
++count;
}
}
return count;
}
returning -1 is due to an illegal operation (division by zero)
int solution(int A, int B, int K) {
int tmp=(A%K==0?1:0);
int x1=A/K-tmp ;
int x2=B/K;
return x2-x1;
}
100/100 - another variation of the solution, based on Pham Trung's idea
class Solution {
public int solution(int A, int B, int K) {
int numOfDivs = A > 0 ? (B / K - ((A - 1) / K)) : ((B / K) + 1);
return numOfDivs;
}
}
class Solution {
public int solution(int A, int B, int K) {
int a = A/K, b = B/K;
if (A/K == 0)
b++;
return b - a;
}
}
This passes the test.
It's similar to "how many numbers from 2 to 5". We all know it's (5 - 2 + 1). The reason we add 1 at the end is that the first number 2 counts.
After A/K, B/K, this problem becomes the same one above. Here we need to decide if A counts in this problem. Only if A%K == 0, it counts then we need to add 1 to the result b - a (the same with b+1).
Here's my solution, two lines of Java code.
public int solution(int A, int B, int K) {
int a = (A == 0) ? -1 : (A - 1) / K;
return B / K - a;
}
The thought is simple.
a refers to how many numbers are divisible in [1..A-1]
B / K refers to how many numbers are divisible in [1..B]
0 is divisible by any integer so if A is 0, you should add one to the answer.
Here is my solution and got 100%
public int solution(int A, int B, int K) {
int count = B/K - A/K;
if(A%K == 0) {
count++;
}
return count;
}
B/K will give you the total numbers divisible by K [1..B]
A/K will give you the total numbers divisible by K [1..A]
then subtract, this will give you the total numbers divisible by K [A..B]
check A%K == 0, if true, then + 1 to the count
Another O(1) solution which got 100% in the test.
int solution(int A, int B, int K) {
if (A%K)
A = A+ (K-A%K);
if (A>B)
return 0;
return (B-A)/K+1;
}
This is my 100/100 solution:
public int solution1(int A, int B, int K) {
return A == 0 ? B / K - A / K + 1 : (B) / K - (A - 1) / K;
}
0 is divisible by any integer so if A is 0, you should add one to the answer.
This is the O(1) solution, ( There is no check required for the divisility of a)
public static int countDiv(int a, int b, int k) {
double l1 = (double)a / k;
double l = -1 * Math.floor(-1 * l1);
double h1 = (double) b / k;
double h = Math.floor(h1);
Double diff = h-l+1;
return diff.intValue();
}
There is a lot of great answers, but I think this one has some elegance in it, also gives 100% on codility.
public int solution(int a, int b, int k) {
return Math.floorDiv(b, k) - Math.floorDiv(a-1, k);
}
Explanation: Number of integers in the range [1 .. B] that divisible by K is B/K. Range [A .. B] can be transformed to [1 .. B] - [1 .. A) (notice that round bracket after A means that A does not belong to that range). That gives as a result B/K - (A-1)/K. Math.floorDiv is used to divide numbers and skip remaining decimal parts.
I will show my code in go :)
func CountDiv(a int, b int, k int) int {
count := int(math.Floor(float64(b/k)) - math.Floor(float64(a/k)));
if (math.Mod(float64(a), float64(k)) == 0) {
count++
}
return count
}
The total score is 100%
If someone is still interested in this exercise, I share my Python solution (100% in Codility)
def solution(A, B, K):
if not (B-A)%K:
res = int((B-A)/K)
else:
res = int(B/K) - int(A/K)
return res + (not A%K)
int divB = B / K;
int divA = A / K;
if(A % K != 0) {
divA++;
}
return (divB - divA) + 1;
passed 100% in codelity
My 100% score solution with one line code in python:
def solution(A, B, K):
# write your code in Python 3.6
return int(B/K) - int(A/K) + (A%K==0)
pass
int solution(int A, int B, int K)
{
// write your code in C++14 (g++ 6.2.0)
int counter = 0;
if (A == B)
A % K == 0 ? counter++ : 0;
else
{
counter = (B - A) / K;
if (A % K == 0) counter++;
else if (B % K == 0) counter++;
else if ((counter*K + K) > A && (counter*K + K) < B) counter++;
}
return counter;
}
Assumptions:
A and B are integers within the range [0..2,000,000,000];
K is an integer within the range [1..2,000,000,000];
A ≤ B.
int from = A+(K-A%K)%K;
if (from > B) {
return 0;
}
return (B-from)/K + 1;
Hi all I was wondering if there is a way to implement this method without casting to a wider data type (e.g. long, double, etc)?
CanTimes(int a, int b){
returns true if a * b is within the range of -2^31 to 2^31-1, else false;
}
For example, we could implement one for the method CanAdd (without casts) as such:
public static boolean CanPlus(int a, int b) {
if (b >= 0) {
return a <= Integer.MAX_VALUE - b
} else {
return a >= Integer.MIN_VALUE - b
}
}
Implementation language is Java, though of course this is more of a language-agnostic problem.
I was thinking if there's some logic we can employ to decide if a * b fits the range of an integer without casting it to a wider data type?
Solution ! based on Strelok's comment:
public static boolean CanTimes(int a, int b) {
if (a == 0 || b == 0) {
return true;
}
if (a > 0) {
if (b > 0) {
return a <= Integer.MAX_VALUE / b;
} else {
return a <= Integer.MIN_VALUE / b;
}
} else {
if (b > 0) {
return b <= Integer.MIN_VALUE / a;
} else {
return a <= -Integer.MAX_VALUE / b;
}
}
}
As per my comment, here is the adapted version, with some unit tests:
public static int mulAndCheck( int a, int b )
{
int ret;
String msg = "overflow: multiply";
if ( a > b )
{
// use symmetry to reduce boundry cases
ret = mulAndCheck( b, a );
}
else
{
if ( a < 0 )
{
if ( b < 0 )
{
// check for positive overflow with negative a, negative b
if ( a >= Integer.MAX_VALUE / b )
{
ret = a * b;
}
else
{
throw new ArithmeticException( msg );
}
}
else if ( b > 0 )
{
// check for negative overflow with negative a, positive b
if ( Integer.MIN_VALUE / b <= a )
{
ret = a * b;
}
else
{
throw new ArithmeticException( msg );
}
}
else
{
// assert b == 0
ret = 0;
}
}
else if ( a > 0 )
{
// assert a > 0
// assert b > 0
// check for positive overflow with positive a, positive b
if ( a <= Integer.MAX_VALUE / b )
{
ret = a * b;
}
else
{
throw new ArithmeticException( msg );
}
}
else
{
// assert a == 0
ret = 0;
}
}
return ret;
}
#Test( expected = ArithmeticException.class )
public void testOverflow()
{
mulAndCheck( Integer.MAX_VALUE, Integer.MAX_VALUE );
}
#Test( expected = ArithmeticException.class )
public void testOverflow1()
{
mulAndCheck( Integer.MIN_VALUE, Integer.MAX_VALUE );
}
#Test
public void testTimesMinus1()
{
Assert.assertEquals( Integer.MIN_VALUE + 1, mulAndCheck( Integer.MAX_VALUE, -1 ) );
Assert.assertEquals( Integer.MAX_VALUE, mulAndCheck( Integer.MIN_VALUE + 1, -1 ) );
}
You can do the multiplication and then check whether dividing by one factor still gives the other.
EDIT
The above doesn't work all the time, as Dietrich Epp points out; it fails for -1 and Integer.MIN_VALUE. I don't know if there are any other edge cases. If not, then it would be easy to check for this one case.
Since the multiplication of a*b is the same as a+a+a+... repeated b times (and vice-versa), you can do something like this:
(I renamed your CanMultiple() function to isIntMultiplication(), since I think its more clear )
public boolean isIntMultiplication(int a, int b) {
// signs are not important in this context
a = Math.abs(a);
b = Math.abs(b);
// optimization: I want to calculate a*b as the sum of a by itself repeated b times, so make sure b is the smaller one
// i.e., 100*2 is calculated as 100+100 which is faster than summing 2+2+2+... a hundred times
if (b > a) { int swap = a; a = b; b = swap; }
int n = 0, total = a;
while(++n < b) {
if (total <= Integer.MAX_VALUE - a) {
total += a;
} else {
return false;
}
}
return true;
}
You see it in action:
// returns true, Integer.MAX_VALUE * 1 is still an int
isIntMultiplication(Integer.MAX_VALUE, 1);
// returns false, Integer.MAX_VALUE * 2 is a long
isIntMultiplication(Integer.MAX_VALUE, 2);
// returns true, Integer.MAX_VALUE/2 * 2 is still an int
isIntMultiplication(Integer.MAX_VALUE/2, 2);
// returns false, Integer.MAX_VALUE * Integer.MAX_VALUE is a long
isIntMultiplication(Integer.MAX_VALUE, Integer.MAX_VALUE);
This solution does not use long types, as required.
Mathematically, the sum of the log-base-2 should be less than 232. Unfortunately, Math doesn't give us log base 2, but this is still simple enough:
static boolean canMultiply(int a, int b) {
return Math.log(Math.abs(a)) + Math.log(Math.abs(b)) <= Math.log(Integer.MAX_VALUE);
}
EDITED: Due to (fair) flak, how about this simple approach that addresses OP's question exactly?
static boolean canMultiply(int a, int b) {
return a == 0 || ((a * b) / a) == b;
}
If there's an overflow, dividing by the original number won't bring us back to starting number.
Importantly, this will work for longs, which can't be cast up.