How itis possible we have a coherent matrix with the code below? - javascript

The author says: The array stores its content in a single array of width × height elements. The elements are stored row by row, so, for example, the third element in the fifth row is (using zero-based indexing) stored at position 4 × width + 2.
the problem is how it is possible to have a coherent array if say the width is 5 when the index will never reach no 2 because of the equation in the square brackets;
let content = [];
function element(x,y){return undefined;}
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
content[y * width + x] = element(x, y);
}
}

Hi I am not sure I understood correctly your question but I try to explain to you the code you have wrote.
As you have wroten, the code represents 2D matrix as one dimensional array. So if we want to create a 3 x 2 matrix, which would look like this (logicaly)
undefinded0, undefinded1
undefinded2, undefinded3
undefinded4, undefinded5
(i put a number to make think easier)
if we use your function the representation would look like this
[undefined0, undefined1, undefined2, undefined3, undefined4, undefined5]
the problem is how it is possible to have a coherent array if say the width is 5 when the index will never reach no 2 because of the equation in the square brackets
Yep thats true, the array has only one dimension, which means there will be only one element that stays at index 2.
I think you may have confuse the one line representation with some sort bidimensional representation. Here let me do an example. If you have the matrix like this
[
[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5],
[0, 1, 2, 3, 4, 5]
]
Each row (even the fifth row) will have an element with index 2, this is the representation above has two dimensions.

Related

Get 1D item with 2D coordinates with 1D array beginning at bottom left of 2D array

How do I get a 1D item which starts at the bottom left of a 2D array after providing 2D coordinates?
var width = 3; // the 2D array width
var height = 3; // the 2D array height
var arr = [0, 1, 2, 3, 4, 5, 6, 7, 8]; // 1D array
console.log(getIndex(0,2));
console.log(getIndex(1,2));
console.log(getIndex(2,2));
console.log(getIndex(0,1));
console.log(getIndex(1,1));
console.log(getIndex(2,1));
console.log(getIndex(0,0));
console.log(getIndex(1,0));
console.log(getIndex(2,0));
//Desired output: 0 1 2 3 4 5 6 7 8
function getIndex(x, y) {
return ... ; // how????????
}
To illustrate, here's the 2D array of the 1D array in the code above:
X
0---2
0 6 7 8
Y | 3 4 5
2 0 1 2
*The numbers in the 2D array represent the position within the 1D index.
To provide needed access (with reverse row order), you can use such formula:
indx = (height - 1 - y) * width + x

Equally distribute array of numbers into x subsets of numbers

I have a large array of numbers that I need to distribute into x ranges of numbers, such that each range contains an equal number of elements from the original array.
For example, when x = 4 , the following array
[1, 1, 2.5, 3, 6, 7, 10, 11.2, 14, 25, 35, 50, 75, 85.5, 100, 120, 128.9, 150, 200, 260]
would produce an array of length x + 1 with the following
[1, 6.5, 30, 110, 260]
1 is the lowest value in the array
6.5 is the midpoint of 6 and 7
30 is the midpoint of 25 and 35
110 is the midpoint of 100 and 120
260 is the highest value
Essentially, this will give me 4 ranges of numbers 1-6.5, 6.5-30, 30-110, and 110-260. Each range would contain 5 numbers of the original array.
Needs to be able to handle a dynamic number of elements that will not necessarily be divided evenly by x.
I asked this question on Mathematics but was told it was more of a programming question.
Based on your question , the following javascript code should satisfy your requirements, I've tested its correctness with a few values of x, but you might want to check if this code applies to all possible test cases for your problem.
var arr = [1, 1, 2.5, 3, 6, 7, 10, 11.2, 14, 25, 35, 50, 75, 85.5, 100, 120, 128.9, 150, 200, 260, 261, 262, 263, 264, 265];
total_elem = arr.length;
var x = 5;
var each_set_elem = total_elem / x;
var i = 1;
var temp = [];
temp.push(arr[0]);
for (i = each_set_elem; i < total_elem; i += each_set_elem) {
this_elem = (arr[i] + arr[i - 1]) / 2;
temp.push(this_elem);
}
temp.push(arr[total_elem - 1]);
console.log(temp);
This code satisfies the test case in the question as well as for x=5 it spits out the correct 6 points so that the 5 ranges each have 4 elements from the given array set.

Calculate Power and Logarithmic Regression

I need to calculate Logarithmic, Power Regression points(Trend line) for my array [X, Y] values below here using java script. Example:
X: [1, 2, 3, 4, 5, 6]
Y: [10, 40, 35, 50, 55, 65]
I referred more sites. But they are only given formula and its description. There is no example how to calculate X,Y values using that equation. Any one please help me on how to calculate Logarithmic, Power Regression.
Thanks,
Bharathi

Advanced Sorting Algorithm

