This image describes the Add Em Up! question from Kattis I was about to solve. Give me some ideas that I could employ while doing it.
I am stuck at how to edit such that the 2 or 5 can be inverted in an integer form.
How can I change a number 1223 or 152 whereby I can replace 2 by 5 or 5 by 2 so it becomes 1523 or 1553 and 125 or 122?
The problem description on this one is unclear. It seems like it's asking you to rotate the cards as you would physically, which entails replacing 6s and 9s, but that replacement never seems to be tested. You can get away with simply reversing the digits in the numbers.
To make matters worse, there's no sample test case with a 3, 4 or 7, which have no sensible representation in flipped form. Intuitively, these flips should be disregarded, and that intuition turns out to be true in the Kattis test suite.
Another edge case is what to do about 10 or 2100. These reverse to 1 and 12 respectively and shouldn't be ignored.
I am stuck at how to edit such that the 2 or 5 can be inverted in an integer form.
After spinning a card physically, 2 stays 2 and 5 stays 5. Only 6 and 9 would change values on a flip, and Kattis doesn't test those at this time. 2 and 5 mirror each other horizontally, but that's not relevant here.
After clarifying the requirements, the problem pretty much boils down to two sum with a reversal tossed in on certain numbers:
Create an empty lookup table
For each number in the input:
If lookup.contains(targetSum - newInputValue), then you found a sum
Otherwise, if 3, 4 and 7 aren't present in the string, do the following:
Produce the "flipped" value of the number by either operating on the digits or reversing the number as a string
If lookup.contains(targetSum - newInputValueFlipped), then you found a sum
Add the flipped value to the lookup table
Add the new input value to the lookup table
An "obvious" optimization is to cache each completed flip in a lookup table but it's not necessary to pass the challenge.
You can convert that number into string first
String str = "" + 123
StringBuilder myName = new StringBuilder(str);
Build a if condition inside a for loop and check for the given num 2 or 5 then replace the given number.
myName.setCharAt(i, '5');
I understand Big-O notation, but I don't know how to calculate it for many functions. In particular, I've been trying to figure out the computational complexity of the naive version of the Fibonacci sequence:
int Fibonacci(int n)
{
if (n <= 1)
return n;
else
return Fibonacci(n - 1) + Fibonacci(n - 2);
}
What is the computational complexity of the Fibonacci sequence and how is it calculated?
You model the time function to calculate Fib(n) as sum of time to calculate Fib(n-1) plus the time to calculate Fib(n-2) plus the time to add them together (O(1)). This is assuming that repeated evaluations of the same Fib(n) take the same time - i.e. no memoization is used.
T(n<=1) = O(1)
T(n) = T(n-1) + T(n-2) + O(1)
You solve this recurrence relation (using generating functions, for instance) and you'll end up with the answer.
Alternatively, you can draw the recursion tree, which will have depth n and intuitively figure out that this function is asymptotically O(2n). You can then prove your conjecture by induction.
Base: n = 1 is obvious
Assume T(n-1) = O(2n-1), therefore
T(n) = T(n-1) + T(n-2) + O(1) which is equal to
T(n) = O(2n-1) + O(2n-2) + O(1) = O(2n)
However, as noted in a comment, this is not the tight bound. An interesting fact about this function is that the T(n) is asymptotically the same as the value of Fib(n) since both are defined as
f(n) = f(n-1) + f(n-2).
The leaves of the recursion tree will always return 1. The value of Fib(n) is sum of all values returned by the leaves in the recursion tree which is equal to the count of leaves. Since each leaf will take O(1) to compute, T(n) is equal to Fib(n) x O(1). Consequently, the tight bound for this function is the Fibonacci sequence itself (~θ(1.6n)). You can find out this tight bound by using generating functions as I'd mentioned above.
Just ask yourself how many statements need to execute for F(n) to complete.
For F(1), the answer is 1 (the first part of the conditional).
For F(n), the answer is F(n-1) + F(n-2).
So what function satisfies these rules? Try an (a > 1):
an == a(n-1) + a(n-2)
Divide through by a(n-2):
a2 == a + 1
Solve for a and you get (1+sqrt(5))/2 = 1.6180339887, otherwise known as the golden ratio.
So it takes exponential time.
I agree with pgaur and rickerbh, recursive-fibonacci's complexity is O(2^n).
I came to the same conclusion by a rather simplistic but I believe still valid reasoning.
First, it's all about figuring out how many times recursive fibonacci function ( F() from now on ) gets called when calculating the Nth fibonacci number. If it gets called once per number in the sequence 0 to n, then we have O(n), if it gets called n times for each number, then we get O(n*n), or O(n^2), and so on.
So, when F() is called for a number n, the number of times F() is called for a given number between 0 and n-1 grows as we approach 0.
As a first impression, it seems to me that if we put it in a visual way, drawing a unit per time F() is called for a given number, wet get a sort of pyramid shape (that is, if we center units horizontally). Something like this:
n *
n-1 **
n-2 ****
...
2 ***********
1 ******************
0 ***************************
Now, the question is, how fast is the base of this pyramid enlarging as n grows?
Let's take a real case, for instance F(6)
F(6) * <-- only once
F(5) * <-- only once too
F(4) **
F(3) ****
F(2) ********
F(1) **************** <-- 16
F(0) ******************************** <-- 32
We see F(0) gets called 32 times, which is 2^5, which for this sample case is 2^(n-1).
Now, we want to know how many times F(x) gets called at all, and we can see the number of times F(0) is called is only a part of that.
If we mentally move all the *'s from F(6) to F(2) lines into F(1) line, we see that F(1) and F(0) lines are now equal in length. Which means, total times F() gets called when n=6 is 2x32=64=2^6.
Now, in terms of complexity:
O( F(6) ) = O(2^6)
O( F(n) ) = O(2^n)
There's a very nice discussion of this specific problem over at MIT. On page 5, they make the point that, if you assume that an addition takes one computational unit, the time required to compute Fib(N) is very closely related to the result of Fib(N).
As a result, you can skip directly to the very close approximation of the Fibonacci series:
Fib(N) = (1/sqrt(5)) * 1.618^(N+1) (approximately)
and say, therefore, that the worst case performance of the naive algorithm is
O((1/sqrt(5)) * 1.618^(N+1)) = O(1.618^(N+1))
PS: There is a discussion of the closed form expression of the Nth Fibonacci number over at Wikipedia if you'd like more information.
You can expand it and have a visulization
T(n) = T(n-1) + T(n-2) <
T(n-1) + T(n-1)
= 2*T(n-1)
= 2*2*T(n-2)
= 2*2*2*T(n-3)
....
= 2^i*T(n-i)
...
==> O(2^n)
Recursive algorithm's time complexity can be better estimated by drawing recursion tree, In this case the recurrence relation for drawing recursion tree would be T(n)=T(n-1)+T(n-2)+O(1)
note that each step takes O(1) meaning constant time,since it does only one comparison to check value of n in if block.Recursion tree would look like
n
(n-1) (n-2)
(n-2)(n-3) (n-3)(n-4) ...so on
Here lets say each level of above tree is denoted by i
hence,
i
0 n
1 (n-1) (n-2)
2 (n-2) (n-3) (n-3) (n-4)
3 (n-3)(n-4) (n-4)(n-5) (n-4)(n-5) (n-5)(n-6)
lets say at particular value of i, the tree ends, that case would be when n-i=1, hence i=n-1, meaning that the height of the tree is n-1.
Now lets see how much work is done for each of n layers in tree.Note that each step takes O(1) time as stated in recurrence relation.
2^0=1 n
2^1=2 (n-1) (n-2)
2^2=4 (n-2) (n-3) (n-3) (n-4)
2^3=8 (n-3)(n-4) (n-4)(n-5) (n-4)(n-5) (n-5)(n-6) ..so on
2^i for ith level
since i=n-1 is height of the tree work done at each level will be
i work
1 2^1
2 2^2
3 2^3..so on
Hence total work done will sum of work done at each level, hence it will be 2^0+2^1+2^2+2^3...+2^(n-1) since i=n-1.
By geometric series this sum is 2^n, Hence total time complexity here is O(2^n)
The proof answers are good, but I always have to do a few iterations by hand to really convince myself. So I drew out a small calling tree on my whiteboard, and started counting the nodes. I split my counts out into total nodes, leaf nodes, and interior nodes. Here's what I got:
IN | OUT | TOT | LEAF | INT
1 | 1 | 1 | 1 | 0
2 | 1 | 1 | 1 | 0
3 | 2 | 3 | 2 | 1
4 | 3 | 5 | 3 | 2
5 | 5 | 9 | 5 | 4
6 | 8 | 15 | 8 | 7
7 | 13 | 25 | 13 | 12
8 | 21 | 41 | 21 | 20
9 | 34 | 67 | 34 | 33
10 | 55 | 109 | 55 | 54
What immediately leaps out is that the number of leaf nodes is fib(n). What took a few more iterations to notice is that the number of interior nodes is fib(n) - 1. Therefore the total number of nodes is 2 * fib(n) - 1.
Since you drop the coefficients when classifying computational complexity, the final answer is θ(fib(n)).
It is bounded on the lower end by 2^(n/2) and on the upper end by 2^n (as noted in other comments). And an interesting fact of that recursive implementation is that it has a tight asymptotic bound of Fib(n) itself. These facts can be summarized:
T(n) = Ω(2^(n/2)) (lower bound)
T(n) = O(2^n) (upper bound)
T(n) = Θ(Fib(n)) (tight bound)
The tight bound can be reduced further using its closed form if you like.
It is simple to calculate by diagramming function calls. Simply add the function calls for each value of n and look at how the number grows.
The Big O is O(Z^n) where Z is the golden ratio or about 1.62.
Both the Leonardo numbers and the Fibonacci numbers approach this ratio as we increase n.
Unlike other Big O questions there is no variability in the input and both the algorithm and implementation of the algorithm are clearly defined.
There is no need for a bunch of complex math. Simply diagram out the function calls below and fit a function to the numbers.
Or if you are familiar with the golden ratio you will recognize it as such.
This answer is more correct than the accepted answer which claims that it will approach f(n) = 2^n. It never will. It will approach f(n) = golden_ratio^n.
2 (2 -> 1, 0)
4 (3 -> 2, 1) (2 -> 1, 0)
8 (4 -> 3, 2) (3 -> 2, 1) (2 -> 1, 0)
(2 -> 1, 0)
14 (5 -> 4, 3) (4 -> 3, 2) (3 -> 2, 1) (2 -> 1, 0)
(2 -> 1, 0)
(3 -> 2, 1) (2 -> 1, 0)
22 (6 -> 5, 4)
(5 -> 4, 3) (4 -> 3, 2) (3 -> 2, 1) (2 -> 1, 0)
(2 -> 1, 0)
(3 -> 2, 1) (2 -> 1, 0)
(4 -> 3, 2) (3 -> 2, 1) (2 -> 1, 0)
(2 -> 1, 0)
The naive recursion version of Fibonacci is exponential by design due to repetition in the computation:
At the root you are computing:
F(n) depends on F(n-1) and F(n-2)
F(n-1) depends on F(n-2) again and F(n-3)
F(n-2) depends on F(n-3) again and F(n-4)
then you are having at each level 2 recursive calls that are wasting a lot of data in the calculation, the time function will look like this:
T(n) = T(n-1) + T(n-2) + C, with C constant
T(n-1) = T(n-2) + T(n-3) > T(n-2) then
T(n) > 2*T(n-2)
...
T(n) > 2^(n/2) * T(1) = O(2^(n/2))
This is just a lower bound that for the purpose of your analysis should be enough but the real time function is a factor of a constant by the same Fibonacci formula and the closed form is known to be exponential of the golden ratio.
In addition, you can find optimized versions of Fibonacci using dynamic programming like this:
static int fib(int n)
{
/* memory */
int f[] = new int[n+1];
int i;
/* Init */
f[0] = 0;
f[1] = 1;
/* Fill */
for (i = 2; i <= n; i++)
{
f[i] = f[i-1] + f[i-2];
}
return f[n];
}
That is optimized and do only n steps but is also exponential.
Cost functions are defined from Input size to the number of steps to solve the problem. When you see the dynamic version of Fibonacci (n steps to compute the table) or the easiest algorithm to know if a number is prime (sqrt(n) to analyze the valid divisors of the number). you may think that these algorithms are O(n) or O(sqrt(n)) but this is simply not true for the following reason:
The input to your algorithm is a number: n, using the binary notation the input size for an integer n is log2(n) then doing a variable change of
m = log2(n) // your real input size
let find out the number of steps as a function of the input size
m = log2(n)
2^m = 2^log2(n) = n
then the cost of your algorithm as a function of the input size is:
T(m) = n steps = 2^m steps
and this is why the cost is an exponential.
Well, according to me to it is O(2^n) as in this function only recursion is taking the considerable time (divide and conquer). We see that, the above function will continue in a tree until the leaves are approaches when we reach to the level F(n-(n-1)) i.e. F(1). So, here when we jot down the time complexity encountered at each depth of tree, the summation series is:
1+2+4+.......(n-1)
= 1((2^n)-1)/(2-1)
=2^n -1
that is order of 2^n [ O(2^n) ].
No answer emphasizes probably the fastest and most memory efficient way to calculate the sequence. There is a closed form exact expression for the Fibonacci sequence. It can be found by using generating functions or by using linear algebra as I will now do.
Let f_1,f_2, ... be the Fibonacci sequence with f_1 = f_2 = 1. Now consider a sequence of two dimensional vectors
f_1 , f_2 , f_3 , ...
f_2 , f_3 , f_4 , ...
Observe that the next element v_{n+1} in the vector sequence is M.v_{n} where M is a 2x2 matrix given by
M = [0 1]
[1 1]
due to f_{n+1} = f_{n+1} and f_{n+2} = f_{n} + f_{n+1}
M is diagonalizable over complex numbers (in fact diagonalizable over the reals as well, but this is not usually the case). There are two distinct eigenvectors of M given by
1 1
x_1 x_2
where x_1 = (1+sqrt(5))/2 and x_2 = (1-sqrt(5))/2 are the distinct solutions to the polynomial equation x*x-x-1 = 0. The corresponding eigenvalues are x_1 and x_2. Think of M as a linear transformation and change your basis to see that it is equivalent to
D = [x_1 0]
[0 x_2]
In order to find f_n find v_n and look at the first coordinate. To find v_n apply M n-1 times to v_1. But applying M n-1 times is easy, just think of it as D. Then using linearity one can find
f_n = 1/sqrt(5)*(x_1^n-x_2^n)
Since the norm of x_2 is smaller than 1, the corresponding term vanishes as n tends to infinity; therefore, obtaining the greatest integer smaller than (x_1^n)/sqrt(5) is enough to find the answer exactly. By making use of the trick of repeatedly squaring, this can be done using only O(log_2(n)) multiplication (and addition) operations. Memory complexity is even more impressive because it can be implemented in a way that you always need to hold at most 1 number in memory whose value is smaller than the answer. However, since this number is not a natural number, memory complexity here changes depending on whether if you use fixed bits to represent each number (hence do calculations with error)(O(1) memory complexity this case) or use a better model like Turing machines, in which case some more analysis is needed.
I had a technical phone interview and I was doing well until i was asked this question. I was totally lost i had very little idea on how to solve such a problem.
You are given the following inputs: Total Score, Number of Players, Scores by each player. Sample Input would be
10 4 3 5 5 7
Where
10 = Total Score
4 = 4 players
3 = Score by player 1
5 = Score by player 2
5 = Score by player 3
7 = Score by player 4
You are to print out any combination that equals the total score. For instance we know player 4 and player 1 can have combine score of total score 10. So output for the above answer would be
1 4
1 = INDEX of player 1 4 = INDEX of player 4. Yes i know index of player 1 is technically 0 but they said print it out as such. If no combination matched you can print out none or anything you like . That didn't matter.
MY ATTEMPT
Well rather than being silent i first told interviewer i can use brute force approach to solve this. He said of course but we need better run time.
So i started thinking we could find all the possible combinations that could lead the total dollar and use MEMOIZATION to store the previously stored values. I was not able to think of a way of generating all combos and so i got stuck there.
Update
He also mentioned the maximum score i can give you is 1000. I am not even sure why this matters?
I would appreciate if someone can stir me in right direction or even provide pseudo/working java sample of how to solve such a problem. I think this is a generic problem and i really wanna understand how to solve this problem
This is the subset sum problem, and assuming your scores are relatively small integers, it can be solved in pseudo-polynomial time using DP:
D(i,0) = 1
D(0,x) = 0 x > 0
D(i,x) = D(i-1, x) + D(i-1, x-arr[i])
The above recursion formulas will generate the matrix of size total_score X num_players. The number of possible combination is denoted in the bottom right entry of the matrix.
The idea is to mimic an exhaustive search, for each person you can either add it or not add it, and invoke the recurse to a smaller problem.
Pseudo code for DP solution:
Input:
let W be the total score
let arr be the array of players scores
let n be the size of arr
Pseudo Code:
declare 2d array D of size W+1 X n+1
//initialization of "borders":
for each i from 0 to n+1:
D[i][0] = 1
for each x from 1 to W+1
D[0][x] = 0
//the DP:
for each i from 1 to n+1:
for each x from 1 to W+1:
if arr[i] < x:
D[i][x] = D[i-1][x]
else:
D[i][x] = D[i-1][x] + D[i-1][x-arr[i]]
//by here you have the matrix D filled up
//the wanted value is D[n][W]
return D[n][W]
I have three categories of input , each with a impact range.
Cat 1 : 20 - 16
Cat 2 : 15 - 5
Cat 3 : 4 -1
I have a file with say N randomly generated categories.
I am trying to take a sum of impact for all the 100 entries through a logic that looks something like this :
// calculate sum of impacts
getSum(){
Generate a random class with seed as current system execution time
for(as many entries in file){
switch(category)
case 1 : i = random input between 20 - 16
case 2 : i = random input between 15 - 5
case 3 : i = random input between 4 - 1
some default case here
sum = sum + i
}
return sum
}
.
.
// loop until you get a desired sum
while(true){
if(Call to getSum() returns value within a desired range){
display some statistics;
break;
}
}
However , i see that the program generally runs infinitely , as the random generation and subsequent summation is giving result beyond the desired range. So , to get things in range , I have to manually tune the max-min ranges for each execution.
Can someone suggest an algorithm that will automatically vary the max min ranges for each category , by learning the trend of obtained sum as the program is running , so as to quickly give a solution ?
Edit : i have just read about the 0/1 knapsack algorithm.. and it seems promising , but unsure if that is the algorithm for this case. Any help would be great.
A couple band-aids:
1) use a long int instead of a regular int t give you a longer range.
2) use an unsigned long, since all of your relevant numbers are positive (then be careful of underflow errors when you subtract.
A couple possible strategies:
1) (This contradicts your question, but it is how things are usually done.) Determine the static maximum for each category, and design to it, using long unsigned int if that is large enough, or some larger data structure as necessary.
2) (This is exactly what you are asking.) Use, and build if necessary, a data structure which expands when an overflow occurs.
Solution for strategy 2:
I will get back to you on this. :)
I'm using Gurobi with java to solve a ILP problem.
I set all and I start the program. But Gurobi doesn't even try to solve my problem and gives my an empty solution all variable set to 0.
During the relaxed step Gurobi shows that the minimum value for the function is -246. This is in contrast with the next step were gurobi shows that the optimal solution is 0.
The output of Gurobi is:
Optimize a model with 8189 rows, 3970 columns and 15011 nonzeros
Variable types: 0 continuous, 3970 integer (0 binary)
0 0 0 1.0E100 -1.0E100 0 0
**** New solution at node 0, obj 0.0
Found heuristic solution: objective 0.0000000
Root relaxation: objective -2.465000e+02, 4288 iterations, 0.08 seconds
Nodes | Current Node | Objective Bounds | Work
Expl Unexpl | Obj Depth IntInf | Incumbent BestBd Gap | It/Node Time
0 0 -246.50000 0 315 0.00000 -246.50000 - - 0s
Cutting planes:
MIR: 907
Explored 0 nodes (5485 simplex iterations) in 0.70 seconds
Thread count was 1 (of 1 available processors)
Optimal solution found (tolerance 1.00e-04)
Best objective 0.000000000000e+00, best bound 0.000000000000e+00, gap 0.0%
Gurobi is reporting that it found an optimal solution. The solution with values of 0 for all the variables is optimal (it's not an "empty solution"). The solution with objective -246.5 is for the relaxed problem. The relaxed problem ignores the constraints forcing variables to take on integer values. The solution with objective value of 0 is the solution to the original problem as you formulated it.
The symptoms you are reporting (an all 0 solution that you clearly don't want) is possibly caused by an inverted objective function. Is it possible that you wanted to maximize instead of minimize?