const f = (nums, p) =>
nums.reduce(([map, sum, answer], val, i) => {
const newSum = sum + val;
answer += p * newSum == i + 1;
answer += map[p * newSum - i] || 0;
map[p * newSum - i] = (map[p * newSum - i] || 0) + 1;
return [map, newSum, answer];
}, [{}, 0, 0])[2];
console.log('Input: [2,-1,3,0,1,2,1], 2')
console.log('Output: ' + f([2,-1,3,0,1,2,1], 2));
function bruteForce(A, p){
let result = 0;
for (let windowSize=1; windowSize<=A.length; windowSize++){
for (let start=0; start<A.length-windowSize+1; start++){
let sum = 0;
for (let end=start; end<start+windowSize; end++)
sum += A[end];
if (p * sum == windowSize)
result += 1;
}
}
return result;
}
var numTests = 500;
var n = 20;
var m = 20;
var pRange = 10;
console.log('\nTesting against brute force...')
for (let i=0; i<numTests; i++){
const A = new Array(n);
for (let j=0; j<n; j++)
A[j] = Math.floor(Math.random() * m) * [1, -1][Math.floor(Math.random()*2)];
const p = Math.floor(Math.random() * pRange) * [1, -1][Math.floor(Math.random()*2)];
_f = f(A, p);
_brute = bruteForce(A, p);
if (_f != _brute){
console.log('MISMATCH!');
console.log(p, JSON.stringify(A));
console.log(_f, _brute);
break;
}
}
console.log('Done testing.')