How to find the nearest two numbers of a custom function [closed] - javascript

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Given a number, how can I find the nearest two numbers which starts with 1, 2.5 or 5? (10, 25, 50, 100, 250, 500, 1000...endless)
The result should be the nearest nearest higher number, and one below it.
For example: the number 420 should return 250 and 500.
For example: the number 10 should return 10 and 25.
Can use Lodash if it's helpful.
Thanks.

OK, I think I understand based on your comments.
// Finds the two numbers on each side for any number.
function nearest(n) {
let m = multiplier(n);
return nearest10(n / m).map(n => n * m);
}
// Finds the two numbers on each side for numbers between 1 and 10.
function nearest10(n) {
return n < 2.5 ? [1, 2.5] : n < 5 ? [2.5, 5] : [5, 10];
}
// Returns the neareast power of 10 less than or equal to n.
function multiplier(n) {
return Math.pow(10, Math.floor(Math.log10(n)));
}
And here is a sample of the results:
console.log(nearest(2)); // [1, 2.5]
console.log(nearest(420)); // [250, 500]
console.log(nearest(79310)); // [50000, 100000]

First write the number in scientific notation to get rid of the scale.
420 = 4.2x10^2
Then locate the mantissa among [1, 2.5), [2.5, 5), [5, 10).
4.2 in [2.5, 5)
And transfer the exponent,
2.5x10^2 = 250, 5x10^2 = 500
This is better done using base 10 logarithms,
L= log(X) / log(10)
E= floor(L)
L= L - E
if L < log(2.5), LB= pow(10, N), UB= 2.5 * pow(10,N)
else if L < log(5) , LB= 2.5 * pow(10, N), UB= 5 * pow(10,N)
else LB= 5 * pow(10, N), UB= 10 * pow(10,N)

function findPrevAndNext(x){
// returns the next highest value and previous
// lower value in the infinite series
// [1, 2.5, 5, 10, 25, 50, 100, ...]
var top = 5;
while(top < x){
top = top * 10;
}
var mid = top / 2; // ex: 5/2 = 2.5
var bot = top / 5; // ex: 5/5 = 1
var prev, next = 0;
if(x >= mid){
prev = mid;
next = top;
}
else if(x >= bot){
prev = bot;
next = mid;
}
else{
prev = bot / 2;
next = bot
}
return Array(prev,next);
}
https://jsfiddle.net/o44t0t65/1/

Related

Rounding-off from whole numbers to whole numbers in JavaScript?

So I have some numbers x = 320232 y = 2301 z = 12020305. I want to round these numbers off using JavaScript so that they become x = 320000 y = 2300 z = 12000000.
I tried Math.round and Math.floor but turns out that they only work with decimal values like
a = 3.1; Math.round(a); // Outputs 3 and not whole numbers.
So my question is can we round of whole numbers using JavaScript and If yes then how?
Edit: I want it to the round of to the starting 3 digit places as seen in the variables above. Like If there was another variable called c = 423841 It should round off to become c = 424000.
You could work with the logarithm of ten and adjust the digits.
const
format = n => v => {
if (!v) return 0;
const l = Math.floor(Math.log10(Math.abs(v))) - n + 1;
return Math.round(v / 10 ** l) * 10 ** l;
};
console.log([0, -9876, 320232, 2301, 12020305, 123456789].map(format(3)));
The solution is to first calculate how many numbers need to be rounded away, and then use that in a round.
Math.round(1234/100)*100 would round to 1200 so we can use this to round. We then only need to determan what to replace 100 with in this example.
That is that would be a 1 followed by LENGTH - 3 zeros. That number can be calculated as it is 10 to the power of LENGTH - 3, in JS: 10 ** (length - 3).
var x = 320232;
var y = 2301;
var z = 12020305;
function my_round(number){
var org_number = number;
// calculate integer number
var count = 0;
if (number >= 1) ++count;
while (number / 10 >= 1) {
number /= 10;
++count;
}
// length - 3
count = Math.round(count) - 3;
if (count < 0){
count = 0;
}
// 10 to the power of (length - 3)
var helper = 10 ** count;
return Math.round(org_number/helper)*helper;
}
alert(my_round(x));
alert(my_round(y));
alert(my_round(z));
It is not the prettiest code, though I tried to make it explainable code.
This should work:
function roundToNthPlace(input, n) {
let powerOfTen = 10 ** n
return Math.round(input/powerOfTen) * powerOfTen;
}
console.log([320232, 2301,12020305, 423841].map(input => roundToNthPlace(input, 3)));
Output: [320000, 2000, 12020000, 424000]

