I am trying to write a function using which I can obtain any natural number in minimum steps. Where I am allowed to add or subtract natural numbers starting from 1.
There the conditions are :
Use a number only once
You are allowed to perform only addition and subtraction.
You are not allowed to escape any digit
Find the value of the integer which has a maximum value to obtain that number.
eg : If I my desired number is 4 then it is obtained as -1+2+3 here answer is 3. In a similar manner if I want 6 then 1+2+3 here answer is 3. For 10= 1+2+3+4 ans is 4.
what I have so far :
What I have so far:
public void step() {
int n = (int)Math.sqrt(position * 2);
k = (position - (((n + 1) * n) / 2));
l = ((((n + 1) * (n + 2)) / 2) - position);
System.out.println(k + " " + l);
System.out.println(n);
p = (l > k ? k : l);
r = (l > k ? n : n + 1);
System.out.println(p + " " + r);
if (k == 0) {
result = n;
} else {
result = r + (2 * p);
} System.out.println("__________" + result + "__________");
}
Ok, lets do it in this way. Consider following binary tree. now you can find sum from each path and take every path with sum=your number(let's say 4). now you can get the maximum value from those. Try to come up with implementation of this. I can help you further, If you try some thing.
0
/ \
-1 1
/ \ / \
-2 2 -2 2
The solution is :
for n=1: = 1
for n=2: = 1+2 => 1+2+3 => 1-2+3
for n=3: = 1+2
for n=4: = 1+2+3 => -1+2+3
for n=5: = 1+2+3 => 1+2+3+4-5
for n=6: = 1+2+3
for n=7: = 1+2+3+4=>1+2+3+4+5=>1+2+3-4+5
for any n, first calculate the S(k)=1+2+3+...+k
where S(k)>n and x=S(k)-n is an even number. Then go flip the + of x/2 to -.
S(k) = (1+k)*k/2 > n
=> k*k + k -2n > 0
=> k > (-1 + sqrt(1+8n))/2
eg, n=7, k > 3.2, then k=4, S(4) = 10, 10-7=3, it's odd, so k=5, S(5)=15, x=15-7=8, 8/2=4, flip the sign of 4, we got 1+2+3-4+5 = 7
in some cases, Sk-n is odd, but S(k+1)-n is also odd, in this case, we need to use S(k+2).
The code is as follow :
public void step() {
k = (int)Math.ceil(((-1 + Math.sqrt(1 + 8 * n)) / 2));
int Sk = (1 + k) * k / 2;
if ((Sk - n) % 2 != 0) {
k++;
Sk = (1 + k) * k / 2;
if ((Sk - n) % 2 != 0) {
k++;
Sk = (1 + k) * k / 2;
}
}
int i = (Sk - n) / 2;
System.out.println("maximum number is : " + k + "the number with -ve sign is : " + i);
}
Related
Why is it that inside a for loop and calling a recursive function results to the time complexity of O(2^N) not O(N 2^N) of this code below. Basing on the book CTCI.
void allFib(int n){
for (int i = 0; i < n; i++) {
System.out.println(i + ": "+ fib(i));
}
}
int fib(n){
if (n <= 0) return 0;
else if (n == 1) return 1;
return fib(n - 1) + fib(n -2);
}
Think of your recursive function as computing values in a tree.
fib(n)
/\
/ \
fib(n-1) fib(n-2)
If you look carefully for n = 2, there are 3 values to be computed which is 2^(1+1) - 1 = 3 where 1 here is the height of the tree as in2^(h+1)-1
for n = 3, the height is h = 2
for n = 4, the height is h = 3
For all n, you need to add all of those:
2^2 - 1 + 2^3 - 1 + 2^4 - 1 + ....2^n - 1 -> is of the order of 2^(n+1)
Hence you get O(2^n)
Why does this code generate the result 4.0?
public class Liebniz1 {
public static void main(String[] args) {
double piOverFour = 0;
for (int i = 0; i < 500; i++) {
if (i % 2 == 0)
piOverFour = piOverFour + 1 / (1 + 2 * i);
else
piOverFour = piOverFour - 1 / (1 + 2 * i);
} // for
System.out.println("Liebniz calculated pi to: " + 4 * piOverFour);
}
}
Explanation: 1 / (1 + 2 * i) is 1 for i=0, that means piOverFour will be 1 after the first iteration.
1 / (1 + 2 * i) will always be 0 for i > 0 due to integer division.
That means piOverFour will always remain 1 => 4 * piOverFour will always be 4.
Solution: Use 1.0 / (1 + 2 * i) to circumvent integer division.
Question
Given N and M, write an equation using left shift operators whose
result will be equal to the product N * M.
Input : First line has 0 < T ≤ 50000 denoting number of test cases.
Next T lines have two integers 0 < N, M ≤ 10¹⁶.
Output : For each test case print an equation for N * M resembling
(N << p1) + (N << p2)+ ...+(N << pk) where p1 ≥ p2 ≥ ... ≥ pk
and k is minimum.
SAMPLE INPUT SAMPLE OUTPUT
2
2 1 (2<<0)
2 3 (2<<1) + (2<<0)
Time Limit: 1.0 sec
My Solution 1st approach
int dig = (int)(Math.floor(Math.log10(m)/Math.log10(2))+1);
boolean flag = false;
for(long i = dig; i>=0; --i) {
if(((m>>(i-1l)) & 1l) == 1l) {
if(flag)
System.out.print(" + ("+n+ "<<"+(i-1)+")");
else {
System.out.print("("+n+"<<"+(i-1)+")");
flag = true;
}
}
}
Second Approach
boolean[] arr = new boolean[dig];
int i = dig-1;
while(m > 0) {
if((m&1) == 1 ) {
arr[i] = true;
}
i--;
m = m>>1l;
}
int j = dig-1;
for( i = 0; i < dig; ++i) {
if(arr[i]) {
if(flag)
System.out.print(" + ("+n+"<<"+j+")");
else {
System.out.print("("+n+"<<"+j+")");
flag = true;
}
}
j--;
}
In both cases I am getting 5 correct out of 8 and rest 3 are TLE why?
I don't actually see anything in both of your approaches preventing some ten-thousands of products of numbers up to 57 bit to be represented as Strings in one second:
TLE may be due to System.out.print() taking an inordinate amount of time.
That said, use a utility like
/** builds <code>n * m</code> in the form
* <code>(n<<p1) + (n<<p2) + ... + (n<<pk)</code>
* using left shift.
* #param n (0 < multiplicand <= 10**16)
* #param m 0 < multiplier <= 10**16
* #return a verbose <code>String</code> for <code>n * m</code>
*/
static String verboseBinaryProduct(Object n, long m) {
int shift = Long.SIZE - Long.numberOfLeadingZeros(m) - 1;
final long highest = 1 << shift;
final StringBuilder binary = new StringBuilder(42);
final String chatter = ") + (" + n + "<<";
final long rest = highest - 1;
while (true) {
if (0 != (highest & m))
binary.append(chatter).append(shift);
if (0 == (rest & m)) {
binary.append(')');
return binary.substring(4);
}
m <<= 1;
shift -= 1;
}
}
and System.out.println(verboseBinaryProduct(n, m));.
While reading this book I came across converting binary to integer.
The code that is given by the book is:
// convert a String of 0's and 1's into an integer
public static int fromBinaryString(String s) {
int result = 0;
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (c == '0') result = 2 * result;
else if (c == '1') result = 2 * result + 1;
}
return result;
}
and the way I solved the problem is:
public static int fromBinary(String s) {
int result = 0;
int powerOfTwo = 0;
for (int i = s.length() - 1; i >= 0; i--) {
if ('1' == s.charAt(i)) {
result += Math.pow(2, powerOfTwo);
}
powerOfTwo++;
}
return result;
}
I know my code has an extra counter and it is probably a bit slowly but the way I implement the solution is by following the polynomial definition
x = xn b^n + xn-1 b^n-1 + ... + x1 b^1 + x0 b^0.
What I don't understand is how their's solution works ?
I've already debugged but still can't find what is key. Can someone explain ?
They basically shift the result with 2 * result and add 1 if the bit is set.
Example: 01101
1. iteration: result = 0 -> result * 2 = 0 (same as binary 00000)
2. iteration: result = 0 -> result * 2 + 1 = 1 (same as binary 00001)
3. iteration: result = 1 -> result * 2 + 1 = 3 (same as binary 00011)
4. iteration: result = 3 -> result * 2 = 6 (same as binary 00110)
5. iteration: result = 6 -> result * 2 + 1 = 13 (same as binary 01101)
In terms of bits: 8 + 4 + 1 = 13
Alternatively you could replace result = result * 2 with result <<= 1 but adding 1 in a single statement would not work then. You could write result = (result << 1) + 1 but that's longer and harder to read than the multiplication.
Copying your polynomial definition x = xn b^n + xn-1 b^n-1 + ... + x1 b^1 + x0 b^0 you can rewrite this to
x = ((((...(((( xn * b + xn-1 ) * b + ... )* b + x1 ) * b + x0
where you have b=2 for binary representation and you have n-1 parenthesis opening on the left most side.
For n=4 this reads like
x = ((((x3*2)+x2)*2+x1)*2+x0 = x3 * 2^3 + x2 * 2^2 + x1 * 2^1 + x0 * 2^0
If you are parsing the string begining with the MSB (x_n) towards LSB (x_0), when reading x_i you will have to execute
result = result * 2 + x_i
Before executing this result would have stored the value
((...(((( xn * b + xn-1 ) * b + ... )* b + x_(i+1) )
After executing this result would have stored the value
((...(((( xn * b + xn-1 ) * b + ... )* b + x_i )
Reasoning by induction you can prove you compute the correct answer in the end.
I am trying to calculate partitions of a natural number using the formula below. The formula generates two positive numbers, then two negative and so on. You stop when P(n) < 0 An example is
p(3) = p(2) + p(1) = 3
p(4) = p(3) + p(2) = 3 + 2 = 5
p(5) = p(4) + p(3) - p(0) = 5 + 3 - 1 = 7
p(6) = p(5) + p(4) - p(1) = 7 + 5 - 1 = 11
*P(0) = 1 by convention
In other words in order to calculate say P(5) you would have to calculate P(4) which equals P(3) + P(2) and and P(3) which equals P(2) + P(1) and finally - P(0) which equals 1. You would have to traverse down for each to find what they equal and then sum them. So to find a partition of a number you would have to find the partitions of all other numbers each. I have tried something as you can see the code below but it does not work. k = counter in my code.
Code:
public static long SerialFib( long n )
{
long exponent = 0;
double ex;
long counter = 1;
ex = Math.pow(-1, counter - 1);
exponent = (long) ex;
if (n < 0)
{
return 0;
}
else
{
return SerialFib((exponent * (n - ( (counter * ( (3 * counter) - 1)) /
2)))) + SerialFib((exponent * (n - ( (counter * ( (3 * counter) +1))/2))));
}
}
Counter is going to always be 1 because you aren't passing it back into SerialFib. Also, you need a base case for when n is equal to 0 it will return 1.
first base case:
if(n==0)
return 1;
SerialFib should have another parameter for counter:
SerialFib(long n, int counter)
When you call SerialFib it should look like:
SerialFib( [your formula], ++counter);