I'm writing an app in Javascript that uses Google maps and calculates a full route between a series of legs based off closest legs.
Say I've got 4 legs on the map, each leg has a start and end Latitude and Longitude. The user specifies which two legs are the start and end of the route. Each end of a leg can only connect to another legs start. Then the end of that leg connects to another legs start, and so on. The code determines which legs start to connect to based off the closest leg it can find.
Something like this for example (the dashed lines are the legs):
start-----------end <-connector-> start----------end <-connector-> start----------end
I've got an array of all of the leg coordinates, and I want to sort this array so that it follows the proper progression of connections. Then I can utilize the array to generate the connectors by linearly looping through it.
The array looks something like this:
[
{start_lat: X, start_lng: X, end_lat: X, end_lng: X},
{start_lat: X, start_lng: X, end_lat: X, end_lng: X},
]
Those will be the inner legs. And then I'll have the outer legs (the two legs that are the start and the end of the entire route) stored in variables:
var start = {end_lat: X, end_lng: X}
var end = {start_lat: X, start_lng: X}
As an example it might end up something like:
start -> array[0] -> array[1] -> end
Or it might end up like:
start -> array[1] -> array[0] -> end
The algorithm needs to sort the array based off the start legs end_lat,end_lng and the end legs end_lat,end_lng.
The end result will be a big route connected together with the shortest path.
I'm struggling to think of a way of writing the sorting algorithm that takes these unique factors into consideration.
It's difficult to put this into words, and I'm not really sure how I can help make it clearer, but I'll edit this post if I can think of anything useful to add. Thanks.
Edit:
Here's a picture of what I'm talking about:
The black lines are the legs, the red lines are the connectors I will need to generate after I've sorted the array of leg coordinates into the correct order. The generating the connectors isn't part of this algorithm, but it's just an example of what I'm trying to accomplish so you can understand the big picture. As you can see there are gaps between the legs, none of the coordinates overlap.
You could do something like this:
DEMO
var start = { end_lat: 1, end_lng: 1 },
end = { start_lat: 4, start_lng: 4 },
coordsBetween = [
{ start_lat: 2, start_lng: 2, end_lat: 3, end_lng: 3 },
{ start_lat: 1, start_lng: 1, end_lat: 2, end_lng: 2 },
{ start_lat: 3, start_lng: 3, end_lat: 4, end_lng: 4 }
];
function orderedCoords(start, coords) {
var result = [],
point = start;
while (point = coords.filter(function (item) {
return item.start_lat === point.end_lat
&& item.start_lng === point.end_lng;
})[0]) {
result.push(point);
}
return result;
}
console.log(orderedCoords(start, coordsBetween));
Basically we find the next point that starts where start ends and let that point become the next start until there's no match and at each step we push the point into result.
EDIT:
This would work of the coordinates of the start and end point
overlapped, but none of mine do, there is a large gap between them and
I need to generate the 'connectors' between them...
I have expanded my first idea by using an algorithm to calculate the closest point insead of looking for overlapping coords.
DEMO
var start = { end_lat: 1, end_lng: 1 },
end = { start_lat: 4, start_lng: 4 },
segments = [
{ start_lat: 2, start_lng: 2, end_lat: 3, end_lng: 3 },
{ start_lat: 1, start_lng: 1, end_lat: 2, end_lng: 2 },
{ start_lat: 3, start_lng: 3, end_lat: 4, end_lng: 4 }
];
function orderedSegments(start, segments) {
var result = [],
segment = start,
i;
while ((i = indexOfClosestSegment(segment, segments)) !== -1) {
result.push(segment = segments.splice(i, 1)[0]);
}
return result;
}
function indexOfClosestSegment(segment, segments) {
var i = 0,
len = segments.length,
segIndex = -1,
tempDistance, smallestDistance;
for (; i < len; i++) {
if (
(tempDistance = distanceBetween(segment, segments[i])) < smallestDistance
|| typeof smallestDistance === 'undefined') {
smallestDistance = tempDistance;
segIndex = i;
}
}
return segIndex;
}
function distanceBetween(segmentA, segmentB) {
return Math.sqrt(
Math.pow(segmentB.start_lat - segmentA.end_lat, 2)
+ Math.pow(segmentB.start_lng - segmentA.end_lng, 2)
);
}
console.log(orderedSegments(start, segments));
Notice that the points are geo coordinates and you will need to use a
spherical distance algorithm, not the trivial pythagoras. I think GM
provides such helper functions for their data structures; of course
the algorithm will still work with a different distanceBetween
implementation. – #Bergi
I think DFS is Okay and transfer visited ordered leg list to next recursion.
and in every recursion choose the last leg and recursive with each unvisted legs.

Setting vAxis format in Google Line Chart [duplicate]

