Take value of variable and run it through array - javascript

I am in the process of building a calculator to determine how long a childs colic is going to last.
I have the calculator working correctly just need it to take the value it gets and run it through the array and match the next closest value to the value shown and then reference it to its associated week.
So for instance if you select week 2 and then week 5 the calculation returns childs colic will end in .5614399999999999 weeks. You would then run the .5614 through the wessel_data array and find that .5614 falls in between week 6 and 7. I would then take the next closest week which is week 7 and show that instead of the .5614. So it should say childs colic will end in .64 weeks. Now that it has found the .64 I want it to output the associated weeks so that it would say childs colic will end in 7 weeks.
This is what I have written to find the next associated value but cant get it to work.
function closest (num, wessel_data) {
var curr = wessel_data[0];
var diff = Math.abs (num - curr);
for (var val = 0; val < wessel_data.length; val++) {
var newdiff = Math.abs (num - wessel_data[val]);
if (newdiff < diff) {
diff = newdiff;
curr = wessel_data[val + 1];
}
}
return curr;
}
I also have a fiddle so you can see what I am talking about.
Fiddle

I think you want the index of the wessel_data, not the data itself. That is just for comparing. So in this function set curr = val + 1. Not wessel_data[val + 1].
You aren't using this function at all in your fiddle so it is hard to tell what exactly you are doing.
My advice is to think of what values you want returned given inputs and work backward from there.

Related

What can I use to add new value to previous value and repeat this a certain amount of times? (Javascript)

I'm trying to get an array of numbers based on a calculation that keeps adding a set amount to the previous amount until this have repeated 20 times. The initial number is a negative number because the client pays an initial amount of money for a solar power system and then the calculation should subtract an amount each month based on how much the client saves by not having to pay for electricity. It needs to be an array (I think) because it needs to go into a chart. Here's a google worksheet that might make what I'm trying to more clear. The part of the sheet that is relevant to my question is in columns T and U in pink.
I did tonne of reading on loops, different array types (reduce and map). I'm new to this so it didn't seem any of those types of arrays will do what I need to be done. I found the below code somewhere and it seemed like this is the closest to what I need to happen but I could be completely off track (my adjusted version is further down):
// program to generate fibonacci series up to n terms
// take input from the user
const number = parseInt(prompt('Enter the number of terms: '));
let n1 = 0, n2 = 1, nextTerm;
console.log('Fibonacci Series:');
for (let i = 1; i <= number; i++) {
console.log(n1);
nextTerm = n1 + n2;
n1 = n2;
n2 = nextTerm;
}
I tried to adjust it to try get it to do what I need it to do but in console it shows one number and then the rest is NAN. I know this means not a number but I don't know why or how to fix it:
function runningNetProfit(n) {
var profitSequence = [0];
var nextYear = (monthlyEstimatedSavings * 12);
for (var i = negSystemCost; i < n - 1; i++) {
profitSequence.push(nextYear);
nextYear = nextYear + profitSequence[i];
}
return profitSequence;
}
console.log(runningNetProfit(20))
I added what I did (all of the code) to a codepen as well, maybe it can make my question more clear, that can be found here The javascript relevant to this question is right at the bottom from line 145. Any advice would be much appreciated.
See if this code works for you:
It takes a given installation cost, the price they pay for electricity, and the number of months, then spits out an array with these numbers.
const installCost = 250000;
const electricityCost = 45000;
const numMonths = 20
const newArray = Array.from({length: numMonths})
const updatedArray = newArray.map((_, index) => index * electricityCost - installCost);
console.log(updatedArray) // returns [-250000,-205000,-160000,-115000,-70000,-25000,20000,65000,110000,155000,200000,245000,290000,335000,380000,425000,470000,515000,560000,605000]
Here's the code sandbox for it: https://codesandbox.io/s/blue-pine-l5rjc8?file=/src/index.js

Javascript Help - selfDividingNumbers Algorithm producing all 0's

