Simple deep-learning prediction - javascript

I'm starting to learn about deep-learning and found synaptic.js.
I would like to create a prediction system where I have a input of numbers and would like the AI to understand the pattern.
My training data would be a array of 2 numbers, and the output I want to validate is [x, y, z] where x and z are kind of booleans for even/odd, and y is the sum of both numbers in the imput.
So:
var trainingSet = [{
'input': [20, 34],
'output': [1, 54, 0]
}, {
'input': [22, 33],
'output': [1, 55, 1]
},{
'input': [24, 35],
'output': [1, 59, 1]
},{
'input': [23, 36],
'output': [0, 59, 0]
}];
and I would like the AI to know the answer if I input [20, 31].
How would I set up such logic?
I started a jsFiddle based on a YouTube talk but don't understand what the code does actually...
Made a loop to generate trainig data in this jsFiddle that basically is:
// training data generator:
var trainingSet = [];
for (var i = 0; i < 500; i++) {
var obj = {};
obj.input = [
Math.random() * 10,
Math.random() * 10
].map(Math.round);
obj.output = [
Number(obj.input[0] % 2 == 0),
obj.input[0] + obj.input[1],
Number(obj.input[1] % 2 == 1)
]
trainingSet.push(obj);
}
document.body.innerHTML = JSON.stringify(trainingSet);

Unless the generator you build is simply to explain the problem to us, there's no way the problem can be solved. More formally, no function exists such that you can recover the input from the output. The generator produces random numbers and what is preserved is whether they were odd / even and the sum. There exists an infinite set of numbers that fulfills these criteria. From your example: 54 = 20 + 34 = 18 + 36 = 16 + 38 ... If there was a process driving this, it can be done. But it's random. Your neural network can never learn a pattern because there is no pattern.

Related

How to implement array support with Chevrotain parser?

I am building a calculator with Chevrotain parser and I have played with their calculator example
Chevrotain Playground: https://chevrotain.io/playground/
Parser Grammar: Calculator embedded semantics
Input Sample: Parenthesis precedence
The example above uses integer as input/output. I would like to support integers AND arrays.
Basic example:
2 * ( 3 + 7 )
Example with arrays:
2 * ( {{array1}} + {{array2}} )
const map = {
array1: [1, 2, 3, 4, 5],
array2: [10, 20, 30, 40, 50]
}
I know how to lex and parse {{array}} but I don't know how to visit them or loop over the arrays to achieve the following result
2 * ( 1 + 10 ) = 22
2 * ( 2 + 20 ) = 44
2 * ( 3 + 30 ) = 66
2 * ( 4 + 40 ) = 88
2 * ( 5 + 50 ) = 110
End result of the parsing of 2 * ( {{array1}} + {{array2}} )
should be [22, 44, 66, 88, 110]
Once the AST has been created (including the arrays on some leaf node), how can I reduce it to the end result which is an array
One approach is to have some sort of state (with the current index) and run the visitor as many time as array.length. But it is unclear to me how to can be implemented with Chevretain
This solution will work
const map = {
array1: [1, 2, 3, 4, 5],
array2: [10, 20, 30, 40, 50]
}
const { array1, array2 } = map;
const res = [];
for (let i = 0; i < (array1.length > array2.length ? array1.length : array2.length); i++) {
if (array1[i] && array2[i]) {
res.push((array1[i] + array2[i]) * 2);
} else if (array1[i] && !array2[i]) {
res.push(array1[i] * 2);
} else {
res.push(array1[i] * 2);
}
}
// res = [ 22, 44, 66, 88, 110 ]
First, we will extract the arrays from an object, then we will create a loop that will run several times of the longer array (trinary operator).
Inside the loop, we will insert the item from array1 plus the item from array2 doubled by 2 into the new array, and if there is no item in one of the spots in the arrays (meaning that one of the arrays is shorter than the other) we will insert only one item.

Partition N where the count of parts and each part are a power of 2, and part size and count are restricted