This question already has answers here:
Google Charts vertical axis in whole numbers
(4 answers)
Closed 9 years ago.
How to set the vAxis value format in google Line Chart in order to not get multiple lines with same value? Let's say I have lines with values: 1.5 1.0 0.5 and 0, after I set the format to '#', I got 0, 0, 1, 1...
Possible duplicate of this question
Copy-pasted answer:
If you just want numbers to display as whole numbers, then it's
easy:
function drawVisualization() {
// Create and populate the data table.
var data = google.visualization.arrayToDataTable([
['x', 'Cats', 'Blanket 1', 'Blanket 2'],
['A', 1, 1, 0.5],
['B', 2, 0.5, 1],
['C', 4, 1, 0.5],
['D', 8, 0.5, 1],
['E', 7, 1, 0.5],
['F', 7, 0.5, 1],
['G', 8, 1, 0.5],
['H', 4, 0.5, 1],
['I', 2, 1, 0.5],
['J', 3.5, 0.5, 1],
['K', 3, 1, 0.5],
['L', 3.5, 0.5, 1],
['M', 1, 1, 0.5],
['N', 1, 0.5, 1]
]);
// Create and draw the visualization.
new google.visualization.LineChart(document.getElementById('visualization')).
draw(data, {curveType: "function",
width: 500, height: 400,
vAxis: {maxValue: 10, format: '0'}}
);
}
If you go to [google playground][1] you will note that the axis labels
are 0, 2.5, 5, 7.5, 10. By adding the format: '0' to the vAxis, it
will display only whole numbers, so my labels become 0, 3, 5, 8, 10.
But obviously this is not ideal since 8 displays as being halfway
between 5 and 10, which it isn't, because the number is actually 7.5
and just being rounded.
Your ability to change the axis scale/labels is restricted. And to do
what you're asking would take a special bit of javascript to create an
appropriate scale and number of gridlines to prevent breaking things
down in to funky numbers.
Basically, you want to make sure that your maximum and minimum values,
and number of gridlines, allow for easy division such that you will
only get whole numbers. To do that, you need to create some funky new
logic. Here is some sample code that will allow you to get an
appropriate min/max axis value:
// Take the Max/Min of all data values in all graphs
var totalMax = 345;
var totalMin = -123;
// Figure out the largest number (positive or negative)
var biggestNumber = Math.max(Math.abs(totalMax),Math.abs(totalMin));
// Round to an exponent of 10 appropriate for the biggest number
var roundingExp = Math.floor(Math.log(biggestNumber) / Math.LN10);
var roundingDec = Math.pow(10,roundingExp);
// Round your max and min to the nearest exponent of 10
var newMax = Math.ceil(totalMax/roundingDec)*roundingDec;
var newMin = Math.floor(totalMin/roundingDec)*roundingDec;
// Determine the range of your values
var range = newMax - newMin;
// Define the number of gridlines (default 5)
var gridlines = 5;
// Determine an appropriate gap between gridlines
var interval = range / (gridlines - 1);
// Round that interval up to the exponent of 10
var newInterval = Math.ceil(interval/roundingDec)*roundingDec;
// Re-round your max and min to the new interval
var finalMax = Math.ceil(totalMax/newInterval)*newInterval;
var finalMin = Math.floor(totalMin/newInterval)*newInterval;
There are a couple issues here (unfortunately). The first is that I am
using the number of gridlines to determine the min/max values -- you
want to figure out how many gridlines you should have to use nice
whole numbers. The easiest way to do this, I think, would be as
follows (pseudo-code only):
// Take the Max/Min of all data values in all graphs
var totalMax = 3;
var totalMin = -1;
// Figure out the largest number (positive or negative)
var biggestNumber = Math.max(Math.abs(totalMax),Math.abs(totalMin));
// Round to an exponent of 10 appropriate for the biggest number
var roundingExp = Math.floor(Math.log(biggestNumber) / Math.LN10);
var roundingDec = Math.pow(10,roundingExp);
// Round your max and min to the nearest exponent of 10
var newMax = Math.ceil(totalMax/roundingDec)*roundingDec;
var newMin = Math.floor(totalMin/roundingDec)*roundingDec;
// Determine the range of your values
var range = newMax - newMin;
// Calculate the best factor for number of gridlines (2-5 gridlines)
// If the range of numbers divided by 2 or 5 is a whole number, use it
for (var i = 2; i <= 5; ++i) {
if ( Math.round(range/i) = range/i) {
var gridlines = i
}
}
Then you set the gridlines option (vAxis.gridlines) to the above
variable, and your max to newMax, and your min to newMin. That should
give you whole number axis labels.
Note: if your numbers are really small then the above function may not
work. The function is also not tested so please check it against some
examples on your own time and let me know if it doesn't work properly.
[1]:
http://code.google.com/apis/ajax/playground/?type=visualization#line_chart

Categories