Here is a kata from Codewars:
'If you have completed the Tribonacci sequence kata, you would know by now that mister Fibonacci has at least a bigger brother. If not, give it a quick look to get how things work.
Well, time to expand the family a little more: think of a Quadribonacci starting with a signature of 4 elements and each following element is the sum of the 4 previous, a Pentabonacci (well Cinquebonacci would probably sound a bit more Italian, but it would also sound really awful) with a signature of 5 elements and each following element is the sum of the 5 previous, and so on.
Well, guess what? You have to build an Xbonacci function that takes a signature of X elements - and remember each next element is the sum of the last X elements - and returns the first n elements of the so seeded sequence.'
and this is my solution:
function Xbonacci(signature,n){
let i=0;
let k = n - signature.length;
while(k--){
let sumNums = 0;
signature.slice(i , signature.length ).map((num)=>{
return sumNums += num;
})
signature.push(sumNums);
i++
}
return signature;
}
but it's not passing the test because of optimization problems. I don't know how to optimize this code. is there any solution to make this code faster?
In this code i can't seem to understand why -Infinity is behaving like a base so when compared to it returns the biggest number from an array of numbers.
function max(...numbers) {
let result = -Infinity;
for (let number of numbers) {
if (number > result) result = number;
}
return result;
}
It is confusing at first and probably in your mind a solution would sound like this:
let result = 0;
The problem is that when we want to find the MAXIMUM value of an array we need to compare every element with each other. It is more like a "habit" that we set the MAXIMUM to -INFINITY. That simply means that the biggest element so far is the lowest possible number that we can express. Does it make sense? We simply assume that the biggest number we will every find is -Infinity. Then we compare the elements from the array with this base number(in our case -Infinity) and if we were false (and probably we were) then we replace -Infinity with the next number that's bigger than our current value. We do that for the whole range of numbers and that's how we find the Maximum element.
You can pick multiple elements as the starting point, but never pick a number entered by yourself( you should do that ONLY if the exercise asks so).
If you would pick for example:
let result = 0;
then you might have a problem. Maybe the numbers are all negative, for example [-3,-13,-5,13,-99] but you already set the biggest number to 0 so every comparation would be wrong and useless.
So, keep in mind that is a good practice, in this case, to set the base value to -Infinity or if you would like to take another approach then set the base value to the first element in the array.
In using this numbers to find the max of a series of numbers ,you loop through an array of numbers, each number will be compared to -infinity. And since the program is running from left to right the result will update itself each time it finds a bigger number. I tried this comparison method with an actual number.
let edge;
let array1 = [1, 2, 3, 4, 5, 6, 8, 9, 100, 200];
function maxwell(){
for(let checker of array1){
if(checker > 2)edge = checker;
}return edge;
}console.log(maxwell())
I am having issues with understanding dynamic programming solutions to various problems, specifically the coin change problem:
"Given a value N, if we want to make change for N cents, and we have infinite supply of each of S = { S1, S2, .. , Sm} valued coins, how many ways can we make the change? The order of coins doesn’t matter.
For example, for N = 4 and S = {1,2,3}, there are four solutions: {1,1,1,1},{1,1,2},{2,2},{1,3}. So output should be 4. For N = 10 and S = {2, 5, 3, 6}, there are five solutions: {2,2,2,2,2}, {2,2,3,3}, {2,2,6}, {2,3,5} and {5,5}. So the output should be 5."
There is another variation of this problem where the solution is the minimum number of coins to satisfy the amount.
These problems appear very similar, but the solutions are very different.
Number of possible ways to make change: the optimal substructure for this is DP(m,n) = DP(m-1, n) + DP(m, n-Sm) where DP is the number of solutions for all coins up to the mth coin and amount=n.
Minimum amount of coins: the optimal substructure for this is
DP[i] = Min{ DP[i-d1], DP[i-d2],...DP[i-dn] } + 1 where i is the total amount and d1..dn represent each coin denomination.
Why is it that the first one required a 2-D array and the second a 1-D array? Why is the optimal substructure for the number of ways to make change not "DP[i] = DP[i-d1]+DP[i-d2]+...DP[i-dn]" where DP[i] is the number of ways i amount can be obtained by the coins. It sounds logical to me, but it produces an incorrect answer. Why is that second dimension for the coins needed in this problem, but not needed in the minimum amount problem?
LINKS TO PROBLEMS:
http://comproguide.blogspot.com/2013/12/minimum-coin-change-problem.html
http://www.geeksforgeeks.org/dynamic-programming-set-7-coin-change/
Thanks in advance. Every website I go to only explains how the solution works, not why other solutions do not work.
Lets first talk about the number of ways, DP(m,n) = DP(m-1, n) + DP(m, n-Sm). This in indeed correct because either you can use the mth denomination or you can avoid it. Now you say why don't we write it as DP[i] = DP[i-d1]+DP[i-d2]+...DP[i-dn]. Well this will lead to over counting , lets take an example where n=4 m=2 and S={1,3}. Now according to your solution dp[4]=dp[1]+dp[3]. ( Assuming 1 to be a base case dp[1]=1 ) .Now dp[3]=dp[2]+dp[0]. ( Again dp[0]=1 by base case ). Again applying the same dp[2]=dp[1]=1. Thus in total you get answer as 3 when its supposed to be just 2 ( (1,3) and (1,1,1,1) ). Its so because
your second method treats (1,3) and (3,1) as two different solution.Your second method can be applied to case where order matters, which is also a standard problem.
Now to your second question you say that minimum number of denominations can
be found out by DP[i] = Min{ DP[i-d1], DP[i-d2],...DP[i-dn] } + 1. Well this is correct as in finding minimum denominations, order or no order does not matter. Why this is linear / 1-D DP , well although the DP array is 1-D each state depends on at most m states unlike your first solution where array is 2-D but each state depends on at most 2 states. So in both case run time which is ( number of states * number of states each state depends on ) is the same which is O(nm). So both are correct, just your second solution saves memory. So either you can find it by 1-D array method or by 2-D by using the recurrence
dp(n,m)=min(dp(m-1,n),1+dp(m,n-Sm)). (Just use min in your first recurrence)
Hope I cleared the doubts , do post if still something is unclear.
This is a very good explanation of the coin change problem using Dynamic Programming.
The code is as follows:
public static int change(int amount, int[] coins){
int[] combinations = new int[amount + 1];
combinations[0] = 1;
for(int coin : coins){
for(int i = 1; i < combinations.length; i++){
if(i >= coin){
combinations[i] += combinations[i - coin];
//printAmount(combinations);
}
}
//System.out.println();
}
return combinations[amount];
}
In the following function, which returns the factorial of a number, how is the tall of the numbers stored when the function is recursively called.
function factorialize(num) {
if (num < 3) {
return num;
}
return num * factorialize(num - 1);
}
factorialize(5);
I get that this is working backwards to achieve the factoral of 5, which is obtained by multiplying all positive numbers up to the passed number:
1 * 2 * 3 * 4 * 5 obtains the result
I am confused as to how the result of each multiplication is stored or tallied to continually build towards the result of 120.
Thanks guys :)
The function is doing the check, and then calling itself. When it calls itself again, it passes in the result of a calculation.
So, every time factorialize(num - 1); is called, num will be the result of the previous call, and the calculation will remove 1 from that value and pass that new value in.
Step through is like this:
Initial call is factorialize(5), which calls the function with a parameter of 5.
The function checks if 5 is less than 3 (it isn't), and if not, calls itself again. The parameter this time is the original parameter minus 1 - so 4
Next time round, it's checking if 4 is less than 3. If not, call itself again for 4 minus 1 - 3
This continues until the parameter passed in is less than 3
I'm trying to make an alert which will tell you the n'th step of Fibonacci using a for loop. What I have so far is
var x=1;
var y=1;
var call = function(n) {
if (n===1||2) {
alert(1);
}
else {
for(i=3; i<n+1; i++) {
y=(x+y);
x=y-x;
if (i===n) {
alert(y);
}
}
}
};
call(prompt("Calculate Fibonacci to how many steps?"));
How I've tried to make it work is:
Set variable x and y to 1
Create a function named call which does the following:
Check if the number provided when the function is called is 1 or 2,
if so alert 1 (1 being the first two steps of Fibonacci)
If n is not 1 or 2, start for loop at count=3
if count is less than one more than the called step run the
following:
add x and y together
set y to this total
set x to the total, minus x
if the count is equal to the step called, alert with the total
add one to the count, go through loop again
But I'm always alerted with 1, even if I change the alert from the first if statement from 1 to a string. I'm not sure if there's an error in the code or in the logic of it.
I've seen a for loop isn't the most efficient way to do this, but I'd like to get it to work this way for learning's sake. I'm only a few lessons in Code Academy so my experience is very limited. Other pages that address this or a very similar problem are
Fibonacci calculator steps
http://ecomputernotes.com/js/javascript-tutorial/javascript-for-loop
https://answers.yahoo.com/question/index?qid=20091001160834AA5xiZ1
This
if (n===1||2) {
needs to be
if (n===1||n===2) {
Your code is evaluating the truthiness of 2, which is always true.
Also, it's unnecessary to evaluate i===n during each iteration. This will be true only after the last iteration of the loop, so just alert(y) after the loop.