Merge Sort JS .......Not able to understand it - javascript

function MergeSortCaller() {
let array = [7, 2, 9, 3]
const auxiliaryArray = array.slice();
partition (array, 0, array.length - 1, auxiliaryArray);
}
function partition(
mainArray,
startIdx,
endIdx,
auxiliaryArray,
) {
if (startIdx === endIdx) return;
const middleIdx = Math.floor((startIdx + endIdx) / 2);
partition (auxiliaryArray, startIdx, middleIdx, mainArray);
partition (auxiliaryArray, middleIdx + 1, endIdx, mainArray);
doMerge (mainArray, startIdx, middleIdx, endIdx, auxiliaryArray);
}
function doMerge(
mainArray,
startIdx,
middleIdx,
endIdx,
auxiliaryArray,
) {
let k = startIdx;
let i = startIdx;
let j = middleIdx + 1;
while (i <= middleIdx && j <= endIdx) {
if (auxiliaryArray[i] <= auxiliaryArray[j]) {
mainArray[k++] = auxiliaryArray[i++];
} else {
mainArray[k++] = auxiliaryArray[j++];
}
}
while (i <= middleIdx) {
mainArray[k++] = auxiliaryArray[i++];
}
while (j <= endIdx) {
mainArray[k++] = auxiliaryArray[j++];
}
console.log(auxiliaryArray, mainArray)
}
MergeSortCaller()
Output:-
Aux -> 7 2 9 3
Main -> 2 7 9 3
Aux -> 7 2 9 3
Main -> 2 7 3 9
Aux -> 2 7 3 9
Main -> 2 3 7 9
This is working code of Merge Sort. But I am not able to get that how in the 3rd call of doMerge(), the auxilaryArray get changed even I don't make any change to it.
In the code all the changes are happening to mainArray.
PLZ help me...
Thanks...

Visit Graphical Structure for Visualization of mergesort it may help you.

Related

Digital Root (repeated digital sum) code issue

Question : Given n, take the sum of the digits of n. If that value has
more than one digit, continue reducing in this way until a
single-digit number is produced. The input will be a non-negative
integer. Ex- 16 --> 1 + 6 = 7 942 --> 9 + 4 + 2 = 15 --> 1 +
5 = 6 132189 --> 1 + 3 + 2 + 1 + 8 + 9 = 24 --> 2 + 4 = 6 493193
--> 4 + 9 + 3 + 1 + 9 + 3 = 29 --> 2 + 9 = 11 --> 1 + 1 = 2
function digitalroot(n) {
let a = n;
var sum = 0;
while(a >= 1){
sum += a % 10;
a = Math.trunc(a/10)
}
if(sum > 9){
digitalroot(sum)
}
console.log("Print")
console.log(sum)
return sum
}
I tried above code but not getting correct output with below called input
With this two inputs passed in function: (16), (456)
O/P:
Print
7
Print
6
Print
15
Please help me, I am new to JavaScript
you forgot to return value from function call inside that sum>9 condition.
check recursion here : w3School
function digitalroot(n) {
let a = n;
var sum = 0;
while(a >= 1){
sum += a % 10;
a = Math.trunc(a/10)
}
if(sum > 9){
return digitalroot(sum)
}
return sum
}
console.log(digitalroot(493193));
Check this working example
function digitalroot(n){
console.log(`Value of n = ${n}`)
var digits = (""+n).split("");
for (var i = 0; i < digits.length; i++) {
digits[i] = +digits[i];
}
var finalVal = digits
let result = finalVal.reduce((a, b) => a + b, 0)
console.log(`Final Value with list ${result}`)
}
digitalroot(289)

