I am trying to solve below problem ,my one test case fail why ?
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path.
Note: You can only move either down or right at any point in time.
Input:
[
[1,3,1],
[1,5,1],
[4,2,1]
]
Output: 7
Explanation: Because the path 1→3→1→1→1 minimizes the sum.
/**
* #param {number[][]} grid
* #return {number}
*/
var minPathSum = function(grid) {
let firstRow = 0,
firstColumn = 0,
endColumn = 0,
endRow = 0;
if(grid.length === 1){
return grid[0][0]
}
let firstArray = grid[0];
let endArray = grid[grid.length - 1];
firstArray.forEach((i) => firstRow += i);
endArray.forEach((i) => endRow += i);
for (let i = 1; i < grid.length - 1; i++) {
firstColumn += grid[i].shift();
endColumn += grid[i].pop()
}
let cornEdge = grid[grid.length - 1].pop();
let firstElemt = grid[0].shift();
if (firstRow + endColumn + cornEdge> firstElemt + firstColumn + endRow) {
return firstElemt+ firstColumn + endRow
} else {
return firstRow + endColumn +cornEdge
}
};
failed test case
Input
[[1,2,5],[3,2,1]]
Output
7
Expected
6
from my point of view above expectation is wrong ? it should be 7 using 1->3->2->1 but how it is six
This is a brute force solution to the problem. It will recursively iterate every possible path through the array, and return the minimum found.
Unfortunately, whilst it works with the two test cases presented in the question, it exceeds the runtime execution limits on Leetcode for the more complex cases; although it does still yield an answer. For example:
minPathSum([
[3,8,6,0,5,9,9,6,3,4,0,5,7,3,9,3],
[0,9,2,5,5,4,9,1,4,6,9,5,6,7,3,2],
[8,2,2,3,3,3,1,6,9,1,1,6,6,2,1,9],
[1,3,6,9,9,5,0,3,4,9,1,0,9,6,2,7],
[8,6,2,2,1,3,0,0,7,2,7,5,4,8,4,8],
[4,1,9,5,8,9,9,2,0,2,5,1,8,7,0,9],
[6,2,1,7,8,1,8,5,5,7,0,2,5,7,2,1],
[8,1,7,6,2,8,1,2,2,6,4,0,5,4,1,3],
[9,2,1,7,6,1,4,3,8,6,5,5,3,9,7,3],
[0,6,0,2,4,3,7,6,1,3,8,6,9,0,0,8],
[4,3,7,2,4,3,6,4,0,3,9,5,3,6,9,3],
[2,1,8,8,4,5,6,5,8,7,3,7,7,5,8,3],
[0,7,6,6,1,2,0,3,5,0,8,0,8,7,4,3],
[0,4,3,4,9,0,1,9,7,7,8,6,4,6,9,5],
[6,5,1,9,9,2,2,7,4,2,7,2,2,3,7,2],
[7,1,9,6,1,2,7,0,9,6,6,4,4,5,1,0],
[3,4,9,2,8,3,1,2,6,9,7,0,2,4,2,0],
[5,1,8,8,4,6,8,5,2,4,1,6,2,2,9,7]
]);
// 83 = 3+0+8+2+2+3+3+3+1+0+0+0+2+0+2+5+0+2+0+5+4+1+3+3+8+3+3+3+5+2+0+0+7
const minPathSum = function(grid) {
let maxX = grid[0].length - 1;
let maxY = grid.length - 1;
return mapPath(grid, 0, 0, maxX, maxY, 0);
};
const mapPath = function(grid, x, y, maxX, maxY, length) {
const value = grid[y][x];
if (x === maxX && y === maxY) {
return length + value;
}
const minX = (x < maxX)
? mapPath(grid, x + 1, y, maxX, maxY, length + value)
: Infinity;
const minY = (y < maxY)
? mapPath(grid, x, y + 1, maxX, maxY, length + value)
: Infinity;
return Math.min(minX, minY);
};
console.log(minPathSum([[1,3,1],[1,5,1],[4,2,1]]));
console.log(minPathSum([[1,2,5],[3,2,1]]));
You should do like:
function min(array){
return Math.min(...array);
}
function sum(array){
return array.reduce((a, c)=>a+=c);
}
function sumsMin(arrayOfArrays){
const sums = [];
arrayOfArrays.forEach(a=>{
sums.push(sum(a));
});
return min(sums);
}
console.log(sumsMin([[1,2,5],[3,2,1]]));
I'm making an "acceleration" array like this:
acc["0100"] = 1;
acc["0300"] = 2;
acc["0600"] = 4;
acc["0900"] = 8;
acc["2000"] = 16;
acc["5000"] = 32;
And, when the user presses a key, I start a timer: this._startTick = (new Date()).getTime();
Now I have a timer that checks if the key is still pressed. If so, then I do something like:
this._delay = (new Date()).getTime() - this._startTick;
And now, based on this._delay, I'd like to find one of the previous values (1, 2, 4 or 8). How would you do that?
NB: if the value is greater than "5.0" then the result should always be 32.
NOTA: my goal is, given an elapsed time, find out which value is the best. I started the way I've just explained, but if you have another solution, I'll take it!
It's easier to operate on an array than on an object:
var accArr = [];
for (time in acc) {
accArr.push({time: time, value: acc[time]});
}
Assuming you have an array, you can do:
function getValue(delay) {
var diffs = accArr.map(function (e) { return Math.abs(e.time - delay); });
return accArr[diffs.indexOf(Math.min.apply(null, diffs))].value;
}
EDIT:
Well, you didn't mention that this is a performance-critical function. In that case, I would recommend picking a granularity (e.g. 0.05, so the multiplier for delay is 20) and pre-calculating all values from 0 to MAX_DELAY:
var multiplier = 20,
granularity = 1 / multiplier;
var delayValues = (function () {
var result = [];
for (var delay = 0; delay <= MAX_DELAY; delay += granularity) {
result.push(getValue(delay));
}
return result;
})();
During the animation, fetching the value will be a simple lookup in a relatively small table:
function getValueFast(delay) {
return (delayValues[Math.round(delay * multiplier)] ||
delayValues[delayValues.length - 1])
}
JSPerf comparison between this solution and simple if statements shows they perform equally fast for searching around a middle value.
Here is the jsfiddle test page.
var getAccForDelay = (function () {
var acc = {
0.1: 1,
0.3: 2,
0.6: 4,
0.9: 8,
2.0: 16,
5.0: 32
};
return function(delay) {
var key,
bestKey = undefined,
absDiff,
absDiffMin = Number.MAX_VALUE;
for (key in acc) {
if (acc.hasOwnProperty(key)) {
absDiff = Math.abs(delay - key);
if (absDiffMin > absDiff) {
absDiffMin = absDiff;
bestKey = key;
}
}
}
return bestKey === undefined ? undefined : acc[bestKey];
};
}());
Test:
console.clear();
console.log(getAccForDelay(0));
console.log(getAccForDelay(0.33));
console.log(getAccForDelay(3.14));
console.log(getAccForDelay(123456.789));
Output:
1
2
16
32
=== UPDATE ===
The above solution doesn't utilize of the fact that acc is sorted by key. I optimized the code by replacing linear search with binary search, which is much faster on long arrays. Here is the test page.
var getAccForDelay = (function () {
var accKey = [ 0.1, 0.3, 0.6, 0.9, 2.0, 5.0 ],
accValue = [ 1, 2, 4, 8, 16, 32 ],
accLength = accKey.length;
return function(delay) {
var iLeft, iMiddle, iRight;
iLeft = 0;
if (delay <= accKey[iLeft])
return accValue[iLeft];
iRight = accLength - 1;
if (accKey[iRight] <= delay)
return accValue[iRight];
while (true) {
if (iRight - iLeft === 1)
return delay - accKey[iLeft] < accKey[iRight] - delay ? accValue[iLeft] : accValue[iRight];
iMiddle = ~~((iLeft + iRight) / 2);
if (delay < accKey[iMiddle])
iRight = iMiddle;
else if (accKey[iMiddle] < delay)
iLeft = iMiddle;
else
return accValue[iMiddle];
}
};
}());
In my humble opinion I think the best solution to this problem is to write a function which picks the best acceleration based on the time using if statements as follows:
function getAcceleration(time) {
if (time < 0.20) return 1;
if (time < 0.45) return 2;
if (time < 0.75) return 4;
if (time < 1.45) return 8;
if (time < 3.50) return 16;
return 32;
}
However this is a static solution. If that's alright with you then I recommend you use this method. On the other hand if you need a dynamic solution then use this instead:
var getAcceleration = createAccelerationMap(0.1, 0.3, 0.6, 0.9, 2.0, 5.0);
function createAccelerationMap(previous) {
var length = arguments.length, limits = [];
for (var i = 1; i < length;) {
var current = arguments[i++];
limits.push((previous + current) / 2);
previous = current;
}
return function (time) {
var length = limits.length, acceleration = 1;
for (var i = 0; i < length;) {
if (time < limits[i++]) return acceleration;
acceleration *= 2;
}
return acceleration;
};
}
Either way you may then use getAcceleration as follows:
console.log(getAcceleration(0)); // 1
console.log(getAcceleration(0.33)); // 2
console.log(getAcceleration(0.64)); // 4
console.log(getAcceleration(1.42)); // 8
console.log(getAcceleration(3.14)); // 16
console.log(getAcceleration(123456.789)); // 32
See the demo: http://jsfiddle.net/QepT7/
If the 0.1 is the number of seconds, and you want to round to 1 decimal you can do something this:
// 0.42332 * 10 = 4.2332
// Math.round( ) will be 4
// 4 / 10 = 0.4
acc[ (Math.round(this._delay * 10) / 10).toString() ]
var seconds = this._delay.toString().substring(0,2)
console.log(acc[seconds]);
This is a straight-forward approach of your problem: First I convert the float to a string, second I cut off everything after the third character.
What units are you using?
this._startTick = (new Date()).getTime();
// ms = ms
this._delay = (new Date()).getTime() - this._startTick;
// ms = ms - ms
So to get to "0.1"/etc from milliseconds I'm assuming you are doing
(Math.floor(ms / 100) / 10).toString();
Why not just keep everything in ms/100 so you can use integers?
var acc = [];
acc[ 1] = 1;
acc[ 3] = 2;
acc[ 6] = 4;
acc[ 9] = 8;
acc[20] = 16;
acc[50] = 32;
Then you can create a "nearest" lookup function like this
function find(x) {
var i = 0;
x = x | 0; // The | 0 will cause a cast to int
if (x < 0) x = 0;
if (acc[x] !== undefined) return acc[x];
if (x > acc.length) return acc[acc.length - 1];
while (++i < acc.length) {
if (acc[x - i] !== undefined) return acc[x - i];
if (acc[x + i] !== undefined) return acc[x + i];
}
}
find(this._delay / 100);
Now examples are
find(30); // 16
find(100.5); // 32
find(0); // 1
How can I make a function that calculates the factorial (or the gamma function) of decimal numbers in JavaScript? For example, how could I calculate 2.33!?
I might have found an existing solution...
It's an implementation of Lanczos method, I found it at the swedish wikipedia (http://sv.wikipedia.org/wiki/Gammafunktionen). It was written in python and says to be correct up to 15 decimals. I ported it to js, cross checked some random values against (http://www.efunda.com/math/gamma/findgamma.cfm).
http://jsfiddle.net/Fzy9C/
var g = 7;
var C = [0.99999999999980993, 676.5203681218851, -1259.1392167224028,771.32342877765313, -176.61502916214059, 12.507343278686905, -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7];
function gamma(z) {
if (z < 0.5) return Math.PI / (Math.sin(Math.PI * z) * gamma(1 - z));
else {
z -= 1;
var x = C[0];
for (var i = 1; i < g + 2; i++)
x += C[i] / (z + i);
var t = z + g + 0.5;
return Math.sqrt(2 * Math.PI) * Math.pow(t, (z + 0.5)) * Math.exp(-t) * x;
}
}
(and ofcourse it does not support imaginary numbers, since js does not)
As an alternative to the other answers here, here's a much simpler approximation for the gamma function, proposed in 2007 by Gergő Nemes. (See the wikipedia page on Stirling's approximation).
This can be implemented directly in JavaScript in a single line:
function gamma(z) {
return Math.sqrt(2 * Math.PI / z) * Math.pow((1 / Math.E) * (z + 1 / (12 * z - 1 / (10 * z))), z);
}
You can see this in action on jsFiddle.
This is accurate to 8 digits for z > 8, but it is still accurate to a handful of digits for smaller z. It is not quite as accurate as Lanczos approximation, but it is simpler and also slightly faster.
Note that the gamma function and the factorial function are slightly different. The factorial function can be defined in terms of the gamma function thus:
function factorial(n) {
return gamma(n + 1);
}
This is not a trivial problem. There is not a simple closed-form formula for the gamma function. That said, there are some numerical approximations that should suit your needs.
The following answer will be using a technique called Lanczos approximation. The formula is as follows:
where g is an arbitrarily chosen constant that controls how accurate the approximation will be. For larger g, the approximation will be more accurate. Ag(z) is defined thus:
The hardest part is finding Ag(z), since pn is also defined with a complicated formula dependent on g.
I can't take too much credit for the following code, since I am just writing a port of the Python program on the wikipedia page.
function gamma(n) { // accurate to about 15 decimal places
//some magic constants
var g = 7, // g represents the precision desired, p is the values of p[i] to plug into Lanczos' formula
p = [0.99999999999980993, 676.5203681218851, -1259.1392167224028, 771.32342877765313, -176.61502916214059, 12.507343278686905, -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7];
if(n < 0.5) {
return Math.PI / Math.sin(n * Math.PI) / gamma(1 - n);
}
else {
n--;
var x = p[0];
for(var i = 1; i < g + 2; i++) {
x += p[i] / (n + i);
}
var t = n + g + 0.5;
return Math.sqrt(2 * Math.PI) * Math.pow(t, (n + 0.5)) * Math.exp(-t) * x;
}
}
and of course, by definition of the gamma function:
function factorial(n) {
return gamma(n + 1);
}
You can see this in action on jsFiddle.
Just to complete #apelsinapa answer to correct the calculation for an integer (we didn't get an integer solution when inputing an integer number).
#apelsinapa's great solution:
var g = 7;
var C = [0.99999999999980993, 676.5203681218851, -1259.1392167224028,771.32342877765313, -176.61502916214059, 12.507343278686905, -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7];
function gamma(z) {
if (z < 0.5) return Math.PI / (Math.sin(Math.PI * z) * gamma(1 - z));
else {
z -= 1;
var x = C[0];
for (var i = 1; i < g + 2; i++)
x += C[i] / (z + i);
var t = z + g + 0.5;
return Math.sqrt(2 * Math.PI) * Math.pow(t, (z + 0.5)) * Math.exp(-t) * x;
}
}
And to get a correct answer for integer:
function factorialOfNumber(number) {
if (number % 1 != 0 || number<0){
return gamma(number + 1);
}
else {
if(number == 0) {
return 1;
}
for(var i = number; --i; ) {
number *= i;
}
return number;
}
}
Here's a version I wrote a few years ago ... a bit messy but tested :)
var
M_GAMMA = [76.18009172947146, -86.50532032941677, 24.01409824083091, -1.231739572450155, 0.1208650973866179e-2, -0.5395239384953e-5],
M_GAMMAS = 6;
function gammaFn(x) // Modified to JavaScript from "Numerical Recipies in C" by P. Mainwaring
{
var i = 0, n = ++x, tmp = x + 5.5, ser = 1.000000000190015;
for (tmp -= (x + 0.5) * Math.log(tmp); i < M_GAMMAS; ++i) ser += M_GAMMA [i] / ++n;
return Math.log(2.5066282746310005 * ser / x) - tmp;
}
function fact(x) { return x > 1 ? Math.exp(gammaFn(x)) : 1 }
function combin(n, k) { return (Math.exp(gammaFn(n) - gammaFn(n - k) - gammaFn(k)) + 0.5) | 0 } // Ms Excel COMBIN() n! / k!(n - k)!
n = 49; k = 6; alert(fact(n) + ' ' + fact(k) + ' ' + combin(n, k)); // Lottery odds! (13,983,816)
The gamma and gammaLn functions are then:
function gammaLn(x) { return gammaFn(--x) }
function gamma(x) { return Math.exp(gammaLn(x)) }
:-)
If you're just looking for the function to compute factorials of real numbers then you only need this bit of code from Lanczos approximation:
function = factorial(z) {
var g = 7;
var C = [0.99999999999980993, 676.5203681218851, -1259.1392167224028, 771.32342877765313, -176.61502916214059, 12.507343278686905, -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7];
var x = C[0];
for (var i = 1; i < g + 2; i++)
x += C[i] / (z + i);
var t = z + g + 0.5;
return Math.sqrt(2 * Math.PI) * Math.pow(t, (z + 0.5)) * Math.exp(-t) * x;
}
Works great for negative numbers in addition to decimals.