Unique combinations of numbers that add up to a sum - algorithm

I was asked this in an interview recently and got completely stumped. I know there are questions like this asked on here before but none handled the little twist thrown onto this one.
Given a number, find all possible ways you can add up to it using only the numbers 1,2,3. So for an input of 3, the output would be 4 because the combinations would be 1,1,1 and 1,2 and 2,1 and 3. I know about the coin change algorithm but it doesn't give me that permutation of 1,2 and 2,1. So I just ended up implementing the coin change algorithm and couldn't get the permutation part. Does anybody have any ideas?

It's a recursive problem:
take for example the possible options for 5
X X X X X
1 X X X X
2 X X X
3 X X
So
f(5)=f(4) + f(3) + f(2)
So the generic solution is
f(1)=1
f(2)=2
f(3)=4
f(N)= f(N-1) + f(N-2) + f(N-3) for N > 3

To answer your question about classification of the problem it looks like dynamic programming problem to me. See following question taken from stanford.edu
1-dimensional DP Example
◮ Problem: given n, find the number of different ways to write
n as the sum of 1, 3, 4
◮ Example: for n = 5, the answer is 6
5 = 1 + 1 + 1 + 1 + 1
= 1 + 1 + 3
= 1 + 3 + 1
= 3 + 1 + 1
= 1 + 4
= 4 + 1
And here is the solution to similar problem

Related

How do I find the number of ways to place blocks of length 1 and 3, in a walkway, using recursion?

I have been given the following problem. Given a walkway of length n, design a recursive algorithm that tells the number of ways to place blocks of size 1 and size 3 on the walkway. I understand the strategy to apply recursion to this problem -
Put in base cases for cases where the walkway is of lengths 1, 2, and 3.
Assume that you already have figured out the number of ways to place blocks of length 1 on the walkway
Assume that you already have figured out the number of ways to place blocks of length 3 on the walkway
Add 2) and 3)
My problem is that I don't know how to code 2) and 3). Here's my code below -
def countPatterns(n):
if(n==1 or n==2):
return 1
elif(n==3):
return 2
elif(n<1):
return 0
else:
# return 2) and 3)
This problem is the same as given the target sum and you need to count number of ways that you can get that target sum just by adding numbers 1 and 3.
Example:
sum = 4
ways:
1: 1 + 1 + 1 + 1
2: 1 + 3
3: 3 + 1
So your function for sum = 4 should return 3.
I think your approach is wrong. Here is my solution:
def numWays(tSum):
if tSum < 0:
return 0
if tSum <= 2:
return 1
return numWays(tSum - 1) + numWays(tSum - 3)

What is the most efficient algorithm for solving the cell-sum puzzle?