Fit a quantity of items to a binomial distribution / bell curve [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 1 year ago.
Improve this question
This is a sort of discrete math integration question - I need to fit a fixed quantity of items to a binomial distribution or bell curve over a fixed period.
Say I a total of M boxes being shipped over T days, where n is the number boxes that arrive on day t. I need a way to calculate n(t) for each day t, so that
The Sum ( n(t) ) 0 -> t = M
t is an integer, and n(t) is an integer, and
the shape of n(t) matches as closely as possible to a bell curve.
Edit
In case anyone does think this an SO-worthy question, here's the Javascript I cobbled together from the pointers in Yves Daoust answer.
/*
See https://stackoverflow.com/questions/5259421/
*/
function normal(x, mean, stdDev) {
return stdNormal(( x - mean ) / stdDev);
}
function stdNormal(z) {
// Power series is not stable at these extreme tail scenarios
if (z < -6) { return 0; }
if (z > 6) { return 1; }
let j, k ;
let m = 1; // m(k) == (2**k)/factorial(k)
let b = z; // b(k) == z ** (2*k + 1)
let z2 = z * z; // cache of z squared
let z4 = z2 * z2; // cache of z to the 4th
let values = [];
// Compute the power series in groups of two terms.
// This reduces floating point errors because the series
// alternates between positive and negative.
for (k=0; k<100; k+=2) {
const a = 2*k + 1;
let item = b / (a*m);
item *= (1 - (a*z2)/((a+1)*(a+2)));
values.push(item);
m *= (4*(k+1)*(k+2));
b *= z4;
}
// Add the smallest terms to the total first that
// way we minimize the floating point errors.
let total = 0;
for (k=49; k>=0; k--) {
total += values[k];
}
// Multiply total by 1/sqrt(2*PI)
// Then add 0.5 so that stdNormal(0) === 0.5
return 0.5 + 0.3989422804014327 * total;
}
/*
Compute the cdf of the binomial distribution between 0 and T, times M.
Round all values to integers. Let m(t) the numbers so obtained.
Use n(t) = m(t+1) - m(t). In doing so, you ensure Σ n(t) = n(T) - n(0) = M.
Thanks to Yves Daoust
*/
function distributeItems(itemsToPlace = 100, steps = 7) {
const mean = Math.floor((steps - 1) / 2);
const stdDev = mean / 2.96; /// for 'standard' std dev ;-)
const m = [0]; // cdf
const n = [0]; // items
for (var step = 1; step <= steps; step++) {
m.push(Math.round(normal(step, mean, stdDev) * itemsToPlace,0));
n.push( m[step] - m[step - 1] );
}
const interimCount = n.reduce(function (sum, elt) { return sum+elt; }, 0);
const discrepancy = itemsToPlace - interimCount;
if (discrepancy !==0) {
n[n.length-1] += discrepancy;
}
return n;
}
const n = distributeItems(40,7);
console.log('Items: ',n, 'Total: ',n.reduce(function (sum, elt) { return sum+elt; }, 0))
// Result
// [ 0, 1, 5, 14, 14, 5, 1, 0 ] 40
Maybe not an optimal solution, but should not be far.
Compute the cdf of the binomial distribution between 0 and T, times M.
Round all values to integers. Let m(t) the numbers so obtained.
Use n(t) = m(t+1) - m(t). In doing so, you ensure Σ n(t) = n(T) - n(0) = M.
In the picture below, the blue curve is an exact binomial N=7, p=0.3, adjusted for M=20. The orange curve is obtained by the above procedure. As you can check, 2+5+6+4+2+1+0+0=20.

Factorial in JS at my interview at Sina Weibo

how much 0 at the end of 1*2*3*....*100?
for example1 zero 10,2 zero at the end of 10100,0 zero at 10001
The interviewer gave me 3 mins.
front-end develope intern was the job i went for.
i tried to solve it in JavaScript,it was wrong because 100! is so big for a JS variable.Here is my code.
var factorial = function(x){
if(x<0){
return error;
}else if (x ===1 || x ===0) {
return x;
}else if (x > 1) {
return (factorial(x - 1) * x);
}
}
var counter = 0;
var countZero = function(x){
while((x%10) === 0){
counter = counter + 1;
x = x/10;
}
return counter;
}
console.log(countZero(factorial(100)));
Any ideas?I solved it without computer in a pure-math way,but i want to know how to solve it in JS.
A number gets a zero at the end of it if the number has 10 as a factor. For instance, 10 is a factor of 50, 120, and 1234567890. So you need to find out how many times 10 is a factor in the expansion of 100!.
But since 5×2 = 10, we need to account for all the products of 5 and 2. Looking at the factors in the above expansion, there are many more numbers that are multiples of 2 (2, 4, 6, 8, 10, 12, 14,...) than are multiples of 5 (5, 10, 15,...). That is, if we take all the numbers with 5 as a factor, We'll have way more than enough even numbers to pair with them to get factors of 10 (and another trailing zero on my factorial). So to find the number of times 10 is a factor, all we really need to worry about is how many times 5 is a factor in all of the numbers between 1 and 100
Okay, how many multiples of 5 are there in the numbers from 1 to 100? There's 5, 10, 15, 20, 25,...
Let's do this the short way: 100 is the closest multiple of 5 below or equal to 100, and 100 ÷ 5 = 20, so there are twenty multiples of 5 between 1 and 100.
But wait: 25 is 5×5, so each multiple of 25 has an extra factor of 5 that we need to account for. How many multiples of 25 are between 1 and 100? Since 100 ÷ 25 = 4, there are four multiples of 25 between 1 and 100.
Adding these, We get 20 + 4 = 24 trailing zeroes in 100!
It was more of a math question that a Javascript specific question and you don't need to calculate the actual factorial to find the number of trailing zeros
More details here
Zeros at the end of a number result from 2s and 5s being multiplied together. So, one way to count up the total number of zeros would be to figure out how many total 2s and 5s go into 100! - don't calculate that number, just add up the number of factors - and then return whichever count (2s or 5s) is smallest.
let twos = 0;
let fives = 0;
for (let i = 1; i <= 100; i++) {
let num = i;
while (num % 2 === 0) {
twos++;
num /= 2;
}
while (num % 5 === 0) {
fives++;
num /= 5;
}
}
console.log(Math.min(twos, fives));
For the numbers less or equal than 1000000000 as your case here you could use the following algorithm :
function numberOfZeros(n) {
if (n == 0) return 0;
return parseInt(n * (n - 1) / (4 * n));
}
console.log(numberOfZeros(100));

calculate combinations of n length string and n characters in each position

Ok what i need to do is something like this:
lets say that user has written a string that has 4 characters '6262', now each of the position can contain different number of characters, for example this is how many characters can be in each position:
pos. 1 - 4 different characters 6, 7, 8, 9
pos. 2 - 2 different characters 2, 3
pos. 3 - 4 different characters 6, 7, 8, 9
pos. 4 - 2 different characters 2, 3
now how to calculate in total how many combinations can we have based on 4 length string and respectively 4, 2, 4, 2 chars in each spot?
This is a simple MATH problem not at all connected with programming or code.
4^2 * 2^2 = 2^4 * 2^2 = 2^6 = 64 combinations.
TO make a clearer example how would you calculate how many combinations are in 4 positions and each has 10 possibilities?
it's 10^4 = 1000 which is exactly why there is 10000 numbers possible with 4 digits in numeric system with the base of 10. As you might sense now those numbers are 0000 = 0 to 9999.
EDIT: comment requested the function that calculates what I wrote above.
Pass in this function number of combinations per place and it will return number of total combinations to you:
function productAll() {
var i;
var product = 1;
for (i = 0; i < arguments.length; i++) {
product *= arguments[i];
}
return product;
}
For your example you would call a function like: productAll(4,2,4,3);
Although this isn't a programming problem, here's a programming solution:
var counter = 0;
var abcd = "";
for(a = 6; a <=9; a++) {
for(b = 2; b <=3; b++) {
for(c = 6; c <=9; c++) {
for(d = 2; d <=3; d++) {
counter++;
abcd += a + "" + b + "" + c + "" + d + " ";
}
}
}
}
In the end, counter is 64, as DanteTheSmith predicted.
And abcd is every combination:
6262 6263 6272 6273 6282 6283 6292 6293 6362 6363 6372 6373 6382 6383 6392 6393 7262 7263 7272 7273 7282 7283 7292 7293 7362 7363 7372 7373 7382 7383 7392 7393 8262 8263 8272 8273 8282 8283 8292 8293 8362 8363 8372 8373 8382 8383 8392 8393 9262 9263 9272 9273 9282 9283 9292 9293 9362 9363 9372 9373 9382 9383 9392 9393

How do I assign a probability (uniform increasing or decreasing linear distribution) to a array of values?

Given X=[1,2,3,4,5,6,7,8,9,10] -- but X could be any length(N).
I want to achieve the following:
I want to give the 1st value X[0], the highest probability.
I want to give the 2nd value X[1], a lesser probability than X[0].
I want to give the 3rd value X[2], a lesser probability than X[1].
...
I want to give the Last value X[N], a lesser probability than X[N-1]
All probabilities should sum up to 1.
For clarity with uniform probability distribution(1/(X.length)) looks like this:
{1:0.1, 2:0.1, 3:0.1, 4:0.1, 5:0.1, 6:0.1, 7:0.1, 8:0.1, 9:0.1, 10:0.1,}
If possible solution in javascript would be Great.
You could sum the indices (all values increased by one) and use the sum for calculation the probability.
For a reverse distribution, reverse the probability array.
var add = (a, b) => a + b,
data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],
sum = data.length * (data.length + 1) / 2,
probability = data.map((_, i) => (i + 1) / sum),
sumProbability = probability.reduce(add, 0);
console.log(probability);
console.log(sumProbability);
Let's probability for the last element is q, for previous element is 2*q, for previous is 3*q ... and for the first one is N*q
q + 2 * q + 3 * q +...+(N-1)*q + N * q = 1
q * Sum(1...N) = 1
q * N * (N + 1) / 2 = 1
q = 2 / (N * (N + 1))
So you can find q for any sequence length and get probabilities for every element.
Example for N = 3
q = 2 / (3 * 4) = 1/6
probabilities:
3/6, 2/6, 1/6 Sum = 1

Categories

Resources