I wrote code in JavaScript but issues with start value ex: ?-9, ?-87...etc
Input: {88, 105, 3, 2, 200, 0, 10}
<script type="text/javascript">
function RangeValues(){
var a = [88, 105, 3, 2, 200, 0, 10];
var n = a.length;
var pq = [];
for(var i = 0; i<n; i++) {
if(a[i] >= 0 && a[i] <= 99)
pq.push(a[i]);
}
var start = 0;
if(!Array.prototype.last) {
Array.prototype.last = function() {
return this[this.length - 1];
}
}
while(pq.length != 0)
{
var num = pq.last();
pq.pop();
if(num - start > 1){
console.log( (start) +','+ (num-1));
}
if((num - start) == 1)
{
start = num + 1;
console.log(start);
}
}
if(start == 99){
console.log('99');
}
else if(start < 100) {
console.log(start+' to '+99);
}
return 0;
}
RangeValues();
</script>
actual output: 0-9,0-1,0-2,0-87,0-99
Expected: 1,4-9,11-87,89-99
First, you should sort number in array pq descending so the last value is the min number. Try with below solution:
function RangeValues(){
var a = [88, 105, 3, 2, 200, 0, 10];
//var a = [12, 105, 23, 1, 200, 4, 21];
var n = a.length;
var pq = [];
for(var i = 0; i<n; i++) {
if(a[i] >= 0 && a[i] <= 99){
pq.push(a[i]);
}
}
// sort array descending
pq.sort(function(a, b){return b-a});
var start = 0;
if(!Array.prototype.last) {
Array.prototype.last = function() {
return this[this.length - 1];
}
}
while(pq.length != 0){
var num = pq.last();
pq.pop();
if (num-start == 2 || num == 1){
console.log(num-1);
} else if((num - start)>2){
var from = start + 1;
var end = num - 1;
console.log(from+" - "+end);
}
start = num;
}
if (start < 98){
var from = start + 1;
console.log(from+" - "+99);
} else if( start == 98){
console.log(start+1);
}
return 0;
}
RangeValues();
Related
I am writing a program to calculate euclidean distance and then display the lines based, with the below code:
function discreteFrechet(X, Y) {
var M = X.length;
var N = Y.length;
var S = [
[],
[]
];
var backpointers = [
[],
[]
];
var backpaths = [];
var idx;
var path = [];
var paths;
var back = [
[],
[]
];
for (i = 0; i < M; i++) {
for (j = 0; j < N; j++) {
S[i][j] = 0;
backpointers[i][j] = 0;
}
} /* populates S array */
/*sanity check*/
S[0, 0] = euclidian(X, Y, 0, 0);
opt1 = [-1, 0];
opt2 = [0, -1];
opt3 = [-1, -1];
backpaths.push(opt1);
backpaths.push(opt2);
backpaths.push(opt3);
/*backpaths populated*/
for (i = 0; i < M; i++) {
for (j = 0; j < N; j++) {
options = [];
if (i != 0 || j != 0) {
if (i > 0) {
options[0] = S[i - 1, j];
}
if (j > 0) {
options[1] = S[i - 1, j];
}
if (i > 0 && j > 0) {
options[2] = S[i - 1, j];
}
idx = Math.min(options);
backpointers[i][j] = idx;
S[i][j] = Math.max(options[idx], euclidian(X, Y, i, j));
}
}
}
console.log(S);
paths = [
[M - 1, N - 1]
];
path = [
[],
[]
];
path.push(paths);
//Create "path"
i = M - 1;
j = N - 1;
count = 0;
while ((path[path.length - 1][0] != 0) || (path[0][path[1].length - 1] != 0)) {
back[0][1] = backpaths[backpointers[i], [j]];
i += back[0];
j += back[1];
path.push([i, j]);
if (count > 1000) {
console.log("too many loops");
break;
}
count += 1;
}
path.push([0, 0]);
path.reverse();
//returns bottleneck and the path
}
As I am testing, I am running into a problem with an infinite while loop (hence the break statement) any help or suggestions would be greatly appreciated! The goal is to append indicies into the path element, such that I can then take those path indicies and the bottleneck and use them to plot with d3.
JS guys/gals! I had the impression that when using BFS in 2D arrays in JavaScript, we can directly mark "visited" on array elements like this: grid[i][j].visited = true, and then next time when we check grid[i][j].visited, it will return true. Here's a piece of sample code that works this way (feel free to run it):
var findP = function(origin, grid) {
var q = [origin], count = 0;
grid[origin[0]][origin[1]].visited = true;
var arr = [[0, -1], [0, 1], [-1, 0], [1, 0]];
while(q.length > 0) {
var c = q.length;
count++;
while(c >= 0) {
var t = q.shift();
if (grid[t[0]][t[1]] === '#') {
return count;
}
for(var i = 0; i < arr.length; i++) {
var m = t[0] + arr[i][0];
if (m < 0 || m > grid.length - 1) {
continue;
}
var n = t[1] + arr[i][1];
if (n < 0 || n > grid[0].length - 1) {
continue;
}
if (grid[m][n] !== 'X' && !grid[m][n].visited) {
grid[m][n].visited = true;
q.push([m, n]);
}
}
c--;
}
}
return -1;
}
console.log(findP([1, 1],[['X','X','X','X','X'], ['X','*','X','O','X'],
['X','O','O','#','#'],['X','X','X','X','X']]))
The above code works fine. However, when I tried this, it doesn't work at all (infinite loop alert. won't be fun runnig it):
var shortestPath = function(arr) {
if (!arr || arr.length === 0) {
return -1;
}
var i, j, hasBen = false;
for (i = 0; i < arr.length; i++) {
for (j = 0; j < arr[i].length; j++) {
if (arr[i][j] === '*') {
hasBen = true;
break;
}
}
if (hasBen) {
break;
}
}
//(i, j) is where Ben is:
var steps = 0, helper = [[1, 0], [-1, 0], [0, 1], [0, -1]];
var q = [[i, j]], flag = false;
arr[i][j].visited = true;
console.log(arr[i][j].visited); // undefined
console.log(arr[0][0].visited); //undefined
while(q.length > 0) {
var counter = q.length;
steps++;
while(counter > 0) {
var temp = q.shift(); // temp = [i, j];
for (var x = 0; x < helper.length; x++) {
var t = helper[x];
var m = temp[0] + t[0];
var n = temp[1] + t[1];
if (m < 0 || m >= arr[0].length || n < 0 || n >= arr.length) {
continue;
}
if (!arr[m][n].visited) {
arr[m][n].visited = true;
if (arr[m][n] === '#') {
flag = true;
break;
}
if (arr[m][n] !== 'X') {
q.push([m, n]);
}
}
}
if (flag) {
break;
}
counter--;
}
}
return flag ? steps : -1;
}
shortestPath([['*', 'O', 'O', 'X'], ['X', 'X', 'O', 'X'], ['X', 'X', '#', 'X']]);
The two console.log() in the above code both logs undefined, which leads to infinite loop. However, why the first code snippet works yet the second one doesn't? Aren't they the same when attaching .visited on array elements? I am so confused.
I'm trying to write a shellsort on Node.js like on the book Algorithms, 4th ed. Sedgewick, Wayne. There all the examples written on Java.
Here is my module:
"use strict";
module.exports = (function() {
function sort(array) {
let size = array.length;
let h = 1;
while(h < size/3) {
h = h * 3 + 1;
}
while(h >= 1) {
for(let i = h; i < size; i++) {
for(let j = i; j >= h && less(array, j, j-h); j = j-h) {
exch(array, j, j-h);
}
}
h = h/3;
}
}
function less(array, i, min) {
return array[i] < array[min];
}
function exch(array, i, min) {
let temp = array[i];
array[i] = array[min];
array[min] = temp;
}
return {
sort: sort
};
})();
I use mocha and chai for testing with this function:
function isSorted(array) {
for(let i = 1, size = array.length; i < size; i++) {
if (array[i] < array[i-1]) {
return false;
}
}
return true;
}
and shell sort not working: mocha test screenshot
Your h may become a floating point number if you use h = h / 3. Try h = Math.floor(h / 3); instead.
Implementation of shell sort algorithm in Javascript
function shellSort(arr){
var len = arr.length;
var gapSize = Math.floor(len/2);
while(gapSize > 0){
for(var i = gapSize; i < len; i++) {
var temp = arr[i];
var j = i;
while(j >= gapSize && arr[j - gapSize] > temp) {
arr[j] = arr[j - gapSize];
j -= gapSize;
}
arr[j] = temp;
}
gapSize = Math.floor(gapSize/2);
}
return arr;
}
function isSorted(array) {
for(let i = 1, size = array.length; i < size; i++) {
if (array[i] < array[i-1]) {
return false;
}
}
return true;
}
var randomArray = [45,86,3,5,97,95,4,24,7,88,93,27,45,90,54,89,74,5,90,73,74,857,834,8394,4231,485,32,54,674,12];
var mySortedArray = shellSort(randomArray);
console.log(mySortedArray);
console.log(isSorted(mySortedArray));
Output:
[3, 4, 5, 5, 7, 12, 24, 27, 32, 45, 45, 54, 54, 73, 74, 74, 86, 88, 89, 90, 90, 93, 95, 97, 485, 674, 834, 857, 4231, 8394]
true
I am trying to implement heapsort in Javascript, but there is a undefined element at array.length - 2 and the element at index 0 is unsorted.
Here is the code:
var heapSort = function(array) {
var swap = function(array, firstIndex, secondIndex) {
var temp = array[firstIndex];
array[firstIndex] = array[secondIndex];
array[secondIndex] = temp;
};
var maxHeap = function(array, i) {
var l = 2 * i;
var r = l + 1;
var largest;
if (l <= array.heapSize && array[l] > array[i]) {
largest = l;
} else {
largest = i;
}
if (r <= array.heapSize && array[r] > array[largest]) {
largest = r;
}
if (largest != i) {
swap(array, i, largest);
maxHeap(array, largest);
}
};
var buildHeap = function(array) {
array.heapSize = array.length;
for (var i = Math.floor(array.length / 2); i >= 1; i--) {
maxHeap(array, i);
}
};
buildHeap(array);
for (var i = array.length; i >= 2; i--) {
swap(array, 1, i);
array.heapSize--;
maxHeap(array, 1);
}
};
var a = [55, 67, 10, 34, 25, 523, 1, -2];
heapSort(a);
document.getElementById("getHeapSort").innerHTML = a;
* {
font-family: Arial, sans-serif;
}
<p id="getHeapSort"></p>
I figured that array[i] == undefined when i = array.length. I tried fixing this (setting i = array.length - 1), but the array came out in an entirely different order. I also figured that 0 was never swapped because i is always greater than 0. Again, I tried, and the array came out in a entirely different order.
You were using 1-based indexing instead of 0-based indexing in JavaScript. I also added a trace for your convenience.
Try this:
var heapSort = function(array) {
var swap = function(array, firstIndex, secondIndex) {
var temp = array[firstIndex];
array[firstIndex] = array[secondIndex];
array[secondIndex] = temp;
};
var maxHeap = function(array, i) {
var l = 2 * i;
var r = l + 1;
var largest;
if (l < array.heapSize && array[l] > array[i]) {
largest = l;
} else {
largest = i;
}
if (r < array.heapSize && array[r] > array[largest]) {
largest = r;
}
if (largest != i) {
swap(array, i, largest);
maxHeap(array, largest);
}
};
var buildHeap = function(array) {
array.heapSize = array.length;
for (var i = Math.floor(array.length / 2); i >= 0; i--) {
maxHeap(array, i);
}
};
buildHeap(array);
for (var i = array.length-1; i >= 1; i--) {
swap(array, 0, i);
array.heapSize--;
maxHeap(array, 0);
document.getElementById("getHeapSort").innerHTML = document.getElementById("getHeapSort").innerHTML + a + "<br>";
}
};
var a = [55, 67, 10, 34, 25, 523, 1, -2];
document.getElementById("getHeapSort").innerHTML = a + "<br>";
heapSort(a);
Here is a JFiddle: http://jsfiddle.net/mbL5enL5/1/
Please let me know if there is a faster, more elegant way to get this result:
I have an array of numbers, and once set a value i should get smallest and highest number to the right and left to my value.
For example if I have: [1,2,3,4,6,7,8,9] and a value is 5,
my numbers will be:1, 4,6,9
if value is 4
my numbers will be 1,4,4,9
My horrible code is:
var arr = [1, 8, 2, 3, 9, 5, 4, 6, 7];
var result1 = [];
var result2 = [];
var goal = 5;
for (a = 0; a < arr.length; a++) {
if (arr[a] < goal) {
result1.push(arr[a])
} else if (arr[a] === goal) {
result1.push(arr[a]);
result2.push(arr[a]);
} else {
result2.push(arr[a]);
}
};
var count1 = result1[0];
for (x = 0; x < result1.length; x++) {
if (result1[x] < count1) {
count1 = result1[x]
}
};
var count11 = result1[0];
for (xx = 0; xx < result1.length; xx++) {
if (result1[xx] > count11) {
count11 = result1[xx]
}
};
var count2 = result2[0];
for (y = 0; y < result2.length; y++) {
if (result2[y] > count2) {
count2 = result2[y]
}
};
var count22 = result2[0];
for (yy = 0; yy < result2.length; yy++) {
if (result2[yy] < count22) {
count22 = result2[yy]
}
};
console.log(count1 + ' ' + count11 + ' ' + count22 + ' ' + count2)
You can simplify your code a lot by using a few mighty methods: Array::filter and Math.min/max:
var arr = [1, 8, 2, 3, 9, 5, 4, 6, 7];
var goal = 5;
var result1 = arr.filter(function(x) { return x <= goal });
var result2 = arr.filter(function(x) { return x >= goal });
var count1 = Math.min.apply(Math, result1);
var count11 = Math.max.apply(Math, result1);
var count2 = Math.min.apply(Math, result2);
var count22 = Math.max.apply(Math, result2);
Assuming the array is sorted always,
var array = [1, 2, 3, 4, 6, 7, 8, 9],
number = 5,
pivot, small, large;
for (var i = 0, len = array.length; i < len; i += 1) {
if (array[i] >= number) {
pivot = i;
break;
}
}
if (pivot > 0) {
small = [array[0], array[pivot - 1]];
large = [array[pivot], array[len - 1]];
console.log(small, large);
} else {
console.log("Not possible");
}
Well I came up with the following solution. Considering that array is always sorted
function GetVals(arr, pivot){
return arr.reduce(function(t,v,i,arr){
if (v < pivot) {
if (typeof t.LMin == "undefined" || t.LMin > v)
t.LMin = v;
if (typeof t.LMax == "undefined" || t.LMax < v)
t.LMax = v;
} else if (v > pivot) {
if (typeof t.RMin == "undefined" || t.RMin > v)
t.RMin = v;
if (typeof t.RMax == "undefined" || t.RMax < v)
t.RMax = v;
}
return t;
}, {});
}
The returned result will have 4 properties, LMin LMax for left min and max and RMin RMax for right min maxes respectively.
if LMin and LMax are equal, this means there is only 1 value from the left (the same rule for the right)
if LMin and LMax are undefined, this means that there are no values from the left less than pivot.
EDIT
Although I realize the question has been answered and another response selected, I at least wanted to update my code to a tested version. FWIW, it works, and does not rely on nor assume a sorted array.
function minmax(valueArray, targetValue) {
var i = 0;
var minBelow;
var maxBelow;
var minAbove;
var maxAbove;
while (i < valueArray.length) {
var currentValue = valueArray[i];
if (currentValue < targetValue) {
if (currentValue < minBelow || !minBelow) {
minBelow = currentValue;
}
if (currentValue > maxBelow || !maxBelow) {
maxBelow = currentValue;
}
}
if (currentValue > targetValue) {
if (currentValue < minAbove || !minAbove) {
minAbove = currentValue;
}
if (currentValue > maxAbove || !maxAbove) {
maxAbove = currentValue;
}
}
i++;
}
return {
minBelow: minBelow,
maxBelow: maxBelow,
minAbove: minAbove,
maxAbove: maxAbove
};
}
function test() {
alert('In test');
var foo = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
var bar = minmax(foo, 5);
alert(bar.minBelow + ","+ bar.maxBelow + "," + bar.minAbove + "," + bar.maxAbove);
}