javascript making change algorithm - javascript

I'm solving this problem "Making change" in javascript:
Question:
Given an amount of money, an array of coin denominations, compute the
number of ways to make the amount of money with coins of the available
denominations.
Example:
For amount=4 (4¢) and denominations=[1,2,3] (1¢,
2¢ and 3¢), your program would output 4—the number of ways to make
4¢ with those denominations:
1¢, 1¢, 1¢, 1¢
1¢, 1¢, 2¢
1¢, 3¢
2¢, 2¢
I found a solution:
var makeChange = function(total){
var count = 0;
var coins = [1, 2, 5, 10, 20, 50, 100, 200];
var changer = function(index, value){
var currentCoin = coins[index];
if( index === 0){
if( value % currentCoin === 0){
count++;
}
return;
}
while( value >= 0 ){
changer(index-1, value);
value -= currentCoin;
}
}
changer(coins.length-1, total);
return count;
};
makeChange(200);
Problem(s):
Can someone explain to me what is going on? I tried following the code but i get lost in between the recursion.
I understand that he is taking the final coin value and he is substracting from the given total. (But why?) I'm kinda lost.
When value >= 0 in the while loop, It keeps looping around increasing the index, i couldn't understand why.
Can someone make sense out of this algorithm?
Sorry, just started learning Dynamic Programming.
Thank you,

Let's track what happens with makeChange(4):
The function changer gets defined then called for the first time.
value = 4, index = 7, coins[7] = 200
Since the variable, index is not 0, we move on to the while loop.
A second call to changer is made with index 6
Meanwhile, the first call continues the 'while'
loop but since 200 has been subtracted from 'value',
'value' is now less than 0 so the 'while' loop terminates
and this first call does nothing more.
(Keep in mind that the variable 'value' is distinct
and private to each call, so the 'while' loop only
affects the 'value' in its own function call.)
Ok, now this pattern continues with all the function calls that have index pointing to a coin larger than value until index is 1.
value = 4, index = 1, coins[1] = 2
This time more happens in the while loop:
We get the function call, 'changer(0,4)',
AND a second function call, 'changer(0,2)',
after we subtract 2 from 'value', which was 4,
AND a third function call, 'changer(0,0)',
after we subtract 2 from 'value', which was 2.
These 3 calls respectively represent:
1 + 1 + 1 + 1
2 + 1 + 1
2 + 2
Each time the line 'value -= currentCoin' is executed,
it represents the start of another set of choices for
solutions that include that coin.
4 % coins[0] = 0, meaning 4 is divisible by 1 represents 1 + 1 + 1 + 1
4 - 2 folllowed by 2 % 1 represents 2 + 1 + 1
and 4 - 2 - 2 represents 2 + 2
Total count: 3

Related

Can anyone explain how this block of code works?

