Store all odd numbers between -6 and 38 into an array - java

I'm doing some Java exercises, and this was one of them. I did this:
int odds[] = new int[22];
int storedNo = -5;
for (int i = 0; i < odds.length; i++) {
odds[i] = storedNo;
storedNo += 2;
}
Which works. But, I looked at the answer and it said to do this:
int[] odds = new int[22];
for (int i = 0; i < 22; i++) {
odds[i] = i * 2 - 5;
}
My question is, how did they arrive at that answer?, specifically the i * 2 - 5 part? I don't get how to think of the math to get that answer.

A simple way to think about it is that it evaluates the equation y = 2x - 5 for integer values x in [0, 21].
How did they arrive at this solution? One way is to look at the first and last points. We know the first odd number is at x = 0, y = -5 and the last is at x = 21, y = 37. Two points is sufficient to solve for a linear equation y = mx + b:
From the first point we have
(-5) = m(0) + b
=> b = -5
From the second point we have
(37) = m(21) + b
=> 37 = 21m - 5
=> 21m = 42
=> m = 2
Thus our solution is y = 2x - 5. This also follows the intuitive observation that successive odd numbers have a difference of 2, and the y-intercept of the line should be the smallest number.

Just follow the math to see how it works. The first odd number you have is -5, so doing i*2 - 5 gives you -5 to start out when your loop variable is 0. When i increases by 1 on each loop iteration, you're going to have a result that's 2 greater than the previous.
0 * 2 - 5 = -5
1 * 2 - 5 = -3
2 * 2 - 5 = -1
...
21 * 2 -5 = 37

Related

Arithmetic Operations -Java

class Example {
public static void main(String args[]){
System.out.println(12+8/5%4*(5-4/5)+4*5);
}
}
Why the output is 37? Can anyone explain? I'm a beginner in java
Check the precedence of the operators in java:
12+8/5%4*(5-4/5)+4*5
12+8/5%4*(5-0)+4*5
12+8/5%4*5+4*5
12+1%4*5+4*5
12+1*5+4*5
12+5+20
37
You have: 12+8/5%4*(5-4/5)+4*5
In the post of user3134614
12+8/5%4*(5-4/5)+4*5
12+8/5%4*(5-0)
12+8/5%4*5+4*5
12+1%4*5+4*5
12+1*5+4*5
12+5+20
37
You have the basic operators
+ add two numbers
- subtract two numbers
* Multiply two numbers
/ divide two numbers
And these, a little more advanced
% gets the remainder of two numbers, that is, that divides them and obtains the remainder, if the number is even, then the rest is zero, and if it is odd, it is another number
For example 4%4 would be 4 divided by 4 results in 2 and 2 + 2 = 4, there is no remainder, on the other hand 5%4 = 1, because 2 + 2 = 4 and over 1 of 5
The parentheses () separate a mathematical expression and return it as a single quantity, example
5 - (3-2) * 2 is equivalent to 5 - (1) * 2 = 5 - 2 = 3
Then
12+8/5%4*(5-4/5)+4*5
12+8/5%4*(5-0) is 12+8/5%4*(5 - (4/5) = 0.8, but converted to integer is 0, then 5 - 0 = 5)
12+8/5%4*5+4*5 is 12+ (8/5 = 1.6, but to integer is 1) %4*5+4*5
12+1%4*5+4*5 is 12+ (1%4 = 1 (1 is different of 4 then result is 1)) *5+4*5
12+1*5+4*5 is 12 + (1*5 = 5) + (4*5 = 20)
12+5+20 and 12 + 5 + 20 = 37
37

Trying to find the number of x's that satisfies n + x = n ^ x fails with timeout

