Related to Code Optimization - java

I have came across a question but I'm unable to optimize my code. Please tell me how can I optimize my code.
Scanner in = new Scanner(System.in);
int max=0;
int a = in.nextInt();
for(int i=1;i<a;i++){
for(int j=i+1;j<=a;j++)
{
int d = i^j;
if(d>max)
max=d;
}
}
System.out.println(max);
The explanation for the above code is:
The Xor of 1 and 2 is 3.
The Xor of 1 and 3 is 2.
The Xor of 2 and 3 is 1.
So, the maximum is 3.

Scanner in = new Scanner(System.in);
int a = in.nextInt();
System.out.println("Max = " + Double.toString(Math.pow(2, 1+Math.floor(Math.log(a)/Math.log(2)))-1.0));
Oops.. Doesn't work when a=0, but you should be able to adjust for that.
Explanation
For each possible input a, there is a number between 1 and a that equals not a (considering only as many binary digits as are in a itself). So, the max will always equal (2^n)-1, where n is the number of binary digits in a.

Okay, so the maximum you're looking for is all ones in a binary string of length of the binary string that represents your input value.
Your input value is 3, in binary it's '11', xor table:
0 xor 0 = 0
1 xor 0 = 1
0 xor 1 = 1
1 xor 1 = 0
so what you want is to xor the input value with the opposite value. Here the opposite value is the value with all bytes flipped.
In your example the length of the binary string is 2, so you need to get 2 ones. To achieve that you xor '10' and '01' or '01' and '10' and that's how you get 3.
But you can simply take the opposite of '11' which is '00' and xor those two and get 3 as well (as in the algorithm I described).
I have no idea how to flip a bit string of given length because the '~' operator will flip all 32 bits of an int, but alternatively you can implement it this way:
public class Program {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int a = sc.nextInt();
sc.close();
for(int i = 1; i < a; ++i) {
a |= i;
}
System.out.println(a);
}
}
Now your running time is linear and not quadratic, however you can also achieve the same result by doing:
1 << (int)(Math.log(a)/Math.log(2)) - 1;

Related

Extracting a number in Java isn't working as expected

This program is supposed to print the numbers (indiviual digits) in a number
`
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a number");
int number = sc.nextInt();
int Size = 0;
String Conversion = Integer.toString(number);
Size = Conversion.length();
int n = 0;
while (n <= Size){
int d = number%10;
int power = Size - 2;
number = (number/(10^(power)));
System.out.println(d);
n += 1;
}
}
}
`
Really Appreciate for Anyone for Took time to help me.
Thanks
For some reason I get
1
9
3.
instead of
1
3
4
using the debugger gives me some hint, Specifically this block `
number = (number/(10^(power)));
`
for second iteration the value is +4 than expected, 3.
for third Its okay.
changing and adding +4 on that block gives
1
3
7
4
Found it !!
Credit OH GOD SPIDERS, tkausl
Solution 1 : Instead of using carrot characters in
number = (number/(10^(power)));
use Math.pow function.
Solution 2 :
Don't use (number/(10^(power))
instead just divide by 10

How can I print integer digits on separate lines using Java