Greetings Stack Overflow!
First off, this is my first question!
I am trying to solve the selfDividingNumbers algorithm and I ran into this interesting problem. This function is supposed to take a range of numbers to check if they are self dividing.
Self Dividing example:
128 is a self-dividing number because
128 % 1 == 0, 128 % 2 == 0, and 128 % 8 == 0.
My attempt with Javascript.
/*
selfDividingNumbers( 1, 22 );
*/
var selfDividingNumbers = function(left, right) {
var output = [];
while(left <= right){
// convert number into an array of strings, size 1
var leftString = left.toString().split();
// initialize digit iterator
var currentDigit = leftString[0];
for(var i = 0; i < leftString.length; i++){
currentDigit = parseInt(leftString[i])
console.log( left % currentDigit );
}
// increment lower bound
left++;
}
return output
};
When comparing the current lower bound to the current digit of the lower bound, left % currentDigit it always produces zero! I figure this is probably a type error but I am unsure of why and would love for someone to point out why!
Would also like to see any other ideas to avoid this problem!
I figured this was a good chance to get a better handle on Javascript considering I am clueless as to why my program is producing this output. Any help would be appreciated! :)
Thanks Stack Overflow!
Calling split() isn't buying you anything. Remove it and you'll get the results you expect. You still have to write the code to populate output though.
The answer by #Joseph may fix your current code, but I think there is a potentially easier way to go about doing this. Consider the following script:
var start = 128;
var num = start;
var sd = true;
while (num > 0) {
var last = num % 10;
if (start % last != 0) {
sd = false;
break;
}
num = Math.floor(num / 10);
}
if (sd) {
print("Is self dividing");
}
else {
print("Is NOT self dividing");
}
Demo
To test each digit in the number for its ability to cleanly divide the original number, you can simply use a loop. In each iteration, check num % 10 to get the current digit, and then divide the number by ten. If we never see a digit which can not divide evenly, then the number is not self dividing, otherwise it is.
So the string split method takes the string and returns an array of string parts. The method expects a parameter, however, the dividing element. If no dividing element is provided, the method will return only one part, the string itself. In your case, what you probably intended was to split the string into individual characters, which would mean the divider would be the empty string:
var leftString = left.toString().split('');
Since you are already familiar with console.log, note that you could also use it to debug your program. If you are confused about the output of left % currentDigit, one thing you could try is logging the variables just before the call,
console.log(typeof left, left, typeof currentDigit, currentDigit)
which might give you ideas about where to look next.

Find number of pairs with difference larger than or equal to given number