The cell-sum puzzle is defined as follows:
Given two sets of non-negative integers X = {x1, x2,...,xm} and Y = {y1, y2,...,yn}, fill each cell in a grid of m rows and n columns with a single non-negative integer such that xi is the sum of the cells in the ith row for every i ≤ m and such that yj is the sum of the cells in the jth column for every j ≤ n.
For example, if X = {7, 13} and Y = {8, 9, 3}, then your goal would be to replace the question marks in the following grid:
? + ? + ? = 7
+ + +
? + ? + ? = 13
= = =
8 9 3
and a valid solution would be:
3 + 1 + 3 = 7
+ + +
5 + 8 + 0 = 13
= = =
8 9 3
How do you solve this puzzle for arbitrarily large m and n? Also, for your method of choice, do you know the time complexity, and can you tell whether it is the most efficient algorithm possible?
Here's a linear-time algorithm (O(m + n) assuming we can output a sparse matrix, which is asymptotically optimal because we have to read the whole input; otherwise O(m n), which is optimal because we have to write the whole output).
Fill in the upper-left question mark with the min of the first row sum and the first column sum. If the first row sum equals the min, put zeros in the rest of the row. If the first column sum equals the min, put zeros in the rest of the column. Extract the subproblem by subtracting the new value from the first row/column if they remain and recurse.
On your example:
? + ? + ? = 7
+ + +
? + ? + ? = 13
= = =
8 9 3
Min of 7 and 8 is 7.
7 + 0 + 0 = 7
+ + +
? + ? + ? = 13
= = =
8 9 3
Extract the subproblem.
? + ? + ? = 13
= = =
1 9 3
Min of 13 and 1 is 1.
1 + ? + ? = 13
= = =
1 9 3
Extract the subproblem.
? + ? = 12
= =
9 3
Keep going until we get the final solution.
7 + 0 + 0 = 7
+ + +
1 + 9 + 3 = 13
= = =
8 9 3
Edit: the problem is not NP-hard. The algorithm in David Eisenstat's answer is provably correct for finding a solution. However, I'll leave this answer here since it gives a way to find all solutions, which might be of interest to some.
For what it's worth, my "method of choice" is constraint programming; it's easy to model this as a constraint satisfaction problem, and then a wide range of well-developed algorithms can be applied. The code below is in Python, using the python-constraint library.
x_sums = [7, 13]
y_sums = [8, 9, 3]
from constraint import *
problem = Problem()
x_n, y_n = len(x_sums), len(y_sums)
max_num = max(x_sums + y_sums)
problem.addVariables(range(x_n * y_n), range(max_num + 1))
for i, x in enumerate(x_sums):
v = [ i + x_n * j for j in range(y_n) ]
problem.addConstraint(ExactSumConstraint(x), v)
for j, y in enumerate(y_sums):
v = [ i + x_n * j for i in range(x_n) ]
problem.addConstraint(ExactSumConstraint(y), v)
solution = problem.getSolution()
for i in range(x_n):
print(*( solution[i + x_n * j] for j in range(y_n) ))
Output: it finds a different solution to yours. Alternatively, you could search for all solutions; there are 26 of them.
4 0 3
4 9 0
The time complexity of this is hard to pin down exactly; as a very weak upper bound we can say it's definitely at most O(max_num ** (x_n * y_n)) since that's the size of the search space. In practice it is much better than that, but the algorithm this library uses is rather complicated and difficult to analyse precisely. It's a backtracking search, but with some clever ways of using the constraints to eliminate the vast majority of branches from the search tree.
For some idea of how deep this rabbit hole goes, the Handbook of Constraint Programming gives a lot of details about techniques that constraint-solving algorithms can use to improve efficiency.

Count the total number ways to reach the nth stair using step 1, 2 or 3 but the step 3 can be taken only once