I've written code to print the digits of an integer on separate lines, but I am not getting the expected output. The output of the code is instead in reverse order. How can I make my output correct without using the Math.pow method?
import java.util.Scanner;
class NumberInDigit
{
public static void main(String[] args)
{
int div;
Scanner sc = new Scanner(System.in);
System.out.println("enter the number");
int n = sc.nextInt();
while(n>0)
{
div = n%10;
n= n/10;
}
System.out.println(div);
}
}
n = 234
Output is 4,3,2
Expected output is 2,3,4
The "%" is the modulo operator so div = n%10; takes n (234), then finds the remainder the 234 when divided by 10. 234/10 = 23.4 (i.e. 4 is the remainder). So div is assigned a value of 4 (i.e. div = 4). Then you are dividing n (234), by 10 and reassigning it to n - so (234 / 10 = 23), note the remainder is ignored.
That is the end of the first iteration of the loop, and it returns div = 4.
The second iteration (when n = 23) will print out 3 (because 23 / 10 = 2r3) - remember we are returning the remainders. N is then set to 2.
The third itereration (when n = 2) will print out 2 (because 2/10 = 0r2) - the remainder is 2. N is now set to 0 as (2 / 10 = 0). So then next iteration will fail the condition of n > 0.
This is why you are getting 4,3,2.
There are a number of ways to get the expected number, but since you are working in base10 (i.e. the decimal system), I think the easiest would be just to convert the number into a string and then iterate through the string printing every number until you reached the end, or a decimal point.
you are dividing division Remainders and again dividing them again, if you want to operation on string use array
You can do it this way also:
int n=234,x=n,y=100;
while(x>=0)
{
x=n/y;
n=n%y;
System.out.println(x);
y=y/10;
}
This way output is 2,3,4.
First of all your code has syntax and logical issues. "n" doesn't have a type and it should only return 4 (since you are executing return it should not continue the while loop).
To accomplish what you need you can change your code a bit:
public static void main(String [] args){
System.out.println(printReversedNumList(234));
}
private static List printReversedNumList(int num) {
final List<Integer> reversedNumList = new ArrayList<>();
while(num>0)
{
int remainder = num%10;
num= num/10;
reversedNumList.add(remainder);
}
Collections.reverse(reversedNumList);
return reversedNumList;
}

find the Nth number of this sequence. Two set bits