I have a array/dict(HashMap) of positive integers.
I need to find the number of pairs that have a absolute difference greater or equal to a given number, K.
import random
import time
#given number
k = 4
# List of 2,00,000 random numbers in range 0-1000
strength = [random.randrange(0,1000) for x in range(200000)]
strength.sort()
# start clock
start1 = time.clock()
n = len(strength)
# count keeps track of number of pairs found
count = 0
for x in range(n):
for y in range(x,n):
if abs(strength[x] - strength[y]) >= k:
# if found, all number from this point to the end will satisfy
count += n-y
# So no need to go to the end
break
end1 = time.clock()
print(count)
print(end1-start1)
All the answers I find are for pairs less than or equal to a given number.
I need to find the number of pairs that have a absolute difference greater or equal to a given number, K.
Note that the total number of pairs is n * (n - 1) / 2, so if you can find the number of pairs with difference less than K, the number of pairs with difference greater than K is just n * (n - 1) / 2 - num_pairs_with_diff_less_than_K
The solution you provide is also correct (and well documented). If your question is how to adapt it to your case, then all you need to do is to use values of your HashMap (sorted) instead of the strength array.
You can get the 2 item combinations of the array and then filter / reduce them according to the difference.
One might do the job in JavaScript as follows;
Array.prototype.combinations = function(n){
return this.reduce((p,c,i,a) => p.concat(n > 1 ? a.slice(i+1).combinations(n-1).map(e => (e.push(c),e))
: [[c]]),[]);
};
function getAcordingToDiff(a,d){
return a.combinations(2)
.reduce((p,c) => Math.abs(c[0]-c[1]) >= d ? (p.push(c),p) : p ,[]);
}
var arr = Array(30).fill().map((_,i) => i+1); // array from [1,...,30]
console.log(JSON.stringify(arr))
console.log(JSON.stringify(getAcordingToDiff(arr,25))); // diff >= 25
Explanation:
So in the heart of the above code obviously lies the Array.prototype.combinations function. For those who are not familiar with JS, this is just an ordinary function that we define under the Array object's prototype (so that now every array has access to this function like arr.combinations(n)) But let's use a more expressive language and refactor the above combinations array method into a generic function.
function combinations(a,n){
var sa;
return a.reduce(function(p,c,i,a){
if (n > 1) sa = combinations(a.slice(i+1), n-1).map(e => (e.push(c),e));
else sa = [[c]];
return p.concat(sa);
},[]);
}
So as you will notice combinations(a,n) is a recursive function which takes an array a and items count n. It works on the basis of keeping the first item of the input array and recursively invoking itself with one item shorter array, combinations(a.slice(i+1), n-1), and with one less items count up until n decrements to 1 in which case it starts it's return cycle with whatever remains from the input array and each item is wrapped in an array, sa = [[c]].
So on the return cycle of the recursive calls we take the resulting array and push the kept first element (remember -> It works on the basis of keeping the first item of the input array) into each item of the returned array (remember -> ...and each item is wrapped in an array, sa = [[c]]).
So that's it... You should be able to figure out yourself the details.
However in our application we are given an array of numbers and requested to obtain only the 2 item combinations with a certain difference. In this particular case we don't need to calculate all combinations and then filter them. We can do this on the way constructing our combinations. As the required difference value d gets bigger this will bring in a huge gain over filtering afterwards method, since now as d gets bigger we are eliminating more and more of the two item combinations, even before we generate them. And... let's hard-wire our code to work with 2 items only and merge everything in a single function. The performance results are below;
function getCombosWithDiff(a, d, n = 2){
var sa;
return a.reduce(function(p,c,i,a){
if (n > 1) sa = getCombosWithDiff(a.slice(i+1), d, n-1).reduce((r,e) => Math.abs(e[0]-c) > d ? (e.push(c),r.push(e),r)
: r, []);
else sa = [[c]];
return p.concat(sa);
},[]);
}
var arr = Array(100).fill().map((_,i) => i+1);
result = getCombosWithDiff(arr,89);
console.log(JSON.stringify(arr));
console.log(JSON.stringify(result));
So that's it. I have tried the above code to list the 2 items combinations each with diff greater than 10 from an array of 1000 items. It takes like 5000 msecs in Chrome and 14000 msecs in FF. However as mentioned above, the more the diff value d gets bigger, the shorter it takes. e.g same array with diff 900 would resolve in just 1100msecs with Chrome and in 4000msecs with FF.
You can test and play here
Create a 1001-element array A of integers initialized to zeroes. Generate your random integers, and increment the appropriate index by 1 for each such integer. With some math, you could do this without generating 2,000,000 random integers, but it's not worth the complexity.
Create a second 1001-element integer B s.t. B[i] = A[0] + ... + A[i]
Answer is sum from i=0 to 1000-k of B[i] * (2,000,000 - B[i+k-1])

NodeJS combining object array range properties

