Related
I'm trying to get my code to do this:
Original array = [1,2,3,4] swap once-> [4,2,3,1] swap again->[4,3,2,1]
Therefore result is 2
But it's not working. Here's what I have so far:
function check(arr){
var sarr = [];
var cnt = 0;
var arrL = arr.length;
// Create a second copy of the array for reference
var arrCopy = [...arr];
for(let i=0; i<arrL;i++){
var maxV = Math.max(...arr);
sarr.push(maxV);
let pos = arr.indexOf(maxV);
// Remove the found number
arr.splice(pos,1);
// Check if the index of the number in the new array is same with the copy, if not then there was a swap
let ai =arrCopy.indexOf(maxV);
let si =sarr.indexOf(maxV);
if (ai !== si && (i+1)!=arrL && pos !== 0){
cnt++;
};
}
console.log(cnt);
}
check([1, 2, 3, 4, 5, 6]);//Result should be 3
check([6,5,4,3,2,1]); //result should be 0
check([1,2,3,4]); //result should be 2
check([1,3,2,5,4,6]); //result should be 3
check([1,2,10,4,5,6,7,8,9,3,12,11]);//result should be 6
check([ 49, 37, 9, 19, 27, 3, 25, 11, 53, 42, 57, 50, 55, 56, 38, 48, 6, 33, 28, 8, 20, 31, 51, 14, 23, 4, 58, 52, 36, 22, 41, 47, 39, 2, 7, 13, 45, 1, 44, 32, 10, 15, 21, 30, 17, 60, 29, 5, 59, 12, 40, 24, 54, 46, 26, 43, 35, 34, 18, 16]);//result should be 54
Can someone please let me know what I'm doing wrong?
I would start with a copy of the array in descending order for getting the right index of the items.
For practical reasons, (or just a shorter conception of the loop with including check and decrement), I loop from the end of the array.
Then I check the value of array and reversed at the dame index and go on with the iteration.
If not the same value, the items at the wanted position i and the actual position p are swapped and the count incremented.
At the end the count is returned.
function check(array) {
var reversed = array.slice().sort((a, b) => b - a),
count = 0,
i = array.length,
p;
while (i--) {
if (array[i] === reversed[i]) continue;
p = array.indexOf(reversed[i]);
[array[i], array[p]] = [array[p], array[i]];
count++;
}
console.log(...array);
return count;
}
console.log(check([1, 2, 3, 4, 5, 6])); // 3
console.log(check([6, 5, 4, 3, 2, 1])); // 0
console.log(check([1, 2, 3, 4])); // 2
console.log(check([1, 3, 2, 5, 4, 6])); // 3
console.log(check([1, 2, 10, 4, 5, 6, 7, 8, 9, 3, 12, 11])); // 6
console.log(check([ 49, 37, 9, 19, 27, 3, 25, 11, 53, 42, 57, 50, 55, 56, 38, 48, 6, 33, 28, 8, 20, 31, 51, 14, 23, 4, 58, 52, 36, 22, 41, 47, 39, 2, 7, 13, 45, 1, 44, 32, 10, 15, 21, 30, 17, 60, 29, 5, 59, 12, 40, 24, 54, 46, 26, 43, 35, 34, 18, 16])); // 54
.as-console-wrapper { max-height: 100% !important; top: 0; }
function minimumSwaps(arr) {
var count = 0;
arr.sort((a, b) => {
if (a < b) {
count++;
}
});
return count;
}
console.log(minimumSwaps([1, 2, 3, 4, 7, 6, 5]));
I need to make a utility that checks the intersection of 3 arrays.
Here's my implementation in JS:
function intersection(array1, array2, array3) {
let intermediateList = [];
let intermediateList2 = [];
for (let i = 0; i < array1.length; i++) {
if (!(array2.indexOf(array1[i]) == -1)) {
intermediateList.push(array1[i]);
}
for (let j = 0; j < intermediateList.length; j++) {
if (!(intermediateList.indexOf(array3[j]) == -1)) {
intermediateList2.push(intermediateList[i]);
}
}
}
let endList = [ ...intermediateList, ...intermediateList2];
return endList;
}
intersection([5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20])
// [5, 15] /--> fine
intersection([5, 10, 15, 20, 40, 32], [32, 15, 88, 1, 5, 7, 40], [1, 10, 15, 5, 20, 40, 32])
// [5, 15, 40, 32, undefined, undefined, undefined] /--> can someone spot why do I get those undefined values?
How would you implement this with reduce?
Your function has a nested for loop which iterates the intermediateList every time where the outer loop is running. Then you push a value with index i instead of index j, but this should work only if the two for loops are not nested but chained.
function intersection(array1, array2, array3) {
let intermediateList = [];
let intermediateList2 = [];
for (let i = 0; i < array1.length; i++) {
if (array2.indexOf(array1[i]) !== -1) {
intermediateList.push(array1[i]);
}
}
for (let j = 0; j < intermediateList.length; j++) {
if (array3.indexOf(intermediateList[j]) !== -1) {
intermediateList2.push(intermediateList[j]);
}
}
return intermediateList2;
}
console.log(intersection([5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20]));
console.log(intersection([5, 10, 15, 20, 40, 32], [32, 15, 88, 1, 5, 7, 40], [1, 10, 15, 5, 20, 40, 32]));
.as-console-wrapper { max-height: 100% !important; top: 0; }
You could reduce the arguments and return a single array with common values.
const intersection = (...array) => array.reduce((a, b) => a.filter(v => b.includes(v)));
console.log(intersection([5, 10, 15, 20], [15, 88, 1, 5, 7], [1, 10, 15, 5, 20]));
console.log(intersection([5, 10, 15, 20, 40, 32], [32, 15, 88, 1, 5, 7, 40], [1, 10, 15, 5, 20, 40, 32]));
I have the following example data:
[0] = {01,02,03, 04,05,06, 07,08,09}
[1] = {11,12,13, 14,15,16, 17,18,19}
[2] = {21,22,23, 24,25,26, 27,28,29}
[3] = {31,32,33, 34,35,36, 37,38,39}
[4] = {41,42,43, 44,45,46, 47,48,49}
[5] = {51,52,53, 54,55,56, 57,58,59}
[6] = {61,62,63, 64,65,66, 67,68,69}
[7] = {71,72,73, 74,75,76, 77,78,79}
[8] = {81,82,83, 84,85,86, 87,88,89}
To create the new matrix I did this, Knowing it static 9x9
var grid2=[[],[]];
grid2.push([grid[0][0],grid[0][1], grid[0][2],grid[1][0],grid[1][1], grid[1][2],grid[2][0],grid[2][1], grid[2][2]]);
grid2.push([grid[3][0],grid[3][1], grid[3][2],grid[4][0],grid[4][1], grid[4][2],grid[5][0],grid[5][1], grid[5][2]]);
grid2.push([grid[6][0],grid[6][1], grid[6][2],grid[7][0],grid[7][1], grid[7][2],grid[8][0],grid[8][1], grid[8][2]]);
grid2.push([grid[0][3],grid[0][4], grid[0][5],grid[1][3],grid[1][4], grid[1][5],grid[2][3],grid[2][4], grid[2][5]]);
grid2.push([grid[3][3],grid[3][4], grid[3][5],grid[4][3],grid[4][4], grid[4][5],grid[5][3],grid[5][4], grid[5][5]]);
grid2.push([grid[6][3],grid[6][4], grid[6][5],grid[7][3],grid[7][4], grid[7][5],grid[8][3],grid[8][4], grid[8][5]]);
grid2.push([grid[0][6],grid[0][7], grid[0][8],grid[1][6],grid[1][7], grid[1][8],grid[2][6],grid[2][7], grid[2][8]]);
grid2.push([grid[3][6],grid[3][7], grid[3][8],grid[4][6],grid[4][7], grid[4][8],grid[5][6],grid[5][7], grid[5][8]]);
grid2.push([grid[6][6],grid[6][7], grid[6][8],grid[7][6],grid[7][7], grid[7][8],grid[2][6],grid[8][7], grid[8][8]]);
This works, but my question is, can this be done more efficiently / elegantly.
The point of this, is part of a larger code base, that takes the matrix and validates if it is a Sudoku solution.
You can use a simple algorithm for this
let idx = [0, 1, 2], idy = [0, 1, 2];
let result = [];
for(let i=0; i<9; i+=3){
for(let j=0; j<9; j+=3){
idx.forEach(e => {
idy.forEach(f => {
result.push(arr[i+e][j+f]);
})
})
}
}
You could take a nested approach for transforming the given 2D to a 4D array.
var data = [[1, 2, 3, 4, 5, 6, 7, 8, 9], [11, 12, 13, 14, 15, 16, 17, 18, 19], [21, 22, 23, 24, 25, 26, 27, 28, 29], [31, 32, 33, 34, 35, 36, 37, 38, 39], [41, 42, 43, 44, 45, 46, 47, 48, 49], [51, 52, 53, 54, 55, 56, 57, 58, 59], [61, 62, 63, 64, 65, 66, 67, 68, 69], [71, 72, 73, 74, 75, 76, 77, 78, 79], [81, 82, 83, 84, 85, 86, 87, 88, 89],],
result = data.reduce((r, a, i) => (
a.forEach((b, j) =>
[Math.floor(i / 3), Math.floor(j / 3), i % 3].reduce(
(s, k) => s[k] = s[k] || [],
r
)[j % 3] = b),
r),
[]);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
I have an array that can be of any length. and need to split it into sections. The first section will be a length of 14, and there after a length of 16
var size1 = 14;
var size2 = 16;
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40];
var arrays = [];
if (a.length > 14){
for (i = 0; i < 14; i++) {
arrays.push(a.splice(0, size1));
}
for (i = 14 ; i < a.length; i++){
arrays.push(a.splice(0, size2));
}
} else {
arrays.push(a.splice(0, size1));
}
console.log(arrays);
However based on what I am doing my array keeps splitting only at 14. Can you advice on how I can do this?
Thank you
The solution using Array.prototype.slice() function:
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
size1 = 14,
size2 = 16,
arrays = [];
[0, size1, size2].forEach(function (v, i, arr) {
arrays.push((arr[i+1])? a.slice(v, v + arr[i+1]) : a.slice(arr[i-1] + v));
});
console.log(arrays);
You could use an array for the chunk length and a zero for the rest and map the chunks by keeping the length of the previous lengths.
It works for an arbitrary count of chunks.
var chunks = [14, 16, 0],
array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40],
result = chunks.map((last => a => array.slice(last, a ? (last += a) : undefined))(0));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Edit: so, like this then?
var size1 = 14;
var size2 = 16;
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40];
var head = a.slice(0, size1);
var arrays = [head];
while (size1 < a.length){
arrays.push(a.slice(size1, Math.min(size1+size2, a.length)));
size1 += size2;
}
console.log(arrays)
You can try this with all dynamic array sizes, it will get you desired output.
Hope you were looking for this solution.
var size1 = 14;
var size2 = 16;
var flag=0;
var a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40];
var arrays = [];
var t=a.length/14;
while(a.length>0){
if (flag==0 && a.length > 14){
arrays.push(a.splice(0, size1));
flag=1;
} else if(a.length>=16){
arrays.push(a.splice(0, size2));
}
else{
arrays.push(a.splice(0, a.length));
}
}
console.log(arrays)
I have an array that looks like:
var myArray = [12, 24, 36, 48, 60, 15, 30];
I need to build a new array of arrays from this to show the index number from the original array in the new array. The final result should look like the following:
var myNewArray = [
[1, 12],
[2, 24],
[3, 36],
[4, 48],
[5, 60],
[6, 15],
[7, 30]
];
You can use
Array.prototype.map(), and then generate new array based on value and index of that array.
Demo
var myArray = [12, 24, 36, 48, 60, 15, 30],
newArray = myArray.map(function (value, index) {
return [index + 1, value];
});
FYI: - JavaScript arrays are zero-indexed: the first element of an array is at index 0
var myArray= [12, 24, 36, 48, 60, 15, 30],
myArrayIndexed= myArray.map(function(itm, i){
return [i+1, itm];
});
myArrayIndexed.join(']\n[');
/* returned value: */ [
[1, 12],
[2, 24],
[3, 36],
[4, 48],
[5, 60],
[6, 15],
[7, 30]
]
It's as simple as that:
var myArray = [12, 24, 36, 48, 60, 15, 30];
var myNewArray = [];
for (var i = 0; i < myArray.length; i++) {
myNewArray.push([i+1,myArray[i]]);//or just i depending on the index you need
}
Even a faster way is to cache the length of the array:
for (var i = 0, var l = myArray.length; i < l; i++) {}
To my knowledge and research so far - Javascript's native for loop is quicker than array map for iterating through the array. Here is an interesting benchmark.
Hope this helps!