Look at the following sequence:
3, 5, 6, 9, 10, 12, 17, 18, 20....
All the numbers in the series has exactly 2 bits set in their binary representation. Your task is simple, you have to find the Nth number of this sequence.
1 <= T <= 105
1 <= N <= 1014
public class Solution {
public static void main(String[] args) {
/* Enter your code here. Read input from STDIN. Print output to STDOUT. Your class should be named Solution. */
Scanner sc = new Scanner (System.in);
int t = sc.nextInt();
while ( t > 0 ){
int n = sc.nextInt();
t--;
int x =1;
while ( n > 0 ){
int y = 0;
while ( y < x ){
n--;
if ( n == 0 ){
System.out.println((1<<x)|(1<<y));
}
y++;
}
x++;
}
}
}
}
This is giving me a timeout error can i have an optimized solution of the given range of inputs
Examine The On-Line Encyclopedia of Integer Sequences
This is an integer sequence, which means we should be checking The On-Line Encyclopedia of Integer Sequences®. It frequently includes fairly optimal algorithms or mathematical expressions to produce elements in a specific integer sequence, so look there when you want an optimized solution.
After searching for 3, 5, 6, 9, 10, 12, 17, 18, 20, we find that this is OEIS sequence A018900, "Sum of two distinct powers of 2.", which includes several code snippets we should examine to determine which is fastest.
Fastest algorithm on OEIS page
Examining those snippets, the most efficient appears to be Smalltalk code by Hieronymus Fischer (Version 1 in the PROG section):
distinctPowersOf: b
"Version 1: Answers the n-th number of the form b^i + b^j, i>j>=0, where n is the receiver.
b > 1 (b = 2, for this sequence).
Usage: n distinctPowersOf: 2
Answer: a(n)"
| n i j |
n := self.
i := (8*n - 1) sqrtTruncated + 1 // 2.
j := n - (i*(i - 1)/2) - 1.
^(b raisedToInteger: i) + (b raisedToInteger: j)
Above code published in OEIS sequence A018900 on 20 April 2014, authored by Hieronymus Fischer, licensed by The Online Encyclopedia of Integer Sequences under the CC BY-NC 3.0 copyright license.
Appropriate data type
Signed 64-bit longs run out of space to hold the result and can begin to set incorrect bits after n exceeds 1,953. Since n won't exceed 1,014 in practice, long results will be fine.
Signed 32-bit ints run out of space after n exceeds 465, so they aren't large enough.
Solution using optimized algorithm
Here, we translate the Smalltalk algorithm to Java. Since optimized efficiency is your goal, we'll speed things up very slightly by using << 3 to multiply a small int value by eight and >>> 1 to perform floored division by two on a positive int:
import java.util.Scanner;
public class Solution {
// Gives the exact floor of the square root of x.
// based on Java algorithm by Programmer Olathe
// from http://www.codecodex.com/wiki/Calculate_an_integer_square_root#Java
public static final int floorSqrt(final int x) {
return (int) Math.sqrt(x);
} // Finds the nᵗʰ integer with exactly two bits set.
// Cannot properly handle n > 1953.
// based on Smalltalk algorithm by Hieronymus Fischer
// from https://oeis.org/A018900
public static final long nthWithTwoBitsSet(final int n) {
// Find the indexes of the two bits.
final int i = (floorSqrt((n << 3) - 1) + 1) >>> 1;
final int j = n - ((i*(i - 1)) >>> 1) - 1; // Return a long with the two bits set.
return (1L << i) | (1L << j);
} public static final void main(final String[] args) {
final Scanner in = new Scanner(System.in);
for (int t = in.nextInt(); t > 0; t--) {
System.out.println(nthWithTwoBitsSet(in.nextInt()));
}
}
}
Solution with slightly improved efficiency
We can gain further efficiency at the cost of bad design by combining all three methods into one:
import java.util.Scanner;
public class Solution {
// Cannot properly handle n > 1953.
// based on Java floored-square-root algorithm by Programmer Olathe
// from http://www.codecodex.com/wiki/Calculate_an_integer_square_root#Java
// based on Smalltalk nᵗʰ-with-two-bits-set algorithm by Hieronymus Fischer
// from https://oeis.org/A018900
public static final void main(final String[] args) {
final Scanner in = new Scanner(System.in);
for (int t = in.nextInt(); t > 0; t--) {
final int n = in.nextInt(); // Find the indexes of the two bits.
final int i = (((int) Math.sqrt((n << 3) - 1)) + 1) >>> 1;
final int j = n - ((i*(i - 1)) >>> 1) - 1; // Print a long with the two bits set.
System.out.println((1L << i) | (1L << j));
}
}
}
For my explanation I number the bit position from the least significant bit from 0. So 3 has bits 0 and 1 set. 5 has bits 0 and 2 set, etc.
There are 0 numbers where the most significant set bit is bit 0 (because then there is no other bit to set). 1 number where it’s bit 1 (3). Two numbers where it’s bit 2 (101 = 5 and 110 = 6). And so forth. m numbers where the most significant set bit is bit m.
This in turn means that up to and including numbers where bit b is the more significant of the two set bits, there are b * (b + 1) / 2 numbers. Let’s for a moment assume this is equal to N. Then according to the formual for solving a quadratic equation b = (sqrt(8 * N + 1) - 1) / 2. If this isn’t a whole number, it’s because N didn’t exactly equal the formula I said. Round up to find b and then find which other bit must be set for everything to agree.
I am on purpose not giving you the full solution. You wanted to solve this problem, you do the work. I hope my input is useful.
The other — smaller but easier — optimization is: Find the largest N among the test cases. Calculate the numbers of the sequence up to this largest N and put them into an array (you may modify your code from the question to do this). Then print all the required results by looking them up in the array. Language nitpicking: One may may argue that this is not literally an optimization since this word comes from latin optimus meaning best and it doesn’t produce the fastest possible program.

(Java)Why does my decimal to binary conversion method only work some of the time when counting consecutive integers in a character array?