the title may be a bit confusing but I'll explain it in detail. I have a table in UI and user can choose date ranges from there like;
monday - {in:"13:00:00",out:"13:59:59"}
tuesday - [{in:"13:00:00",out:"13:59:59"},{in:"14:00:00",out:"14:59:59"}]
user can only choose multiple hour intervals for one day. I already made the grouping the intervals according to their date and combining the intervals like
tuesday- [{in:"13:00:00",out:"14:59:59"},{in:"14:00:00",out:"14:59:59"}]
in the first iteration. But I couldn't figure out how to make it for more than 4 or 5 hour intervals.FYI I'm using lodash for sorting and grouping and moment for converting hours to int.
If user enters 5 intervals for tuesday like [{in:"13:00:00",out:"13:59:59"},{in:"14:00:00",out:"14:59:59"},{in:"15:00:00",out:"15:59:59"},{in:"18:00:00",out:"18:59:59"},{in:"19:00:00",out:"19:59:59"}]
I want ranges to be combined like ;
[{in:"13:00:00",out:"15:59:59"},{in:"18:00:00",out:"19:59:59"}]
Any help or suggestion will be appreciated.
Assuming that your input data is chronological then one way of implementing your reduced time table is this;
var timeSlices = [{in:"13:00:00",out:"13:59:59"},{in:"14:00:00",out:"14:59:59"},{in:"15:00:00",out:"15:59:59"},{in:"18:00:00",out:"18:59:59"},{in:"19:00:00",out:"19:59:59"}],
ts = new Date(),
te = new Date(),
reduced = timeSlices.reduce((p,c) => {p.length ? (ts.setHours(...p[p.length-1].out.split(":")),
te.setHours(...c.in.split(":")),
te-ts <= 1000 ? p[p.length-1].out = c.out
: p.push(c))
: p.push(c);
return p;},[]);
console.log(reduced);
However if the objects with in and out times are located arbitrary in the array then a more conceptual approach like first sorting them according to their in times would be essential. That wouldn't be a big deal though.
Assuming ranges are composed of Moment instances and you wanted to combine any two ranges where the end of one range either overlapped another range or was less than or equal to one second behind the start of another range, this function should be able to combine the ranges
function combineRanges (ranges) {
if (ranges.length <= 1) {
return ranges
}
ranges = ranges.sort(byStart)
var current = ranges[0]
var combined = [current]
for (var i = 1; i < ranges.length; i++) {
var next = ranges[i]
if (current.out.diff(next.in, 'seconds') > 1) {
combined.push(next)
current = next
} else if (current.out.isBefore(next.out)) {
current.out = next.out
}
}
return combined
}
function byStart (a, b) {
return a.in - b.in
}

How to Sum up last 12 month amounts in javascript dynamically

I need to write a code regarding last 12 months calculation every next month so that when a user enters the value in the current month or in next month he should get the result
here how the calculation goes
CA (jan 14) = (Avg of B.Y. 2001=100 for the past 12 months - 115.76)*100/115.76
CA (jan 14)=( 232.66-115.76)*100/115.76=100.009
so every month if some body enters it we should get the value by the above calculation.
I tried with some sort of coding in JavaScript please checkout in this link
http://jsfiddle.net/kundansingh/SLC5F/
B.Y. 2001=100 = value will be enter by user
Total of 12 Months = total value of last 11 months and current month so 12 months
% Increase over 115.763 = 232.66-115.76
App. CA = ( 232.66-115.76)*100/115.76
i need dynamically for every month if input for next month value also it should show the result... what i have created is for one month ..please help me to sort the issue
In this case I'd really recommend using jQuery to make your life a lot easier, especially since you're going to want to do at least one for loop, if not two.
You need to loop through each row, get the previous 11 values, then do your calculations.
In your jsFiddle, the following code should work. I have edited your jsFiddle accordingly: http://jsfiddle.net/SLC5F/1/
$('tr', '#order-table').each(function() {
var total = 0;
var $rows = $(this).prevAll();
// return if we don't have enough rows
// probably better to just add a class to the active rows instead,
// but it's not my job to format your code.
if ( $rows.length < 13) return;
$rows = $rows.slice(0, 11);
// again, would be better to add a class to active inputs instead of using
// a not() filter. you can do this yourself.
total += parseFloat( $(this).find('input').not('.row-total-input, [readonly]').val() );
$rows.each(function() {
total += parseFloat( $(this).find('input').not('.row-total-input').val() );
});
// return if total isn't a number
if ( isNaN(total) ) return;
var monthly_average = total / 12;
// again, would be better to add classes to these TDs instead of using eq()
// make sure you do this before using this script in a live application.
$('td', this).eq(2).text(total);
$('td', this).eq(3).text(Math.round(monthly_average * 100) / 100);
$('td', this).eq(4).text(Math.round(( monthly_average - 115.763 ) * 100 / 115.764 * 100) / 100);
});

Categories