I'm trying to solve the following problem from the section Bit Manipulation at the Hacker Rank site using new features of Java 8 such as Streams.
The problem description:
Given an integer, n, find each x such that:
0 <= x <= n
n + x = n ^ x
where ^ denotes the bitwise XOR operator. Then print an integer denoting the total number of x's satisfying the criteria above.
Constraints
0 <= n <= 1015
Sample Input: 5
Sample Output: 2
Explanation:
For n = 5, the x values 0 and 2 satisfy the conditions:
5 + 0 = 5 ^ 0 = 5
5 + 2 = 5 ^ 2 = 7
Thus, we print 2 as our answer.
Sample Input: 10
Sample Output: 4
Explanation:
For n = 10, the x values 0, 1, 4, and 5 satisfy the conditions:
10 + 0 = 10 ^ 0 = 10
10 + 1 = 10 ^ 1 = 11
10 + 4 = 10 ^ 4 = 14
10 + 5 = 10 ^ 5 = 15
Thus, we print 4 as our answer.
My code is as follows:
public class SumVsXor
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
long n = in.nextLong();
long count = LongStream.rangeClosed(0, n)
.filter(k -> k + n == (k ^ n))
.count();
System.out.println(count);
}
}
The problem is this code doesn't pass all the test cases.
It works for small values of n, but for large values such as 1000000000000000 it fails due to timeout.
I wonder whether LongStream can't handle Streams with that many elements.
The problem with your code is that it is very inefficient. For the case of n==1000000000000000, your Stream pipeline is performing 1,000,000,000,000,000 addition and XOR operations, which takes a long time. Testing for each number between 0 and n whether n + x == n ^ x would take a long time even if you use a for loop instead of Streams.
Instead of checking all the numbers between 0 and n, you should try to figure out a better way to calculate the required total number of x's. That fact that this problem appears under a "Bit Manipulation" section should give you a hint
to look into the bits of numbers that satisfy n + x == n ^ x.
Let's consider the case of n==1000000000000000. The binary representation of that large number is
0000000000000011100011010111111010100100110001101000000000000000
=== == = ====== = = = == == =
--- - - - - -- -- --- - ---------------
~~~~~~~~~~~~~~
In order for n + x to be equal to n ^ x, x must have a 0 value in all the bits corresponding with the 1 bits of n (marked with = above), and either 0 or 1 value in the bits corresponding with the 0 bits of n (marked with - above). This doesn't include the leading 0s (marked with ~ above), since x must be <= n, so any leading 0s in n must also have a 0 value in x.
This means that the total number of x's for which n + x == n ^ x is 2the number of 0s in n, not including leading 0s.
In the case of n = 1000000000000000, there are 30 such 0 bits, so the total number of x's that satisfy the requirement is 230.
Here's one way to compute the total number of x's :
long n = 1000000000000000L;
int zeroBitsCount = 0;
while (n > 0) {
if (n % 2 == 0) {
zeroBitsCount++; // counts the number of non-leading 0 bits
}
n = n >> 1; // divide n by 2 in order to examine the next bit in the next iteration
}
long total = 1L << zeroBitsCount; // the total is 2^(the 0 bits count)
I came to the same result, but via a different explanation, so thought I might post it here.
Eran's answer got to the same conclusion that I did : to modify the zeroes in the binary representation of the initial number - that is pretty straightforward.
Let's suppose our number is
101010100
so it has 5 zeroes.
you need all the possible combinations of:
a single zero
two zeroes
three zeroes
four zeroes
five zeroes
that is actually :
comb(1,5) + comb(2,5) + comb(3,5) + comb(4,5) + comb (5,5)
that is a well known formula being equal to:
pow(2,n) // where n is five in our case
from there the solution is obvious...
This is a simple question if you know little bit about XOR. I don't know much about java. But I can explain in python.
1.First convert the number to binary.
2.Count the number of zeros in that binary number.
3.print 2 ^ (number of zeros) and that's it.
Here is my python code.
n = int(input())
sum = 0
if n!=0:
n=str(bin(n))
for i in range(len(n)):
if n[i]=='0':
sum = sum + 1
print(2**(sum-1))
else: print(1)
The reason to decrement the sum by 1 is, in python it convert the number to the binary as this format. e.g: 0b'10101.
public static void main (String[] args) {
Scanner in = new Scanner (System.in);
long n = in.nextLong();
long count = 1L << (64-Long.bitCount(n)-Long.numberOfLeadingZeros(n));
System.out.println(count);
}

How to stack fruit in a neat pile