I'm a novice Java coder working on a problem dealing with counting consecutive integers in the binary forms of numbers.
The numbers are read from the input, and converted to binary using the method called conversion. The binary form is then sent to a character array where the for loop checks for consecutive characters(specifically the number 1) and prints the maximum count as the final answer.
I've managed to get the code to a state where I feel it should be working, but I've only had success with about half of the test cases. The larger number conversions like 262,141 tend to produce incorrect answers. Can anyone tell me where I've gone wrong?
I have a suspicion that it's something to do with the character array, but after several hours of research I haven't been able to find a solution to my particular problem.
import java.io.*;
import java.util.*;
public class Solution {
public static int conversion(int decimal){//this will take the decimal from the input and convert it to binary
int result = 0;//the result from each step of the conversion
int base = 1;//used to multiply the remainder by 1, 10, 100 etc
while(decimal > 0){
int remainder = decimal % 2;//takes the remainder of the iteration
decimal = decimal / 2;//halves the decimal number
result = result + (remainder * base);//pseudo concatenation of the binary
base = base * 10;//increases the base multiplier to continue filling out the binary leftward
}
return result;//returns result after loop has finished
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();//scan the input to obtain the decimal number
int binaryForm = conversion(n);//convert the decimal to binary and assign to binaryForm variable
String stringForm = Integer.toString(binaryForm);//convert binaryForm to a String
int counter = 1;
int max = 1;
char testArray[] = stringForm.toCharArray();//send stringForm to fill out testArray
for(int i = 0; i < testArray.length - 1; i++){//loops through testArray to test stringForm values
if(testArray[i] == testArray[i + 1] && testArray[i] == '1'){//if consecutive values equal char 1, increase counter
counter += 1;
if(counter > max){
max = counter;//if counter is higher than current maxCounter, increase maxCounter
}
}
else {//if consecutive values do not equal 1, reset counter
counter = 1;
}
}
System.out.print(max);//print the maximum consecutive values for the decimal input when converted to binary
}
}
You are trying to create a binary representation of a decimal number using an integer. This will work for smaller numbers but it doesn't take long for you to reach an overflow. You should use a string representation of the binary number like so
String numBin = "";
while(num > 0)
{
numBin = num % 2 + numBin;
num = num / 2;
}
System.out.println("Binary Representation: " + numBin);
Then take that string and loop through it calculating the consecutive counts of 1's
int consecutiveCount = 0;
for(int i = 0; i < numBin.length() - 1; i++)
{
if(numBin.charAt(i) == '1' && numBin.charAt(i + 1) == '1')
{
consecutiveCount++;
}
}
System.out.println("Consecutive Count: " + consecutiveCount);
Output
Number: 261141
Binary Representation: 111111110000010101
Consecutive Count: 7
Number: 3
Binary Representation: 11
Consecutive Count: 1
Number: 18
Binary Representation: 10010
Consecutive Count: 0
Number: 1111111
Binary Representation: 100001111010001000111
Consecutive Count: 5

Binary complement 0 to 1, 1 to 0

I have a number , let say 4 which is in binary represented as 100 , what i will like to achieve is to complement the number i.e. replace 1 by 0 and 0 by 1 . I can achieve it like this
public class Foo {
public static void main(String[] args) {
String binaryString = Integer.toBinaryString(4);
StringBuilder out = new StringBuilder();
char[] chars = binaryString.toCharArray();
char x;
for (char ch : chars) {
if (ch == '1') {
x = '0';
} else {
x = '1';
}
out.append(x);
}
System.out.println(Integer.parseInt(out.toString(), 2));
}
}
What is the most efficient way to achieve the same result in terms of time complexity? Please note that input can be very big numbers and we need to take care of Integer overflow.
Updated
negating a number like ~n will give wrong result , for e.g.
System.out.println(~4);
outputs -5 , expected 3
What is the most efficient way to achieve the same result in terms of time complexity?
Given that the size of int is fixed at 32, the time complexity is O(1). Your program is pretty inefficient, though, because it creates a coupe of strings, does string parsing, and so on.
You can do this faster if you skip the conversion to binary altogether, and simply invert the number, like this:
int val = 4;
int msb = int msb = 32 - Integer.numberOfLeadingZeros(val);
int inverse = ~val & ((1 << msb)-1);
System.out.println(inverse);
The ~ operator is a unary operator that produces a binary complement of the value. The loop computes the position of the most significant bit (MSB). ((1 << msb)-1) is a mask that removes all bits higher than the MSB.
Demo.
You can try using bitwise negation:
private int flipBits(int n) {
return ~n;
}
Why not do something like this:
public static void main(String[] args) {
String binaryString = Integer.toBinaryString(4);
binaryString = binaryString.replaceAll("1", "-");
binaryString = binaryString.replaceAll("0", "1");
binaryString = binaryString.replaceAll("-", "0");
Only 3 lines of code to convert...
BigInteger allows you to use a number of arbitrary length. The way to find the negation is to find the max value possible given the input length and substract the input value from it
//you might want to validate that the string really is a binary number string
BigInteger myNum = new BigInteger(inputStr, 2);
BigInteger max = new BigInteger("2");
max = max.pow(inputStr.length()).subtract(new BigInteger("1"));
BigInteger ans = max.substract(myNum);

Categories