Lambda expression to find of a number is composite or not - java

private static boolean isCompositeLambda(int number) {
return number > 3 && Stream.iterate(2, i -> i + 1)
.filter(x -> number % x == 0)
.limit((long) Math.sqrt(number))
.count() > 0;
}
When i give 5 it goes into infinite loop.
Can anyone give the correct code

You have two problems, the filter is applied first, and the second is the limit is the number of values, not the value it self.
It goes into an very long (but not infinite) loop because it take a long time to generate your limit of numbers. e.g. for 5 it tries to get 2 numbers ((long) Math.sqrt(5)) == 2L, however to achieve the first solution when number == x however it has to check another ~4 billion values before it overflows and reaches -number to get a second solution and the limit is reached. i.e. 5 % 5 == 0 and 5 % -5 == 0
A simpler solution is
private static boolean isCompositeLambda(int number) {
return number > 3 &&
IntStream.rangeClosed(2, (int) Math.sqrt(number))
.anyMatch(x -> number % x == 0);
}

Related

Improve performance of string to binary number conversion

This is one of the questions that I faced in competitive programming.
Ques) You have an input String which is in binary format 11100 and you need to count number of steps in which number will be zero. If number is odd -> subtract it by 1, if even -> divide it by 2.
For example
28 -> 28/2
14 -> 14/2
7 -> 7-1
6 -> 6/2
3 -> 3-1
2 -> 2/2
1-> 1-1
0 -> STOP
Number of steps =7
I came up with the following solutions
public int solution(String S) {
// write your code in Java SE 8
String parsableString = cleanString(S);
int integer = Integer.parseInt(S, 2);
return stepCounter(integer);
}
private static String cleanString(String S){
int i = 0;
while (i < S.length() && S.charAt(i) == '0')
i++;
StringBuffer sb = new StringBuffer(S);
sb.replace(0,i,"");
return sb.toString();
}
private static int stepCounter(int integer) {
int counter = 0;
while (integer > 0) {
if (integer == 0)
break;
else {
counter++;
if (integer % 2 == 0)
integer = integer / 2;
else
integer--;
}
}
return counter;
}
The solution to this question looks quite simple and straightforward, however the performance evaluation of this code got me a big ZERO. My initial impressions were that converting the string to int was a bottleneck but failed to find a better solution for this. Can anybody please point out to me the bottlenecks of this code and where it can be significantly improved ?
If a binary number is odd, the last (least significant) digit must be 1, so subtracting 1 is just changing the last digit from 1 to 0 (which, importantly, makes the number even).
If a binary number is even, the last digit must be 0, and dividing by zero can be accomplished by simply removing that last 0 entirely. (Just like in base ten, the number 10 can be divided by ten by taking away the last 0, leaving 1.)
So the number of steps is two steps for every 1 digit, and one step for every 0 digit -- minus 1, because when you get to the last 0, you don't divide by 2 any more, you just stop.
Here's a simple JavaScript (instead of Java) solution:
let n = '11100';
n.length + n.replace(/0/g, '').length - 1;
With just a little more work, this can deal with leading zeros '0011100' properly too, if that were needed.
Number of times you need to subtract is the number of one bits which is Integer.bitCount(). Number of times you need to divide is the position of most-significant bit which is Integer.SIZE (32, total number of bits in integer) minus Integer.numberOfLeadingZeros() minus one (you don't need to divide 1). For zero input I assume, the result should be zero. So we have
int numberOfOperations = integer == 0 ? 0 : Integer.bitCount(integer) +
Integer.SIZE - Integer.numberOfLeadingZeros(integer) - 1;
As per the given condition, we are dividing the number by 2 if it is even which is equivalent to remove the LSB, again if number is odd we are subtracting 1 and making it an even which is equivalent to unset the set bit (changing 1 to 0). Analyzing the above process we can say that the total number of steps required will be the sum of (number of bits i.e. (log2(n) +1)) and number of set bits - 1(last 0 need not to be removed).
C++ code:
result = __builtin_popcount(n) + log2(n) + 1 - 1;
result = __builtin_popcount(n) + log2(n);

I am writing a java program that uses one loop to process the integers from 300 down to 200

Here are my instructions:
Write a program that uses one loop to process the integers from 300 down to 200, inclusive. The program should detect multiples of 11 or 13, but not both. The multiples should be printed left-aligned in columns 8 characters wide, 5 multiples per line. When all multiples have been displayed, the program should display the number of multiples found and their sum.
int sum = 300;
while (sum >= 200 && sum <= 300 ) {
sum = sum - 1;
System.out.println( sum % 11 == 0 || sum % 13 == 0 );
}
As you may know, I am getting true and false responses rather than the numbers. I am very much stuck and would like any help or advice I can get! Thank you.
The problem is that the == operator is an equality operator that returns a condition (either true or false). That's why you're printing true and false. If you want to print the actual multiples, first check if they are either a multiple of 11 or a multiple of 13 (but not both), and then print the number, sum.
int sum = 300;
while (sum >= 200 && sum <= 300 ) {
if((sum % 11 == 0) != (sum % 13 == 0)) { //checks if sum is a multiple of 11 or 13 but not both
System.out.println(sum);
}
sum = sum - 1;
}
What (sum % 11 == 0) != (sum % 13 == 0) means is that if sum is a multiple of both 11 and 13, then the expression will equate to false because the results of (sum % 11 == 0) and (sum % 13 == 0) are both true. Similar reasoning will let you see that if sum is only a multiple of one of 11 or 13, then the expression will result in true since one side of the expression will result in true while the other side will result in false.
Since this looks like homework, I don't want to just give the answer away, but I'd like to help, so I'll give you a couple of hints:
1) "if" statements are where you'd want to use comparisons to decide what to do, e.g.
if (blah == more_blah)
2) Since your numbers are all guaranteed to be 3 characters, there is a simple and easy way to get the exact spacing of 8 characters per column. (Hint: print() and println() are both things)
3) Since you want multiple columns, you might want some way to check how many columns you have already and then decide whether you want println or print. (bonus hint: using System.out.println("") could make your code simpler.)