For any given value N we have to find the number of ways to reach the top while using steps of 1,2 or 3 but we can use 3 steps only once.
for example if n=7
then possible ways could be
[1,1,1,1,1,1,1]
[1,1,1,1,1,2]
etc but we cannot have [3,3,1] or [1,3,3]
I have managed to solve the general case without the constraint of using 3 only once with dynamic programming as it forms a sort of fibonacci series
def countWays(n) :
res = [0] * (n + 1)
res[0] = 1
res[1] = 1
res[2] = 2
for i in range(3, n + 1) :
res[i] = res[i - 1] + res[i - 2] + res[i - 3]
return res[n]
how do I figure out the rest of it?
Let res0[n] be the number of ways to reach n steps without using a 3-step, and let res1[n] be the number of ways to reach n steps after having used a 3-step.
res0[i] and res1[i] are easily calculated from the previous values, in a manner similar to your existing code.
This is an example of a pretty common technique that is often called "graph layering". See, for example: Shortest path in a maze with health loss
Let us first ignore the three steps here. Imagine that we can only use steps of one and two. Then that means that for a given number n. We know that we can solve this with n steps of 1 (one solution), or n-2 steps of 1 and one step of 2 (n-1 solutions); or with n-4 steps of 1 and two steps of 2, which has n-2×n-3/2 solutions, and so on.
The number of ways to do that is related to the Fibonacci sequence. It is clear that the number of ways to construct 0 is one: just the empty list []. It is furthermore clear that the number of ways to construct 1 is one as well: a list [1]. Now we can proof that the number of ways Wn to construct n is the sum of the ways Wn-1 to construct n-1 plus the number of ways Wn-2 to construct n-2. The proof is that we can add a one at the end for each way to construct n-1, and we can add 2 at the end to construct n-2. There are no other options, since otherwise we would introduce duplicates.
The number of ways Wn is thus the same as the Fibonacci number Fn+1 of n+1. We can thus implement a Fibonacci function with caching like:
cache = [0, 1, 1, 2]
def fib(n):
for i in range(len(cache), n+1):
cache.append(cache[i-2] + cache[i-1])
return cache[n]
So now how can we fix this for a given step of three? We can here use a divide and conquer method. We know that if we use a step of three, it means that we have:
1 2 1 … 1 2 3 2 1 2 2 1 2 … 1
\____ ____/ \_______ _____/
v v
sum is m sum is n-m-3
So we can iterate over m, and each time multiply the number of ways to construct the left part (fib(m+1)) and the right part (fib(n-m-3+1)) we here can range with m from 0 to n-3 (both inclusive):
def count_ways(n):
total = 0
for m in range(0, n-2):
total += fib(m+1) * fib(n-m-2)
return total + fib(n+1)
or more compact:
def count_ways(n):
return fib(n+1) + sum(fib(m+1) * fib(n-m-2) for m in range(0, n-2))
This gives us:
>>> count_ways(0) # ()
1
>>> count_ways(1) # (1)
1
>>> count_ways(2) # (2) (1 1)
2
>>> count_ways(3) # (3) (2 1) (1 2) (1 1 1)
4
>>> count_ways(4) # (3 1) (1 3) (2 2) (2 1 1) (1 2 1) (1 1 2) (1 1 1 1)
7

Can someone please explain the use of modulus in this code?

I know that modulus gives the remainder and that this code will give the survivor of the Josephus Problem. I have noticed a pattern that when n mod k = 0, the starting count point begins at the very beginning of the circle and that when n mod k = 1, the person immediately before the beginning of the circle survived that execution round through the circle.
I just don't understand how this recursion uses modulus to find the last man standing and what josephus(n-1,k) is actually referring to. Is it referring to the last person to get executed or the last survivor of a specific round through the circle?
def josephus( n, k):
if n ==1:
return 1
else:
return ((josephus(n-1,k)+k-1) % n)+1
This answer is both a summary of the Josephus Problem and an answer to your questions of:
What is josephus(n-1,k) referring to?
What is the modulus operator being used for?
When calling josephus(n-1,k) that means that you've executed every kth person up to a total of n-1 times. (Changed to match George Tomlinson's comment)
The recursion keeps going until there is 1 person standing, and when the function returns itself to the top, it will return the position that you will have to be in to survive. The modulus operator is being used to help stay within the circle (just as GuyGreer explained in the comments). Here is a picture to help explain:
1 2
6 3
5 4
Let the n = 6 and k = 2 (execute every 2nd person in the circle). First run through the function once and you have executed the 2nd person, the circle becomes:
1 X
6 3
5 4
Continue through the recursion until the last person remains will result in the following sequence:
1 2 1 X 1 X 1 X 1 X X X
6 3 -> 6 3 -> 6 3 -> X 3 -> X X -> X X
5 4 5 4 5 X 5 X 5 X 5 X
When we check the values returned from josephus at n we get the following values:
n = 1 return 1
n = 2 return (1 + 2 - 1) % 2 + 1 = 1
n = 3 return (1 + 2 - 1) % 3 + 1 = 3
n = 4 return (3 + 2 - 1) % 4 + 1 = 1
n = 5 return (1 + 2 - 1) % 5 + 1 = 3
n = 6 return (3 + 2 - 1) % 6 + 1 = 5
Which shows that josephus(n-1,k) refers to the position of the last survivor. (1)
If we removed the modulus operator then you will see that this will return the 11th position but there is only 6 here so the modulus operator helps keep the counting within the bounds of the circle. (2)
Your first question has been answered above in the comments.
To answer your second question, it's referring to the position of the last survivor.
Consider j(4,2).
Using the algorithm gives
j(4,2)=(j(3,2)+1)%4)+1
j(3,2)=(j(2,2)+1)%3)+1
j(2,2)=(j(1,2)+1)%2)+1
j(1,2)=1
and so
j(2,2)=((1+1)%2)+1=1
j(3,2)=((1+1)%3)+1=3
j(4,2)=((3+1)%4)+1=1
Now the table of j(2,2) is
1 2
1 x
so j(2,2) is indeed 1.
For j(3,2) we have
1 2 3
1 x 3
x x 3
so j(3,2) is 3 as required.
Finally, j(4,2) is
1 2 3 4
1 x 3 4
1 x 3 x
1 x x x
which tells us that j(4,2)=1 as required.