function f(num) {
if (num<1) {
return 1;
}
return f(num-1) + f(num-2);
}
f(5); // 13
I investigated this code in the debugger but it's still unclear to me how it works. I see it as some kind of recursion, but don't get it at all.
Any kind of help will be appreciated.
There are essentially two forms of recursion direct and indirect. However, in either case any proper form of recursion must abide by three rules which makes it recursive.
1.) A recursive algorithm must have a base case.
2.) A recursive algorithm must change its state and move toward the base case.
3.) A recursive algorithm must call itself, recursively.
The intention for using a recursion algorithms focuses on taking a relatively mid to large problems and breaking them into smaller problems which can be solved iteratively or until the "base case" condition has been proven true.
function f(num) {
if (num<=1) { // (1) Base case condition
return 1; // (2.b) moving forward once the base case is true
}
// (3) the function calling itself
// also (2.a) changed state - (i.e., the param value is being decremented or "unwound" with each pass of recursion (i.e., method call)
return f(num-1) + f(num-2);
}
f(5); // Fn = Fn-1 + Fn-2 (Fibonacci Number Series)
Resources:
https://www.geeksforgeeks.org/recursion/
https://medium.com/launch-school/recursive-fibonnaci-method-explained-d82215c5498e
https://www.khanacademy.org/computing/computer-science/algorithms/recursive-algorithms/a/the-factorial-function
https://www.khanacademy.org/computing/computer-science/algorithms/recursive-algorithms/a/recursive-factorial
https://runestone.academy/runestone/books/published/pythonds/Recursion/TheThreeLawsofRecursion.html
https://www.natashatherobot.com/recursion-factorials-fibonacci-ruby/
It is a simple recursion implementation of calculating the num-th Fibonacci number(1 1 2 3 5 8....). And it has a small bug. It should be:
function f(num) {
if (num<=1) { // should be <= 1 instead of <, to handle when num = 1, otherwise it'll end up with f(0)+f(-1)
return 1;
}
return f(num-1) + f(num-2);
}
You can try to write down by hand and simulate some simple cases, which I think is really helpful when you study algorithms.
For example:
f(0) -> 0 is less than 1, return 1, thus f(0) = 1
f(1) -> 1 is less than or equal to 1, return 1, thus f(1) = 1
f(2) -> 2 is greater than 1, return f(1) + f(0), which we know from above, is 1 + 1, thus f(2) = 2
f(3) -> 3 is greater than 1, return f(2) + f(1), 2 + 1, thus f(3) = 3
f(4) -> 4 is greater than 1, return f(3) + f(2), 3 + 2, thus f(4) = 5
I bet you see the patterns now. Hope it helps.
It is recursion. It's a fibonacci series. Step through it slowly.
Start with a simple example:
f(0) = 1 (as num <1)
Increase to 1
f(1) = f(0) + f(-1) = 2
(as num = 1, but f(num-1) and f(num-2) are both less than 1 (and so each return 1)
increase to 2:
f(2) = f(2-1) + f(0) = f(1) + f(-1) = 3
we've solved f(1) and f(-1) already so we know the total returned is 2
increase to 3:
f(3) = f(3-1) + f(3-2) = f(2) + f(1) = 3 + 2 = 5
Remembering that the algorithm is expanding out each step fully (not relying on previous solutions so to speak). so this last example would look more like:
f(3) = f(2) + f(1) = (f(1) +f(0)) + (f(0)+f(-1)) = (f(0) + f(-1)) + 1 + 1 + 1 = 1 + 1 + 1 + 1 + 1 = 5

Find an intermediate value for MOD factor

I am developing an app. At 5 pm, the array resets and count starts from 0 and by the end of day there are thousands of values inside the array. There is a very simple code inside my logic. My data is inside the array data.
data.forEach(function(entry) {
if (entry.time_stamp >= tsYesterday) {
if (count % 100 == 0) {
element = { x: new Date(entry.time_stamp), y: entry.occupied_count };
history_slots.push(element);
}
count++;
}
But the issue is that at 5 pm when there is just 1 element inside the array, it doesn't gets displayed because (0-99)%100 so I want to replace 100 with something. Can I change the value of MOD Factor on the basis is array length? Please guide me if you understand my question.
Thanks in advance.

Check lines A and count it until it changes to lines B javascript

I am sorry in advance if my title is somehow misleading and I am really sorry for my English if you wouldn't understand me, it's just not my native language!
I will try to explain as better as I can about what I try to achieve. I try to do this for past two entire days and I really need your help!
Let's say I have array with the following numbers:
2 4 6 8 10 1 3 5 2 4
I am trying to count how many even and odd numbers are here in a row, and when even/odd changes - count it again. So my answer from the array above should be:
5 (5 even numbers in a row) 3 (3 odd lines in a row) (2 even lines in a row)
Also when the counting isn't stopped it should post "<br>" instead of counted evens/odds, so it could show me results one time near to each line.
Check this example image:
I have this script which is counting, but it has a few issues: when number is even, it shows counting twice. Next, I can't figure it out how to add <br> to these lines where counting and add result only at the last line of counting. Also my counting result should be at the top, so the script should count from the end as I guess, and when I try i-- it starts the infinite loop...
var digits = ["2, 4, 6, 8, 10, 1, 3, 5, 2, 4"]
var evenCount=1, oddCount=1;
for(var i =0; i < digits.length; i++){
if(digits[i] % 2 ==0){
var oddCount=1;
$("#res").append(evenCount + " (l) <br>");
evenCount++;
}
else
var evenCount=1;
$("#res").append(oddCount + " (n) <br>");
oddCount++;
}
Check my fiddle to see it in action:
https://jsfiddle.net/xk861vf9/8/
First, I think your code show counting twice because you misses two '{' after "for loop" and "else". After I fix the code format, I don't see it counting twice anymore.
$(document).ready(function() {
$("#sub").bind("click", function() {
$("#res").html("");
var digits = $('#content').find("span").map(function() {
return $(this).text();
});
var evenCount = 1;
var oddCount = 1;
for(var i =0; i < digits.length; i++) {
if (digits[i] % 2 ==0) {
oddCount = 1;
$("#res").append(evenCount + " (l) <br>");
evenCount++;
} else {
evenCount=1;
$("#res").append(oddCount + " (n) <br>");
oddCount++;
}
}
});
});
Second, they are many ways to implement that. Take a look at this jsfiddle code as an example.
https://jsfiddle.net/xk861vf9/11/
The concept is to print the counted number after even/odd number changes. Then use for loop to print <br> x times (counted number - 1) so if counted number is 4, there will be 3 <br> tags followed.We also have to check if current number is the last number in array and print the counted number or else the last counted number will be skipped.
Hope this help! :)
Ps. Sorry for my bad English, not my native language too.

Javascript - return array of values that totals next number up

I am trying to work out the best way to achieve the following:
A score might require a total of 25 'items' AS A MINIMUM
currently that person might have 15.8 'items'
I have a number of items required to reach that score (9.2)
So to get that score the minimum a person must have is 10 'items' in x weeks (to be 25.8 and over the 25 threshold).
Assuming they have 4 weeks to do it that gives 2.5 needed per week.
What I am struggling with is how to output an array of 'whole items' that will make 10.
e.g.
2
3
2
3
I want the items to be as evenly distributed as possible.
so
1
2
3
4
would be useless
I am just trying to work out the best way to do this.
I was thinking of:
finding nearest whole number ROUNDED UP (3 in this example)
Then outputting that number
Then on the next pass gathering the 'remainder' (-0.5) and then rounding the number.
But it doesn't quite work for all cases.
Can anyone help me get my head around it without writing hundreds of lines of code.
As a further example say 17 were needed in 5 weeks that would be
4
3
3
4
3
Thanks in advance.
You could do it some way like this:
function myFunction(total, weeks) {
var n = 0;
var temp = 0;
var arr = [];
while (n < total) {
temp = n;
n += total / weeks;
arr.push(Math.floor(n) - Math.floor(temp));
}
return arr;
}
myFunction(10, 4); //[2, 3, 2, 3]
myFunction(17, 5); //[3, 3, 4, 3, 4]
In this code, total / weeks will be the average number you'll want to add to n to get from 0 to total in exactly weeks iterations.
Now the difference between the original value of n (which is stored in temp) and the new value of n is pushed to the array. That will give you the rounded numbers you'll need to add up to the entered total.

Looping in Eloquent Javascript

I cam across the following function in javascript:
for (var number = 0; number <= 12; number = number + 2)
show(number);
The Output is the following
0
2
4
6
8
10
12
I expected it to be
2
4
6
8
10
12
14
Why is the "0" shown first and not "2" since the "number = number + 2"comes before the "show(number);"?
This because the order of the loop is like this:
Init number.
Check the condition.
Run the loop.
Increase number by 2.
and then 2-4 again until the condition is false, if so exits the loop.
the for loop translate to something like this:
var number = 0;
while (number <= 12)
{
show(number);
number = number + 2;
}
In general for loop always work like this:
for(Init Variable; Condition ; Changing Variable)
{
//Some Code
}
translates to:
Init Variable
while (Condition )
{
//Some Code
Changing Variable
}
think of it like this :
why did you write the yellow part ?
this is the seed part which you DO WANT TO BE CONSIDERED !
so it will start with its seed value and then - will be incremented ....
0 is the initial value for the number variable in the for loop of the function:
var number = 0;
The for loop is terminated when the number variable reaches 12:
number <= 12;
Here is some more information on for loops: http://www.w3schools.com/js/js_loop_for.asp

Categories