Write a program in java to print the sum of all numbers from 50 to 250(inclusive of 50 and 250) that are multiples of 3 and not divisible by 9

/* when I run this code there is no error in fact output generated is also correct but I want to know what is the logical error in this code? please can any one explain what is the logical error. */
class abc
{
public static void main(String arg[]){
int sum=0;
//for-loop for numbers 50-250
for(int i=50;i<251;i++){
// condition to check if number should be divided by 3 and not divided by 9
if(i%3==0 & i%9!=0){
//individual number which are selected in loop
System.out.println(i);
//adding values of array so that total sum can be calculated
sum=sum+i;
}
}
//final display output for the code
System.out.println("the sum of intergers from 50 to 250 that are multiples of 3 and not divisible by 9 \n"+sum);
}
}
My philosophy is "less code == less bugs":
int sum = IntStream.rangeClosed(50, 250)
.filter(i -> i % 3 == 0)
.filter(i -> i % 9 != 0)
.sum();
One line. Easy to read and understand. No bugs.
Change this:
if(i%3==0 & i%9!=0){
to this:
if(i%3==0 && i%9!=0){
& = bitwise and operator
&& = logical operator
Difference between & and && in Java?
The only problems I saw were:
The variable sum was undeclared
Use && in place of &
int sum = 0;
for (int i = 50; i <= 250; i++) {
if (i % 3 == 0 && i % 9 != 0) {
System.out.println(i);
sum = sum + i;
}
}
System.out.println("the sum of intergers from 50 to 250 that are multiples of 3 and not divisible by 9 \n" + sum);
Well, instead of touching every single value from 50 to 250 like you would do here for(int i=50;i<251;i++), you can consider something like this...
int i = 48;
int sum = 0;
while(i < 250) {
i += 3;
if(i%9 != 0)
sum += i;
}
This is somewhat optimized in the sense that I am skipping over values that I know are not possible candidates.
But, there is a much bigger issue in your code. The following code block prints true, sure. But, it is a bad idea to depend on the & since that is not its job. The & is for bitwise AND whereas the && is for logical AND, which is what you are trying to do.
boolean t = true;
boolean f = false;
System.out.println(f&t);
Why?
In Java, if it is a && operation, as soon as you find the first false, you are sure that the expression will evaluate to false. Meanwhile, in your implementation, it would need to evaluate both sides. f&t will evaluate to false, but the JVM would need to look at both the f and t variables. Meanwhile, on using &&, it wouldn't even need to look at the t.

determine whether an int is power of 2 [duplicate]

This question already has answers here:
How to check if a number is a power of 2
(32 answers)
Closed 7 years ago.
public class test{
public static void main(String[] args) {
int a=536870912;
System.out.print((Math.log(a)/Math.log(2)));
}
}
536870912 is a number that is power of two, but the result is 29.000000000000004, could anybody explain this? Thanks.
If n is a power of 2, then its binary representation will start with 1 and will contain only 0s after it.
So, you can do:
String binary = Integer.toBinaryString(a);
Pattern powerOfTwoPattern = Pattern.compile("10*");
System.out.println(powerOfTwoPattern.matcher(binary).matches());
Anyway, if you number is not really huge (i.e. fits the int or long range), then you can follow the suggestions here
You can use below method:-
boolean isPowerOfTwo (int x)
{
while (((x % 2) == 0) && x > 1) /* While x is even and > 1 */
x /= 2;
return (x == 1);
}
Explanation:- Repeatedly divides x by 2. It divides until either the quotient becomes 1, in which case x is a power of two, or the quotient becomes odd before reaching 1, in which case x is not a power of two.
pseudo-code following, easily adapted to java
boolean is_power_of_two(int num)
{
int i = Math.ceil(Math.log(num)/Math.log(2.0));
/*while ( i >= 0 )
{
// note 1 is taken as power of 2, i.e 2 ^ 0
// chnage i > 0 above to avoid this
if ( num == (1 << i) ) return true;
i--;
}
return false;*/
// or even this, since i is initialised in maximum power of two that num can have
return (num == (1 << i)) || (num == (1 << (i-1)));
}
NOTE it also can be done with discrete logarithm in constant-time without compiling to string represenation etc, but needs a precomputed table of discrete logarithms for base 2 or even using binary manipulation as in https://stackoverflow.com/a/600306/3591273, these approaches are constant-time but use the default representation of machine int or long

Project Euler #3 - Solution runs forever

First time I've ever encountered this problem. It feels like it will never end.
My approach:
import java.util.TreeSet;
public class Euler3 {
public static void main(String[] args) {
long result = 0;
long startTime = System.nanoTime();
long numberGiven = 600851475143L;
TreeSet<Long> nums = new TreeSet<>();
for (long i = 2L; i < numberGiven; i++) {
if (numberGiven % i == 0 && isPrime(i)) {
nums.add(i);
}
}
result = nums.last();
System.out.print("Result: " + result +
".\nTime used for calculation in nanoseconds: " +
(System.nanoTime() - startTime) + ".");
}
public static boolean isPrime(long n) {
if (n <= 3) {
return n == 1 ? false : true;
} else if (n % 2 == 0 || n % 3 == 0) {
return false;
} else {
for (int i = 5; i * i <= n; i += 6) {
if (n % i == 0 || n % (i + 2) == 0) {
return false;
}
}
return true;
}
}
}
Of course this works on smaller numbers, but as is probably intended doesn't seem effective on over 600 billion.
I'm wondering, without giving the answer away:
Is there some obvious alteration I could employ to reduce the
running time/checks necessary?
Although it clearly doesn't work effectively here, is this approach
otherwise acceptable or would someone who posted this challenge,
even with a smaller number, be looking for something different?
I tried with integers the first time and got an overflow related error, is anything similar happening under the hood that would actually prevent this from terminating?
For every number you're checking that's a factor, you're doing an internal loop to figure out if it's a prime. That means your algorithm is effectively performing n * m operations.
You can instead use the following mathematical "trick", which I think is the same used by the UNIX factor program.
Since every number over one is either prime or a unique product of a set of primes (with potential duplicates in the set), we can just start dividing the number by the first prime two (actually reducing the number in the process) until that's no longer possible (i.e., it becomes odd). At that point, the reduced number will not have two or any multiples of two as a factor.
Then we do the same by continuously dividing by three until that's no longer possible.
Now you'd think that may be onerous but, because you've stripped out all the 'two' factors, the number cannot possibly be a multiple of four (or any other even number for that matter). So we detect that and move up to the next divisor of five and start dividing by that.
So the division operation are only done for prime divisors, speeding things up considerably. In addition, once the divisor gets above the square root of the (reduced) number, no more factors are possible, so we exit. In that case, the reduced number gives us the final (hence highest) prime factor.
For example, consider the number 924:
Number Divisor Result
------ ------- ------
924 2* 462
462 2* 231
231 2 not divisible, go to 3
231 3* 77
77 3 not divisible, go to 4
77 4 not divisible, go to 5
77 5 not divisible, go to 6
77 6 not divisible, go to 7
77 7* 11
11* 7 stop since 7 * 7 > 11
So the prime factors of 924 are {2, 2, 3, 7, 11}.
Now I urge you to try that algorithm on your own before looking below since the entire point of Euler is to test your own abilities. I simply provide the solution for completeness:
public class Test
{
public static void main(String[] args) {
long startTime = System.nanoTime();
long number = 600851475143L;
// Start with a divisor of two,
// continue until over sqrt(number).
long divisor = 2L;
while (divisor * divisor <= number) {
if ((number % divisor) == 0) {
// If factor, output then reduce number.
System.out.println(divisor);
number = number / divisor;
} else {
// Otherwise, move to next divisor.
divisor++;
}
}
// Final number is final divisor.
System.out.println(number);
System.out.print("Time used for calculation in nanoseconds: " +
(System.nanoTime() - startTime) + ".");
}
}
That gives you the four prime factors in about five thousandths of a second (on my box, anyway):
71
839
1471
6857
Time used for calculation in nanoseconds: 458826.
The program can be simple like this, which runs under a second:
long val = 600851475143L;
long ans = 0;
for(long i = 2; i*i <= val; i++){
if(val % i == 0){
ans = i;
while(val % i == 0)//This step will make sure that i is prime
val /= i;
}
}
if(val != 1){//If val is not 1, so val is a prime
ans = val > ans ? val : ans;
}
System.out.println(ans);
Answer is 6857, and it is correct answer :)
Notice that we only check for all i values which i*i smaller than val.

Categories

Resources