How many total gifts in the twelve days of christmas if we extend 12 to any number?

I got this question today in an interview: write a function to calculate the total number of gifts received for any day in the 12 days of christmas song. I wrote a simple function using a for() loop in c#'ish code that worked. Then the interviewer asked me to extend it to any number of days. The conversation then turned to how to optimize the loop. Apparently there's a cool math trick that will do this within the limits of whatever your integer is. Anyone know what it is and what it's called? Any language is ok and a reference to the algorithm would be fabuloso.
Answers that use recursion are NOT what I'm looking for.
EDIT: Answer for day 2 is 4 gifts total, not 3 since I will have 2 Trees (1 from today, 1 from yesterday) and 2 partridges. On day 12 I'll have received a total of 364. I want the formula that lets me input 12 and get 364.
On the first day, you get 1.
On the second day, you get 1 + 2.
On the third day, you get 1 + 2 + 3.
...
On nth day, you get 1 + 2 + 3 + ... + n.
The sum 1 + 2 + ... + n is n(n+1)/2. So the total number, T(N) is the sum of n(n+1)/2 for n in 1..N, where N is the number of days.
Now, n(n+1)/2 = n^2 / 2 + n / 2, and sum of n^2 for n in 1..N is N(N+1)(2N+1)/6, so you get:
T(N) = N(N+1)(2N+1)/12 + N(N+1)/4
= N(N^2 + 3N + 2) / 6
No loops. No recursion.
The $P$-th type of present (where the $1$st is partridges, the $2$nd is turtle doves, etc.) comes in quantities of $P = \sum_{X = 1}^{P} 1$.
On day $D$, you receive presents of type $1$ through $D$, for a total of $\sum_{P = 1}^{D} \sum_{X = 1}^{P} 1$ many presents on that day.
And so, if the days run from $1$ through $N$ (canonically, $N$ is 12, but our interest now is in allowing it to vary), you receive overall $\sum_{D = 1}^{N} \sum_{P = 1}^{D} \sum_{X = 1}^{P} 1$.
This counts the number of non-decreasing triples $1 \leq X \leq P \leq D \leq N$.
This is the same as the number of increasing triples $1 \leq X < P + 1 < D + 2 \leq N + 2$.
So the answer is $\binom{N + 2}{3} = \frac{(N + 2)(N + 1)N}{6}$.
On the n th day, we get 1 + 2 + 3 + ... + n gifts.
Or ... (1 + n) + (2 + n-1) + ...
In other words, (n + 1) * n/2.
You receive 364 gifts.
1
2+1=3
3+2+1=6
4+3+2+1=10
5+4+3+2+1=15
6+5+4+3+2+1=21
7+6+5+4+3=2+1=28
8+7+6+5+4+3+2+=36
9+8+7+6+5+4+3+2+1=45
10+9+8+7+6+5+4+3+2+1=55
11+10+9+8+7+6+5+4+3+2+1=66
12+11+10+9+8+7+6+5+4+3+2+1=78
If you add all of them up you’ll get 364.

Resources