Assume I have a simple array:
[1, 20, 15, 37, 46, 9]
I need to make it look like this:
[1, 9, 15, 46, 37, 20]
So the idea is to put the largest value or pair of the largest two values in the middle of the array then put decreasing numbers to the right and to the left of it like a pyramid.
I have a couple of ideas but they don't seem elegant enough. Please advise.
Assume I have a simple array:
[1, 20, 15, 37, 46, 9]
I need to make it look like this:
[1, 9, 15, 46, 37, 20]
So the idea is to put the largest value or pair of the largest two values in the middle of the array then put decreasing numbers to the right and to the left of it like a pyramid.
I have a couple of ideas but they don't seem elegant enough. Please advise.
Share Improve this question asked Feb 20, 2014 at 14:40 Sergei BasharovSergei Basharov 53.9k78 gold badges207 silver badges352 bronze badges 2 |9 Answers
Reset to default 3Try this:
var arr = [1, 20, 15, 37, 46, 9];
arr.sort(function (a, b) {
return a - b;
});
var arr1 = arr.slice(0, arr.length / 2);
var arr2 = arr.slice(arr.length / 2, arr.length);
arr2.sort(function (a, b) {
return b - a;
});
arr = arr1.concat(arr2);
console.log(arr);
This method is resumed to two steps:
[1, 20, 15, 37, 46, 9] // step 1: sort the entire array
[1, 9, 15, 20, 37, 46] // step 2: sort the second half of the array
[1, 9, 15, 46, 37, 20]
var arr = [1,20,15,37,46,9];
arr.sort(function(a,b){
return a-b;
});
var right = arr.slice(arr.length/2,arr.length).reverse();
var left = arr.slice(0,arr.length/2);
arr = left.concat(right);
console.log(arr);
This can be optimized, but it works.
function pyramid (arr) {
var newArr = [];
// sort numerically
arr.sort(function (a, b) {
return a - b;
});
// put the biggest in new array
newArr.push(arr.pop());
// keep grabbing the biggest remaining item and alternate
// between pushing and unshifting onto the new array
while (arr.length) {
newArr[arr.length % 2 === 0 ? 'push' : 'unshift'](arr.pop());
}
return newArr;
}
pyramid([1, 20, 15, 37, 46, 9]
returns [1, 15, 37, 46, 20, 9]
Here is another short chained approach:
[1, 20, 15, 37, 46, 9].sort(function(a, b) {
return a - b;
}).map(function(v, i, a) {
var p = ~~(a.length / 2);
return i >= p ? a[a.length - i + p - 1] : v;
});
// [1, 9, 15, 46, 37, 20]
Seems to work fine with any number of elements in the array.
I can't give you a javascript example, but I would first put each array element in order, then enumerate (give an index), and then add them in even/odd order from front and back.
[1, 20, 15, 37, 46, 9]
becomes
[1, 9, 15, 20, 37, 46]
then print odd indices up to half the array size, and then print even indices from the end back down to halfway.
edit: python for fun:
tt = sorted([1, 20, 15, 37, 46, 9])
print tt[0:len(tt)/2] + list(reversed(tt[len(tt)/2:len(tt)]))
The technique of sorting the array, halving it, then splicing them together doesn't work as well when you have more elements. One side is "bigger" than the other.
let arr = [361, 324, 289, 256, 225, 196, 169, 144, 121, 100, 81, 64, 49, 36, 25, 16, 9, 4, 1, 0];
arr = arr.slice(arr.length/2).reverse().concat(arr.slice(0,arr.length/2));
// [0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 361, 324, 289, 256, 225, 196, 169, 144, 121, 100]
Interleaving the odd and even indexes looks better, and only takes slightly longer
arr = arr.filter((v, i)=>i % 2 === 0).reverse().concat(arr.filter((v, i)=>i % 2 === 1));
// [1, 9, 25, 49, 81, 121, 169, 225, 289, 361, 324, 256, 196, 144, 100, 64, 36, 16, 4, 0]
Much simpler algorithm
First - order the array in a descending order and define a new empty array.
Second - iterate through the sorted array and insert its items in the following way - if even push to the empty array else unshift the item.
Example
let randoms = [7 ,53 ,21, 43 ,45 ,8, 12, 9, 3, 22, 21]; //some random unsorted array
randoms.sort((a,b) => b - a); // sorting the array
let sortedFromMiddle = []; //the new empty array
randoms.forEach(( num, index ) => {
index % 2 === 0 ? sortedFromMiddle.push(num) : sortedFromMiddle.unshift(num);
});
console.log(sortedFromMiddle); // will log the array
The return from a splice is an array of items that is removed from the original-
function pyramid(arr){
var mid= Math.floor(arr.length/2);
var a2= arr.sort(function(a,b){return a-b}).splice(mid);
return arr.concat(a2.reverse());
}
var a1= [1, 20, 15, 37, 46, 9];
pyramid(a1)
/* returned value: (Array) 1,9,15,46,37,20 */
var data = [1, 20, 15, 37, 46, 9];
arr = data.sort(function(a, b){return a - b});
console.log(arr);
This will return you [1, 9, 15, 20, 37, 46]
46, 37
and not15, 46,
? – Johan Commented Feb 20, 2014 at 14:46