How do you take a number representing a list of items, and divide it into chunks, where the number of chunks is a power-of-two, AND where each chunk also has a power-of-two number of items (where size goes up to a max power of two, so 1, 2, 4, 8, 16, 32, 32 being the max)? Is this even possible?
So for example, 8 items could be divided into 1 bucket (power of two bucket) with 8 items (power of two items):
[8]
9 items could be:
[8, 1]
That works because both numbers are powers of two, and the size of the array is 2 (also a power of two).
Let's try 11:
[8, 2, 1]
Nope that doesn't work. Because the size of the array is 3 which is not a power of two, even though it adds to 11. How about this?
[4, 4, 2, 1]
That works! It's 4 elements which is a power of two.
[2, 2, 2, 1, 1, 1, 1, 1]
That also works, since there are 8 buckets (8 is a power of two), with 1 or 2 items each (each a power of two). But [4, 4, 2, 1] is better because it's shorter.
I guess an even better one (after getting comments) would be this, though I didn't see it the first time around:
[8, 1, 1, 1]
That one is short, and also starts with the largest number.
So following this pattern, here are some other numbers:
13:
[8, 1, 1, 1, 1, 1] // no, 6 not power of 2
[8, 2, 1, 1, 1] // no, 5 not power of 2
[8, 2, 2, 1] // yes, 4 is power of 2
[8, 4, 1] // no, 3 not power of 2
14:
[8, 2, 2, 2]
15:
[8, 4, 2, 1]
16:
[16]
18:
[16, 2]
200:
[32, 32, 32, 32, 32, 32, 4, 4]
When the size of the first layer of buckets in the bucket tree grows to longer than 32, then it nests. So take the number 1234 for example. This can be represented by 38 32's followed by 16 followed by 4.
[32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 16, 4]
But now the bucket size is 40 items long, which isn't a power of two AND it's greater than 32. So it should be nested! I can't quite visualize this in my head, so sorry if this isn't a perfect example, I think you can get the gist of what I mean though.
// the parent "x" is 2 in length
x = [a, b]
// child "a" is 32 in length
a = [32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32]
// child "b" is 8 in length
b = [32, 32, 32, 32, 32, 32, 16, 4]
Taken another layer up, say we have a very large number (I don't know what the minimum large number is) that requires another layer of nesting. What we can say about this layer is that, x will be 32 in length, but we will also have a y that is at least 1.
_x_ = [a, b, c, d, e, f, g, h,
i, j, k, l, m, n, o, p,
q, r, s, t, u, v, w, x,
y, z, a2, b2, c2, d2, e2, f2]
_y_ = [a3]
a = [32, 32, 32, ..., ?]
...
f2 = [32, ..., ?]
Then once we have _x_, _y_, _z_, ... 32 total of these, we build another layer on top.
What is an algorithm/equation that will take a number and divide it into this tree of buckets / item sizes that are all powers of two, up to a max (in this case, 32)?
A subgoal is to minimize the number of levels. There isn't a specific limit, but I am imagining no more than 1 million or very max 1 billion nodes in the entire runtime, so it seems like you'll only have 3 or 4 levels probably, I don't know exactly how to calculate it.
This is going to be used for array lookup. Essentially I am breaking apart a single, large, arbitrarily sized "contiguous" array into small contiguous chunks with size power-of-2 up to 32 in length. This balances lookup performance (i.e. fits within cpu cache), with memory fragmentation.
Update:
I think trying to incorporate this somehow to build up that nested tree I'm trying to describe will help. The last thing now missing is getting the nested arrays to be properly sized to power-of-two values...
The best I have been able to do so far is this:
console.log(spread(74))
console.log(spread(85))
console.log(spread(87))
console.log(spread(127))
console.log(spread(1279))
console.log(spread(12790))
console.log(spread(127901))
function spread(n) {
if (n == 0) {
return [0, 0, 0, 0, 0, 0]
}
let array = []
let r = split(n)
while (r[0] > 31) {
array.push([32, 0, 0, 0, 0, 0])
r[0] -= 32
}
array.push(r)
let s = sum(r)
if (!isPowerOf2(s)) {
let x = pow2ceil(s)
let i = 1
while (i < 5) {
if (r[i] > 1) {
i++
break
}
i++
}
if (i == 5) {
i = 0
}
main:
while (true) {
while (r[i]) {
r[i + 1] += 2
r[i]--
s += 1
if (s == x) {
break main
}
}
i++
}
}
if (array.length == 1) {
return array[0]
} else if (array.length < 33) {
return array
} else {
return divide(array, 32)
}
}
function sum(arr) {
let i = 0
arr.forEach(x => {
i += x
})
return i
}
function split(n) {
const r = [0, 0, 0, 0, 0, 0]
let u = 32
let i = 0
while (u > 0) {
while (n >= u) {
r[i]++
n -= u
}
i += 1
u >>= 1
}
return r
}
function isPowerOf2(v) {
return v && !(v & (v - 1))
}
function pow2floor(v) {
var p = 1;
while (v >>= 1) {
p <<= 1;
}
return p;
}
function pow2ceil(v) {
var p = 2
while (v >>= 1) {
p <<= 1
}
return p
}
function divide(data, size) {
const result = []
const upSize = data.length / size;
for (let i = 0; i < data.length; i += size) {
const chunk = data.slice(i, i + size);
result.push(chunk)
}
if (result.length > size) {
return divide(result, size)
}
return result;
}
It's always possible.
Start with the normal binary representation.
You get a number of summands that are all powers of 2.
So the problem is the number of summands is most of the times not a power of two.
You can always get an extra summand by splitting a power of 2 in 2 summand (also powers of 2). Only exception is 1.
So the question is there a case where not enough summand > 1 exists?
Answer: No
Worst case is we have n summand where n is a (power of 2)-1.
E.g. 3, 7,15, ...
Is we have 3 summand the smallest possible case is 1+2+4. We need 4 summand, so we must create 1 extra summand by splitting one of the summands >1 into two. e.g 1+1+1+4.
For bigger values the highest summand is always >= ceeling(value/2) and has at most ceeling(sqrt(value))+1 summands in binary representation.
ceeling(value/2) grows much faster than sqrt(value).
So we have with increasing values always plenty of summands to split to reach the power of 2 summands goal.
Example: value= 63
Binary representation: 32+16+8+4+2+1 (6 summands)
Highest summand is 32 (at least value/2) (which can be split in any number of summands (all powers of 2) up to 32 summands.
We need at most ceeling(sqrt(63))+1 = 8 summands to reach a power of 2 summands.
So we need 2 extra summands for our 32+16+8+4+2+1
Take any summand >1 and split it in two summands (powers of 2)
e.g 32 = 16+16
=> 16+16+16+8+4+2+1 (7 summands)
do it again (because we needed 2 extra summands).
Take any summand >1 e.g. 4 and split ist 2+2=4
=> 16+16+16+8+2+2+2+1 (8 summands)
Here is a possible algorithm:
Check the lowest 5 bits of the input number n and generate the corresponding powers of 2 in an array. So for instance for n = 13 we get [1, 4, 8]
Divide n by 32 ignoring the above-mentioned bits (floor).
Add to the above array as many values of 32 as n modulo 32. So for example for input = 77 we get [1, 4, 8, 32, 32]
Most of the times this array will have a length that does not exceed 32, but it could go up to 36: [1, 2, 4, 8, 16, 32, ..., 32]. If that happens, extract 16 values from the end of the array and store them in a "carry": this carry will be processed later. So not considering this potential carry, we ensure we end up with an array that is not longer than 32.
Then perform a split in halves of the greatest value in the array (thereby growing the array with one unit) until the array's length is a power of 2. For instance, for the case of 77 we'll have a few of such iterations in order to get [1, 4, 8, 8, 8, 16, 16, 16]
Divide n again by 32 ignoring the remainder (floor).
Consider again n modulo 32. If this is non-zero we have found summands of 32*32, so we create a new array [32, ..., 32] for each of those, and combine that with the previously established array into a new tree. So for instance for 1037, we could get
[
[1,4,4,4],
[32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32]
]
If there is room to add a potential carry (i.e. the top level array does not have a length of 32), then do so.
If the length of the array is not yet a power of 2, apply a similar algorithm as previously mentioned, although now a split in half concerns arrays instead of primitive values.
Repeat this division by 32 to identify even higher nested summands, so these are complete 32*32*32 trees, then in the next iteration, these are complete 324 trees, etc, until all of n is accounted for.
At the end, check if the carry is still there and could not yet be added somewhere: if this is the case add an extra level to the tree (at the top) to combine the achieved result with this carry, so they are siblings in an array of 2.
Implementation
Here is an interactive snippet: type a number and the resulting tree will be displayed in real time. Note that the nested tree is really created in this implementation and will consume quite some memory, so to keep the response times acceptable in JavaScript, I have limited the allowed input to numbers with 7 digits, but in theory the only limit is memory and floating point precision (which in this script is guaranteed up to 253).
// Utility functions
const sum = arr => arr.reduce((a, b) => a+b, 0);
const powersOf2andZero = [0,1,2,4,8,16,32];
const clone = tree => JSON.parse(JSON.stringify(tree));
function createTree(n) {
let tree = [];
let carry = null;
// Isolate 5 least significant bits
for (let pow of [1, 2, 4, 8, 16]) if (n & pow) tree.push(pow);
n = Math.floor(n / 32);
for (let i = n % 32; i > 0; i--) tree.push(32);
// This array could have more than 32 values, up to 36.
// If that happens: remove 16 occurrences of 32, and consider this as carry-over for later treatment.
if (tree.length > 32) carry = tree.splice(-16); // pop off 16 x 32s.
// Make the array length a power of 2 by splitting the greatest value (repeatedly)
let j = tree.length;
while (!powersOf2andZero.includes(tree.length)) {
if (j >= tree.length) j = tree.indexOf(tree[tree.length - 1]); // first occurrence of greatest
// Split greatest value into 2; keep list sorted
tree.splice(j, 1, tree[j] / 2, tree[j] / 2); // delete, and insert twice the half at same spot
j += 2;
}
// Isolate and count factors of 32, 32², 32³, ...etc.
// Add a superiour level in the tree for each power of 32 that is found:
n = Math.floor(n / 32);
let template = 32;
while (n) {
if (tree.length > 1) tree = [tree]; // nest
if (n % 32 < 31 && carry !== null) { // we have room to dump the carry here
tree.push(carry);
carry = null;
}
template = Array(32).fill(template); // nest the template tree, "multiplying" by 32.
for (let i = n % 32; i > 0; i--) tree.push(clone(template));
if (tree.length === 1 && typeof tree[0] !== "number") tree = tree[0]; // Eliminate useless array wrapper
// Turn this top level into a length that is a power of 2 by splitting the longest array (repeatedly)
let j = tree.length;
while (!powersOf2andZero.includes(tree.length)) {
if (j >= tree.length) j = tree.findIndex(elem => elem.length === tree[tree.length - 1].length);
// Split longest array into 2; keep list sorted
let size = tree[j].length / 2;
tree.splice(j, 1, tree[j].slice(0, size), tree[j].slice(size)); // delete, and insert twice the half
j += 2;
}
n = Math.floor(n / 32);
}
// Is the carry still there? Then we cannot avoid adding a level for it
if (carry) return [tree, carry];
return tree;
}
// I/O handling
let input = document.querySelector("input");
let output = document.querySelector("pre");
(input.oninput = function () {
let n = +input.value;
if (isNaN(n) || n % 1 !== 0 || n < 1 || n > 9999999) {
output.textContent = "Please enter an integer between 1 and 9999999";
} else {
let tree = createTree(n);
output.textContent = pretty(tree);
}
})();
function pretty(tree) {
return JSON.stringify(tree, null, 2)
.replace(/\[\s*\d+\s*(,\s*\d+\s*)*\]/g, m => m.replace(/\s+/g, ""))
.replace(/\b\d\b/g, " $&");
}
pre { font-size: 8px }
n: <input type="number" value="927">
<pre></pre>
(Note, the following answers the restriction on part size and the restriction on the number of parts being a power of 2. I missed the part about the number of parts also being restricted, indicating nesting. I'll try to get to that next.)
A simple proof that's also a method is that our minimal number of parts, MIN, is M = floor(N / max_power_of_2) plus the number of set bits in the binary representation of N - M*max_power_of_2; and the maximal number of parts, MAX, is N, where each part is 1.
Each time we divide one of the powers of 2, P, in the power-of-two representation of M (which starts as some count of max_power_of_2) or N-M*max_power_of_2, we have one count less of P, and two more of P/2, another power of 2. This action adds just one part to the partition, meaning we can represent any number of parts between MIN and MAX.
Greedy JavaScript code:
function f(n, maxP){
const maxPowerOf2 = 1 << maxP;
const m = ~~(n / maxPowerOf2);
const A = new Array(maxP + 1).fill(0);
A[maxP] = m;
let nm = n - m * maxPowerOf2;
let p = 0;
let bitCount = 0;
while (nm){
if (nm & 1){
bitCount += 1;
A[p] = 1;
}
nm >>= 1;
p += 1;
}
const min = m + bitCount;
let target = 1;
while (target < min)
target *= 2;
if (target > n)
return -1;
if (target == min)
return A.map((c, p) => [1 << Number(p), c]);
if (target == n)
return [n];
// Target is between MIN and MAX
target = target - min;
let i = m ? maxP : p;
while (target && i > 0){
if (!A[i]){
i -= 1;
continue;
}
const max = Math.min(target, A[i]);
A[i] -= max;
A[i-1] += 2*max;
target -= max;
i -= 1;
}
return target ? -1 : A.map((c, p) => [1 << Number(p), c]);
}
var ns = [74, 85, 87, 127, 1279, 12790, 127901, 63];
var maxP = 5;
for (let n of ns){
let result = f(n, maxP);
let [_n, numParts] = result.reduce(([_n, numParts], [p, c]) => [_n + p * c, numParts + c], [0, 0]);
console.log(n, maxP);
console.log(JSON.stringify(result));
console.log(JSON.stringify([_n, numParts]));
console.log('');
}

Debugging number of possible sums - JavaScript

I'm writing an algorithm that finds the number of possible sums from an array that contains unique values, and a second array that contains the quantity of each corresponding value in the first array. For example, the pair [10, 20, 50] and [1, 2, 1] indicates that the total number of elements that I am combining is actually [10, 20, 20, 50], because there are two instances of the number 20.
My algorithm is currently passing every test except one, and I cannot for the life of me figure out why, since it is passing other, more complicated pairings. Here is my algorithm so far:
function possibleSums(values, quantity) {
const sums = new Set([]);
//my recursive function that finds all possible combinations moving
//down from a specific starting index in the valueArrray:
const combinations = (valueArray, countArray, position, currentSum) => {
if (currentSum > 0) sums.add(currentSum);
for(let i = position; i < valueArray.length; i++){
if (countArray[i] === 0){
continue;
}
currentSum += valueArray[i];
//reduce the count of that value that is still available
countArray[i]--;
//send off a recursive call to find the sum with the next
//available value
combinations(valueArray, countArray, i, currentSum);
//return the original count since `i` is increasing past
//the current value's location in the valueArray
countArray[i]++;
}
}
for (let i = 0; i < values.length; i++){
//start the recursive function calls at each index in the value array
combinations(values, quantity, i, 0)
}
return sums.size
}
This algorithm passes array pairs like :
[3, 1, 1] and [111, 84, 104] with the expected output of 521
[1, 1, 1, 1, 1] and [9, 19, 18, 12, 19] with the expected output of 77
[1, 2, 3] and [2, 3, 10000] with the expected output of 30008
but is failing
[10, 50, 100, 500] and [5, 3, 2, 2] , outputting 96 when the expected output is 122
Can anyone spot what I am missing in my logic?
122 expected output is not too big a test case for logging :)
Let's log the parameters:
...
const combinations = (valueArray, countArray, position, currentSum) => {
console.log(countArray, position, currentSum)
if (currentSum...
We see this, which makes sense:
[ 0, 0, 0, 0 ] 3 1400
But then we also see:
[ 0, 0, 1, 0 ] 3 1400
[ 0, 1, 0, 0 ] 3 1400
...
[ 1, 1, 1, 0 ] 3 1400
which don't.
Changing the current argument during the iteration seems to be affecting the variable during other calls.
Changing
currentSum += valueArray[i];
...
combinations(valueArray, countArray, i, currentSum);
to
//currentSum += valueArray[i];
...
combinations(valueArray, countArray, i, currentSum + valueArray[i]);
seems to do the trick.

Does my merge sort implementation has divide and conquer?

I was told in an interview to write a program for implementing merge sort on the concept of divide and conquer.
I wrote the below program,
var myGlobalArray = undefined;
myGlobalArray = [8,4,17,2,1,32];
example01(myGlobalArray);
myGlobalArray = [48,14,17,2,11,132];
example01(myGlobalArray);
myGlobalArray = [45,14,5,2,1,12];
example01(myGlobalArray);
myGlobalArray = [45,-14,-5,2,1,-12];
example01(myGlobalArray);
myGlobalArray = [38,27,43,3,9,82,10];
example01(myGlobalArray);
function example01(myArray){
var mainArray = [];
createSubArray(myArray,0);
mainArray = mergeArrays(mainArray);
console.log(mainArray[0]);
// creates an array which contains n arrays for n numbers present in myarray
// i.e. if array = [ 34, 1, 27, 3 ] that the below method will return
// [ [34], [1], [27], [3] ]
function createSubArray(subArray,index){
var localArray = [];
if(subArray[index] !== undefined){
localArray.push(subArray[index]);
mainArray.push(localArray);
createSubArray(subArray,++index);// performs division recursively
}
}//createSubArray
// merge the arrays present i.e.
// if gblArray = [ [2,5], [1,7] ]
// then the below method will return
// an merged array [ [1, 2, 5, 7] ]
function mergeArrays(gblArray){
var mergedArrays = [],
main_array = gblArray,
arr = [],
counter = 0,
nextCounter = 0;
do{
while(counter < main_array.length){
nextCounter = counter + 1;
if(main_array[nextCounter] !== undefined){
arr = mergeAndSort(main_array[counter],main_array[nextCounter]);
mergedArrays.push(arr);
}else{
mergedArrays.push(main_array[counter]);
}
counter = nextCounter + 1;
}
main_array = mergedArrays;
mergedArrays = [];
counter = 0;
nextCounter = 0;
}while(main_array.length > 1);
return main_array;
}//mergeArrays
// merges two array and sorts i.e.
// if array1 = [23,1] and array2 = [4,12] than
// the below method returns [1,4,12,23]
function mergeAndSort(array1,array2){
var array2Counter = 0,
array1Counter = 0,
mergedArray = [];
while(array2Counter < array2.length && array1Counter < array1.length){
if(array2[array2Counter] < array1[array1Counter]){
mergedArray.push(array2[array2Counter]);
array2Counter++;
}else{
mergedArray.push(array1[array1Counter]);
array1Counter++;
}
}
while(array1Counter < array1.length){
mergedArray.push(array1[array1Counter]);
array1Counter++;
}
while(array2Counter < array2.length){
mergedArray.push(array2[array2Counter]);
array2Counter++;
}
return mergedArray;
} //mergeAndSort
}//example01
If I run the above code,
the output is
[ 1, 2, 4, 8, 17, 32 ]
[ 2, 11, 14, 17, 48, 132 ]
[ 1, 2, 5, 12, 14, 45 ]
[ -14, -12, -5, 1, 2, 45 ]
[ 3, 9, 10, 27, 38, 43, 82 ]
But by looking at my above implemented merge-sort program, the inteviewer said that if doesn't follows divide and conquer concept.
I tried to convince him that method "mergeArrays" and "mergeAndSort"
do the divide and conquer. But he didn't agreed.
Where am I going wrong ?
The definition of divide and conquer on Wikipedia is:
an algorithm design paradigm based on multi-branched recursion. A divide and conquer algorithm works by recursively breaking down a problem into two or more sub-problems of the same or related type, until these become simple enough to be solved directly. The solutions to the sub-problems are then combined to give a solution to the original problem.
Your solution does divide, and does combine the solutions to give the final solution, but it does not perform the divisions recursively, making the sub problems gradually smaller.
Edit: you do use recursion, but not in the way intended here. Your recursion is tail-recursion, chopping off the smallest unit (they are not gradually getting smaller), and repeating that chopping via a chain of recursive calls, which could just as easily be performed in a loop.
Your solution is a bottom-up approach, while divide and conquer is commonly understood as a top-down method. Although both methods are valid implementations of merge sort, strictly speaking, only one of them uses the divide and conquer paradigm.
But in a broader interpretation, divide and conquer can just as well be bottom-up, relaxing some of the requirements in the definition quoted above. So this may in the end be a matter of opinion.

how to find largest elements from the sorted array?

I have three sorted array I need to find top five "5" element from these array .I am able to find first two element largest element .how I will find other ?
can you suggest how we can find other 3 element ?
here is my code
var maxArray=[];
var array1=[2,7,12,23,40,44,67,88,102]
var array2=[3,12,14,17,23,40,41,67,108]
var array3=[8,12,23,40,59,86,119,130]
var firstMax=array1[array1.length-1];
var secondMax=array2[array2.length-1];
alert(array1[array1.length-1]);
if(array1[array1.length-1]>array2[array2.length-1] && array1[array1.length-1]>array3[array3.length-1]){
maxArray.push(array1[array1.length-1]) ;
firstMax=array1[array1.length-1];
if(array2[array2.length-1]>array3[array3.length-1]){
secondMax=array2[array2.length-1];
}else {
secondMax=array3[array3.length-1];
}
}else if(array2[array2.length-1]>array1[array1.length-1]&& array2[array2.length-1]>array3[array3.length-1]){
maxArray.push(array1[array2.length-1])
firstMax=array2[array2.length-1];
if(array1[array1.length-1]>array3[array3.length-1]){
secondMax=array1[array1.length-1];
}else {
secondMax=array3[array3.length-1];
}
}else{
maxArray.push(array3[array3.length-1])
firstMax=array3[array3.length-1];
if(array2[array2.length-1]>array1[array1.length-1]){
secondMax=array2[array2.length-1];
}else {
secondMax=array1[array1.length-1];
}
}
maxArray.push(secondMax)
alert(maxArray)
fiddle
http://jsfiddle.net/9vsjm8uh/
jsFiddle (yep, even better without jQuery, thanks #Rajacsp)
var array1 = [2, 7, 12, 23, 40, 44, 67, 88, 102]
var array2 = [3, 12, 14, 17, 23, 40, 41, 67, 108]
var array3 = [8, 12, 23, 40, 59, 86, 119, 130]
var flatArray = array1.concat(array2).concat(array3);
flatArray.sort(function sortNumber(a, b) { return b - a; });
var maxArray = flatArray.slice(0, 5);
alert(maxArray); // 130,119,108,102,88
I would suggest the following idea:
Since you are looking for the top 5 values, they will, at worst case, all be in the same list. Thus, there are at most 5 * 3 = 15 values to check.
Then, you can take the 5 highest values from each list (which should be trivial if the list is already sorted), and then put them in another list. Now you have a list of the 15, and you want to find the top 5 values from this list. There are different ways to do this - you could sort the list, then take the top 5 values, or you can simply iterate through the list, finding the max each time.
Combine all of the arrays, sort them, then get the last 5 values.
var total = array1.concat(array2, array3);
total = total.sort(function(a,b){return a-b});
//Now total[length-5] is the 5th largest value
//total[length-4] is the 4th largest and so on
Plain Javascript (no libraries added):
var array1=[2,7,12,23,40,44,67,88,102];
var array2=[3,12,14,17,23,40,41,67,108];
var array3=[8,12,23,40,59,86,119,130];
alert(getTopFive(array1, array2, array3));
function getTopFive(ar1, ar2, ar3){
var finalArray = array1.concat(array2).concat(array3);
finalArray.sort(function sortInverse(a,b) { return b - a; });
return finalArray.slice(0, 5);
}

Categories

Resources