I've chosen Java for this case because the language is simple enough for anyone to translate.
What would be the mathematical algorithm to determine the number of fruit required on the bottom line to stack X number of fruits in a pattern like this? (ignoring power of 2's, which I stack in a square)
* 1
* 2 3 = 2
*
* 1 2
* 3 4 5 = 3
*
* 1
* 2 3
* 4 5 6 = 3
*
* 1 2 3
* 4 5 6 7 = 4
*
* 1 2
* 3 4 5
* 6 7 8 9 = 4
*
* 1
* 2 3
* 4 5 6
* 7 8 9 X = 4
*
* 1 2 3
* 3 4 5 6
* 7 8 9 X 1 = 5
Initially I thought it'd be easy, but as the numbers got higher I'm starting to think it's more of a factorial.
Edit: Adding in the code translated from answer provided below by #templatetypedef
private int _getBottomLineCount() {
double insideSquareRoot = (8 * numberOfApples) +1;
double squareRoot = Math.sqrt(insideSquareRoot);
double val = (squareRoot -1) /2;
return (int) Math.ceil(val); // Round it up to nearest whole number
}
The number of fruit in a pyramid of height n is given by the nth triangular number, given by the equation
Tn = n(n + 1) / 2
For example, a pyramid of height 2 holds 2(2 + 1) / 2 = 3 fruit. A pyramid of height 4 holds 4(4 + 1) / 2 = 10 fruit.
If you have k fruit to put into a stack, you're looking for the smallest number n such that Tn ≥ k. You can solve for this directly:
Tn = k
n(n + 1) / 2 = k
n2 + n = 2k
n2 + n - 2k = 0
Using the quadratic formula gives
n = (-1 ±√(1 + 8k)) / 2
The negative root here can be ignored, so your number n should be given by
n = (√(8k + 1) - 1) / 2
This number might be not be an integer, in which case you want to round up.
Let's try some examples. Suppose that you have 9 fruit to stack. We can evaluate the formula above to get
n = (√(72 + 1) - 1) / 2 = (√(73) - 1) / 2 = 3.772001873
Rounding up gives k = 4, so you'd need a stack of height 4.
Suppose you have 137 fruit to stack. The same formula gives back n = 16.060495162, so you'd need a stack of height 17 to store the fruit.
Hope this helps!

Unpacking Exponent factors table multiplied packed value back into original values

I have this poker card game where a possible 13 card ranks stored as [0 to 12].
Each hand which holds 5 cards which have 13 possible card ranks.
The final value is a identifier which begins from the exponent 13⁵ (to power of 5).
Which stores what kind of winning hand it is.
Then the remaining 5 powers of 13 are used to store each of the 5 cards.
Also not to mention not all 5 cards are stored at all times, that's only for the High Card win, which requires 4 kickers.
My question is using just the final value how would I be able to unpack every card and what kind of winning hand it was.
/** The ranking factors (powers of 13, the number of ranks). */
private static final int[] RANKING_FACTORS = {371293, 28561, 2197, 169, 13, 1};
rankings[0] = HIGHCARD WIN [0]
rankings[1] = 12; //Ace
rankings[2] = 6; //Eight
rankings[3] = 9; //Jack
rankings[4] = 1; //Three
rankings[5] = 3; //Five
// Calculate value.
for (int i = 0; i < NO_OF_RANKINGS; i++) {
value += rankings[i] * RANKING_FACTORS[i];
}
(0*371293) + (12*28561) + (6*2197) + (9*169) + (1*13) + (3*1) = 357451
Attempting to unpack the values from that 357451 value.
Starting trying to figure out the math here.
if 357451 < 371293 rankings[0] = 0
(357451 / 28561) = 12 rankings[1] = 12
(357451 / 2197) / ((13*2)+1) = 6 rankings[2] = 6
(357451 / 169) / ((13*18)+1) = 9 rankings[3] = 9
//Alright it seems that 18 is from answers (12+6) probably because I haven't subtracted them or something.
//So next one should be (12+6+9)= 27, but it's 2115
(357451 / 13) / ((13*2115)+1) = 1 rankings[4] = 1
(357451 / 1) / ((13*9165)+1) = 3 rankings[5] = 3
I think I figured it out but I don't understand the values Probably also only works for this case will break on any other case.
Don't know where the values 2, 18, 2115, 9165 get generated from probably some crap I made up.
How do I do this the proper way? I don't think I could use shifting since this isn't bitwise.
So its done like this then?
(357451 / 371293) = 0
(357451 / 28561) = 12
(357451 % 28561) / 2197 = 6
(357451 % 2197) / 169 = 9
(357451 % 169) / 13 = 1
(357451 % 13) = 3
You're correct through this part..
(357451 / 28561) = 12 rankings[1] = 12
But this is no good...
(357451 / 2197) / ((13*2)+1) = 6 rankings[2] = 6
You need to take your result 12 and multiply it back to 28561 then subtract that from 357451 to see what was left over. In this case it's 14719.
Now you can continue using that number instead of 357451. So 14719 / 2197 = 6.
Continue that pattern (14719 - (2197*6)) until you have your 5 numbers.
(357451 % 28561) will also get you the remainder, if you want to do it that way.
My "decode" code...
private static final int[] RANKING_FACTORS = {4826809, 371293, 28561, 2197, 169, 13, 1};
#Test
public void testDecode() {
long value = 357451;
int[] rankings = new int[6];
//System.out.println(Math.max(0,value-RANKING_FACTORS[0]));
for (int i=0; i < rankings.length; i++) {
rankings[i] = (int)(value / RANKING_FACTORS[i]);
value %= RANKING_FACTORS[i];
System.out.println(rankings[i]);
}
}

Linear Recurrence for very large n

I was trying to solve this problem on SPOJ (http://www.spoj.pl/problems/REC/)
F(n) = a*F(n-1) + b where we have to find F(n) Mod (m)
where
0 <= a, b, n <= 10^100
1 <= M <= 100000
F(0)=1
I am trying to solve it with BigInteger in JAVA but if I run a loop from 0 to n its getting TLE. How could I solve this problem? Can anyone give some hint? Don't post the solution. I want hint on how to solve it efficiently.
Note that the pattern of residues mod (m) should have a repeating pattern in a linear recurrence, and with length <= m by the pigeonhole principle. You need only calculate the first m entries, then figure out which of those entries will apply to F(n) for the actual value of n.
It also helps to solve a simpler problem. Let's pick really small values, say a=2, b=1, m=5, n=1000.
F(0) = 1
F(1) = 2*F(0) + 1 = 2*1 + 1 = 3 -> 3 Mod 5 = 3
F(2) = 2*F(1) + 1 = 2*3 + 1 = 7 -> 7 Mod 5 = 2
F(3) = 2*F(2) + 1 = 2*7 + 1 = 15 -> 15 Mod 5 = 0
F(4) = 2*F(3) + 1 = 2*15 + 1 = 31 -> 31 Mod 5 = 1
F(5) = 2*F(4) + 1 = 2*31 + 1 = 63 -> 63 Mod 5 = 3
etc.
Notice that the residues are [1, 3, 2, 0, 1, 3, ...], which will repeat forever. So from this example, how would you determine F(1000) Mod 5 without looping all the way to the 1000th entry?
First, I'll tell you how to solve a simpler problem. Suppose that b is zero. Then you just need to calculate an mod M. Instead of multiplying n-1 times, use a divide-and-conquer technique:
// Requires n >= 0 and M > 0.
int modularPower(int a, int n, int M) {
if (n == 0)
return 1;
int result = modularPower(a, n / 2, M);
result = (result * result) % M;
if (n % 2 != 0)
result = (result * a) % M;
return result;
}
So you can calculate an in terms of afloor(n/2), then square that, and multiply by a again if n is odd.
To solve your problem, first define the function f(x) = (a x + b) (mod M). You need to calculate fn(1), which is applying f n times to the initial value 1. So you can use divide-and-conquer like the previous problem. Luckily, the composition of two linear functions is also linear. You can represent a linear function by three integers (the two constants and the modulus). Write a function that takes a linear function and an exponent and returns the function composed that many times.

Categories

Resources