how to create matrix as in description [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
How to create matrix, output have to looks like:
1, 3, 5, 7, 9
2, 4, 6, 8, 10
11, 13, 15, 17, 19
20, 22, 24, 26, 28
Expecting for answer on JS, but this is not the point because I`m looking for an algorithm.
Thanks.
I have tried something like this:
let arr = [];
for(let i = 0; i < 2; i++){
arr[i] = []
for(let j = 0; j < 5; j++){
if(j % 2 ==0){
arr[j] = i
}
}
}
console.log(arr)
As you can see there's a common digit 2 is added each time once you fix the starting point. so here i fixed two starting point one is even at 2 and another one is odd at 1. Now in each iteration increment both values by 2 and add both the evenArray and oddArray to final output.
Don't forget to reset evenArray and oddArray after each iteration of inner for loop.
let even = 2;
let odd = 1;
let arr = [];
for(let i = 0; i < 2; i++){
let evenArr = []
let oddArr = []
for(let j = 0; j < 5; j++){
evenArr[j] = even;
oddArr[j] = odd;
even +=2;
odd +=2;
}
even = (even-2) * 2; // to take care of point where even starts with double of last inserted value.
arr.push(oddArr.join(' '),evenArr.join(' '))
}
console.log(arr)
First, try to get the building rule
row start comment
---- ---- ---- ---- ---- ------ ------ -------------------
1 3 5 7 9 odd 1
2 4 6 8 10 even 2
11 13 15 17 19 odd 10 needs an adjustment
20 22 24 26 28 even 20
Then create an array with the wanted rows and fill it with the value. Swich the start value for each line either with 2 or 5, depending on the row's index.
Inside of each row take the start value, an adjustment for not even or odd numbers and add the double of the inner index.
var array = Array.from(
{ length: 4 },
(start => (_, i) => Array.from(
{ length: 5 },
(v => (_, j) => v + (v % 2 === i % 2) + j * 2)
(start *= (i % 2 ? 2 : 5))
))
(0.2)
);
console.log(array.map(a => a.join(' ')));
.as-console-wrapper { max-height: 100% !important; top: 0; }

What type of sorting algorithm resembles the most to this code? (if any).

I am learning programming (with Javascript) and as a test I decided to find a way to wrote an algorithm to sort and array of strings, this is what I came up with.
// test of a sorting algorithm
var steps = 0;
var steps2 = 0;
var array = ['assa', 'erer', 'qwqw', 'ggdffdghdg', 'sdsdethhhghg', 'aaaaaa', 'gthfyjfdsfdf', 'qwqwwere', 'jygyghhf', '1', '0', '345', 'sfsdsddsfsf', 'eee3ew33', '1dwd', 'ddd2'];
var array2 = ['erer', 'jygyghhf', '1', '0', '345', 'sfsdsddsfsf', 'eee3ew33', '1dwd', 'ddd2'];
console.log('array before sort');
console.log(array);
function simpleSort(array) {
let length = array.length;
let currentPos = 1;
while (currentPos < length) {
let pivot = 0;
do {
let currentValue = array[currentPos];
if (currentValue > array[pivot]) {
array.splice(currentPos, 1);
array.splice(pivot, 0, currentValue);
steps++;
}
steps2++;
pivot++;
}
while (currentPos > pivot);
currentPos++;
}
console.log(array);
console.log('steps = ' + steps);
console.log('steps2 = ' + steps2);
}
console.log('********************');
console.log('array after sort');
simpleSort(array);
console.log('********************');
console.log('array after sort with array.sort() and array.reverse() buit in functions');
array.sort();
console.log(array.reverse());
What type of sorting algorithm would resemble most to this code and what would be the big O of this
The algorithm is the same as the following, so it has a similar structure to the O(n^2) sort algorithms.
function simpleSort(array) {
for (var currentPos = 1; currentPos < array.length; currentPos++) {
for (var pivot = 0; pivot < currentPos; pivot++) {
let currentValue = array[currentPos];
if (currentValue > array[pivot]) {
array.splice(currentPos, 1);
array.splice(pivot, 0, currentValue);
}
}
}
}
With an input of [6, 3, 5, 4, 1, 8, 6, 3], after each iteration you have:
6 3 5 4 1 8 6 3
6 3 5 4 1 8 6 3
6 5 3 4 1 8 6 3
6 5 4 3 1 8 6 3
6 5 4 3 1 8 6 3
8 6 5 4 3 1 6 3
8 6 6 5 4 3 1 3
8 6 6 5 4 3 3 1
This shows that the left side is sorted at each step, and increases in size by one each iteration. This is the same as insertion sort.
The if condition can only be true once for each iteration because after the splice, currentValue will become equal to the smallest value in the left array and compared to larger values each time. So it has O(n^2) time complexity.

code check for multiple of 3 and 5

I wrote a code with javascript for this problem :
"If we list all the natural numbers below 10 that are multiples of 3 or 5, we get 3, 5, 6 and 9. The sum of these multiples is 23.
Find the sum of all the multiples of 3 or 5 below 1000."
but the result is false and i don't know why? can you help me guys
my code is :
function multipleSum(n){
var sum = 0;
for(var i = 1; i<n; i++){
var m3 = 3 * i;
var m5 = 5 * i;
if(m3 < n ){
sum=sum+m3
}
if(m5 < n ){
sum=sum+m5;
}
//if(m3 > n && m5 > n) {console.log(m3,m5,sum);break;}
}
return sum
}
console.log(multipleSum(1000)) //266333 but correct one is 233168 why?
Your logic is flawed. You should be iterating on each number (specified in range), and see if the modulus of the number with 3 or 5 is 0 or not. If modulus is zero, it means the number is divisible.
function multipleSum(n){
var sum = 0;
for(var i = 1; i<n; i++){
if(i % 3 == 0 || i % 5 ==0){ // gives reminder of 0, divisible by either 3 or 5
sum += i; // add in sum if that's the case.
}
}
return sum
}
console.log(multipleSum(1000))
Edit: tried some time understanding why you went with multiply approach, I think you are gathering factors and want to break out early from the loop instead of iterating on entire collection. This should help you:
function multipleSum(n){
var sum = 0;
for(var i = 1; i<n; i++){
var m3 = i * 3;
var m5 = i * 5;
if(m3 > n) break; // breaks early!!
if(m3 < n) sum += m3
if(m5 < n && m5 % 3 != 0) sum += m5; // make sure number is not divisible by 3, say m5 = 15, it will be captured as multiple of 3 anyway, we don't want duplicates.
}
return sum
}
console.log(multipleSum(1000))
Your logic is flawed in the way that, all the multiplications of 3 * 5 is doubled. Remember, you have:
3 * 1
5 * 1
3 * 2
3 * 3
5 * 2
3 * 4
3 * 5
5 * 3 // Here comes the dupe.
I would do this in a different way.
Get all the multiples of 3 in an array.
Get all the multiples of 5 in an array.
Break the loop when both the multiplications are greater than n.
Merge both the arrays.
Remove the duplicates.
Add everything using the .reduce() function.
var num = 1000;
var m3 = [];
var m5 = [];
for (i = 0; i < num; i++) {
if (i * 3 < num)
m3.push(i * 3);
if (i * 5 < num)
m5.push(i * 5);
if (i * 3 > num)
break;
}
m35 = m3.concat(m5);
m35u = m35.filter(function(item, pos) {
return m35.indexOf(item) == pos;
});
console.log(m35u.reduce((a, b) => a + b, 0));
I get 233168 as answer.
You can try this one liner (your home work: explain how this works ;):
console.log(
Array.from({length: 1000})
.reduce( (p, n, i) => p + (i % 3 === 0 || i % 5 === 0 ? i : 0), 0 )
);
Try this, maybe answer you.Thank
const solution = (numb) => {
const collectedNumb = [];
const maxDividing = parseInt(numb / 3);
for (let idx = 1; idx <= maxDividing; idx++) {
const multipled3 = idx * 3;
const multipled5 = idx * 5;
multipled3 < numb && collectedNumb.push(multipled3);
multipled5 < numb && collectedNumb.push(multipled5);
}
const uniqCollected = [...new Set(collectedNumb)].sort((a, b)=> a-b);
console.log(uniqCollected);
const reduced = uniqCollected.reduce((acc, numb) => acc + numb, 0);
return reduced;
};

rotate a matrix 45 degrees in javascript

given a matrix like this one:
1 2 3
4 5 6
7 8 9
which can be represented as a 2 dimensional array:
arr = [[1,2,3], [4,5,6], [7,8,9]];
rotate the array so that it is read diagonally at a 45 degree angle and prints out this:
1
4 2
7 5 3
8 6
9
I spent a while coming up with a solution that I don't even fully intuitively understand, but it works, at least for 3x3 and 4x4 matrices. I was hoping to see more logical and clean implementations.
Here's my solution:
arr = [[1,2,3,0],[4,5,6,0],[7,8,9,0], [0,0,0,0]];
// arr[i][j];
transform(arr);
function transform(ar) {
// the number of lines in our diagonal matrix will always be rows + columns - 1
var lines = ar.length + ar[0].length - 1;
// the length of the longest line...
var maxLen = ~~(ar.length + ar[0].length)/2;
var start = 1;
var lengths = [];
// this for loop creates an array of the lengths of each line, [1,2,3,2,1] in our case
for (i=0;i<lines; i++) {
lengths.push(start);
if (i+1 < maxLen) {
start++;
} else {
start--;
}
}
// after we make each line, we're going to append it to str
var str = "";
// for every line
for(j=0; j<lengths.length; j++) {
// make a new line
var line = "";
// i tried to do it all in one for loop but wasn't able to (idk if it's possible) so here we use a particular for loop while lengths of the lines are increasing
if (j < maxLen) {
// lengths[j] is equal to the elements in this line, so the for loop will run that many times and create that many elements
for(c=0; c<lengths[j]; c++) {
// if ar[r][c], the pattern here is that r increases along rows (as we add new lines), and decreases along columns. c stays the same as we add rows, and increases across columns
line += ar[lengths[j]-1-c][c] + " ";
// when we've added all the elements we need for this line, add it to str with a line break
if (c == lengths[j]-1) {
line += "\n"; str += line;
}
}
} else {
// when we're headed down or decreasing the length of each line
for (r=0; r<lengths[j]; r++) {
// the pattern here tripped me up, and I had to introduce another changing variable j-maxLen (or the distance from the center). r stays the same as rows increase and decreases across columns. c increases along rows and decreases across columns
line += ar[lengths[j]-r+j-maxLen][j-maxLen+r +1] + " ";
// that's all our elements, add the line to str;
if (r == lengths[j] -1) {
line += "\n"; str += line;
}
}
}
}
console.log(str);
}
The main idea is to partition the original matrix indexed by (i,j) according to i+j.
This is expressed in the code snippet rotated[i+j].push(arr[i][j]) below:
arr = [[1,2,3], [4,5,6], [7,8,9]];
var summax = arr.length + arr[0].length - 1; // max index of diagonal matrix
var rotated = []; // initialize to an empty matrix of the right size
for( var i=0 ; i<summax ; ++i ) rotated.push([]);
// Fill it up by partitioning the original matrix.
for( var j=0 ; j<arr[0].length ; ++j )
for( var i=0 ; i<arr.length ; ++i ) rotated[i+j].push(arr[i][j]);
// Print it out.
for( var i=0 ; i<summax ; ++i ) console.log(rotated[i].join(' '))
Output:
1
4 2
7 5 3
8 6
9
In Ruby
Produces same output:
puts arr.transpose.flatten.group_by.with_index { |_,k|
k.divmod(arr.size).inject(:+) }.values.map { |a| a.join ' ' }
function transform(ar) {
var result = [],
i, x, y, row;
for (i = 0; i < ar.length; i++) {
row = [];
for (x = 0, y = i; y >= 0; x++, y--) {
row.push(ar[y][x]);
}
result.push(row);
}
for (i = 1; i < ar[0].length; i++) {
row = [];
for (x = i, y = ar[0].length - 1; x < ar[0].length; x++, y--) {
row.push(ar[y][x]);
}
result.push(row);
}
return result;
}
This returns the rotated array, to print it out as you go just replace each result.push(row); line with console.log(row.join(" "));.
Here's my approach:
var origMatrix = [[1,2,3,4,5], [4,5,6,7,8], [9,10,11,12,13], [14,15,16,17,18], [19,20,21,22,23]];
var maxSize = origMatrix.length;//Presuming all internal are equal!
var rotatedMatrix = [];
var internalArray;
var keyX,keyY,keyArray;
for(var y=0;y<((maxSize * 2)-1);y++){
internalArray = [];
for(var x=0;x<maxSize;x++){
keyX = x;
keyY = y - x;
if(keyY > -1){
keyArray = origMatrix[keyY];
if(typeof(keyArray) != 'undefined' && typeof(keyArray[keyX]) != 'undefined'){
internalArray.push(keyArray[keyX]);
}
}
}
rotatedMatrix.push(internalArray);
}
//log results
for(var i=0;i<rotatedMatrix.length;i++){
console.log(rotatedMatrix[i]);
}
Here's a JSFiddle of it in action (open the Console to see the results)
The Idea: Walk the Diagonals and Clip
You could use the diagonal enumeration from Cantor, see Cantor pairing function,
which is used to show that the set N x N has the same cardinality as the set N (i.e. natural numbers can be mapped one to one to pairs of natural numbers) and combine it with a condition that one skips those values which lie outside the rectangular matrix.
The Cantor pairing function pi takes two natural numbers i and j, i.e. the pair (i, j) and maps it to a natural number k
pi : |N x |N -> |N : pi(i, j) = k
Use the reverse mapping to get this
pi^-1 : |N -> |N x |N : pi^-1(k) = (i, j)
i.e. one enumerates the cells of the "infinite Matrix" N x N diagonally.
So counting up k and applying the inverse function will give the proper pair of indices (i, j) for printing the rotated matrix.
Example:
0->(0, 0) 2->(0, 1) | 5->(0, 2) 9->(0, 3) . .
1->(1, 0) 4->(1, 1) | 8->(1, 2)
3->(2, 0) 7->(2, 2) |
---------------------+ <- clipping for 3 x 2 matrix
6->(3, 0)
.
.
Calculation of the Inverse Cantor Pair Function
For input k these formulas give the pair (i, j):
w = floor((sqrt(8*k + 1) - 1) / 2)
t = (w*w + w) / 2
j = k - t
i = w - j
See the link given above for a derivation.
Resulting Algorithm
Given a m x n matrix A: i from [0, .., m - 1] enumerates the rows, and j from [0, .., n - 1] enumerates the columns
Start at k = 0
calculate the corresponding index pair (i, j)
print the matrix value A[i, j] if the indices i and j lie within your matrix dimensions m and n
print a new line, once your i hit the top of the matrix, i.e. if i == 0
increment k
continue with step 2 until you arrived at the index pair (i, j) = (n - 1, n - 1)
Sample Implementation in JavaScript
Note: I tried this out in the MongoDB shell, using its print() function.
Helper functions
function sprint(k) {
var s = '' + k;
while (s.length < 3) {
s = ' ' + s;
}
return s;
}
function print_matrix(a) {
var m = a.row_size;
var n = a.column_size;
for (var i = 0; i < m; i++) {
var s = '';
for (var j = 0; j < n; j++) {
s += sprint(a.value[i][j]);
}
print(s);
}
}
The Inverse of the Cantor pairing function
// inverse of the Cantor pair function
function pi_inv(k) {
var w = Math.floor((Math.sqrt(8*k + 1) - 1) / 2);
var t = (w*w + w) /2;
var j = k - t;
var i = w -j;
return [i, j];
}
The algorithm
// "rotate" matrix a
function rot(a) {
var m = a.row_size;
var n = a.column_size;
var i_max = m - 1;
var j_max = n - 1;
var k = 0;
var s = '';
do {
var ij = pi_inv(k);
var i = ij[0];
var j = ij[1];
if ((i <= i_max) && (j <= j_max)) {
s += sprint(a.value[i][j]);
}
if (i == 0) {
print(s);
s = '';
}
k += 1
} while ((i != i_max) || (j != j_max));
print(s);
}
Example usage
// example
var a = {
row_size: 4,
column_size: 4,
value: [ [1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16] ]
};
print('in:');
print_matrix(a);
print('out:');
rot(a);
Output for 4x4 Matrix
in:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
out:
1
5 2
9 6 3
13 10 7 4
14 11 8
15 12
16
This method works for any m x n Matrix, e.g. 4 x 5:
in:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
16 17 18 19 20
out:
1
6 2
11 7 3
16 12 8 4
17 13 9 5
18 14 10
19 15
20
or 4 x 3:
in:
1 2 3
4 5 6
7 8 9
10 11 12
out:
1
4 2
7 5 3
10 8 6
11 9
12

Categories