2 dimensional array vs simple array - javascript

I'd like to know what would be faster at execution time and which cost less memory than the other solution.
I was doing a sudoku when I asked this question myself. As you know sudoku is a 9 x 9 grid array and generaly all solvers around sudoku are implementing array[9][9]. I presume it's because it looks like the grid you're used to play.
My question is simple, as the grid is always a square (ex: 9x9), what's the fastest and lowest memory consumption between :
- 2Dimensions : Array[9][9]
- Single dimension : Array[81]
Accessing values are in both cases calculated (if Array starts at index 0 and you need the 5th column and 6th row on a 9x9 grid) :
- Couple of coordinates for 2D Array (ex : Array[5-1][6-1])
- single calculated position (Array[((6-1)*9) + (5-1)])
Is there any ways to test this?

As stated in the comments the one array approach is the cheapest (memory wise)
As to speed, timeit is your friend:
import timeit
one_array = timeit.timeit(setup="a = [0]*81;s=3;x=2;y=1;", stmt='a[s*9+y*3+x]')
multi_array = timeit.timeit(setup="a = [[[0]*3]*3]*9;s=3;x=2;y=1;", stmt='a[s][x][y]')
print (one_array)
print (multi_array)
if one_array < multi_array:
print('one_array is faster')
else:
print("multi_array is faster!")
0.21741794539802967
0.13626013606615175
multi_array is faster!
at least in python ...

Related

How can I find all the sum of combinations of elements in an array [duplicate]

I am having issues with understanding dynamic programming solutions to various problems, specifically the coin change problem:
"Given a value N, if we want to make change for N cents, and we have infinite supply of each of S = { S1, S2, .. , Sm} valued coins, how many ways can we make the change? The order of coins doesn’t matter.
For example, for N = 4 and S = {1,2,3}, there are four solutions: {1,1,1,1},{1,1,2},{2,2},{1,3}. So output should be 4. For N = 10 and S = {2, 5, 3, 6}, there are five solutions: {2,2,2,2,2}, {2,2,3,3}, {2,2,6}, {2,3,5} and {5,5}. So the output should be 5."
There is another variation of this problem where the solution is the minimum number of coins to satisfy the amount.
These problems appear very similar, but the solutions are very different.
Number of possible ways to make change: the optimal substructure for this is DP(m,n) = DP(m-1, n) + DP(m, n-Sm) where DP is the number of solutions for all coins up to the mth coin and amount=n.
Minimum amount of coins: the optimal substructure for this is
DP[i] = Min{ DP[i-d1], DP[i-d2],...DP[i-dn] } + 1 where i is the total amount and d1..dn represent each coin denomination.
Why is it that the first one required a 2-D array and the second a 1-D array? Why is the optimal substructure for the number of ways to make change not "DP[i] = DP[i-d1]+DP[i-d2]+...DP[i-dn]" where DP[i] is the number of ways i amount can be obtained by the coins. It sounds logical to me, but it produces an incorrect answer. Why is that second dimension for the coins needed in this problem, but not needed in the minimum amount problem?
LINKS TO PROBLEMS:
http://comproguide.blogspot.com/2013/12/minimum-coin-change-problem.html
http://www.geeksforgeeks.org/dynamic-programming-set-7-coin-change/
Thanks in advance. Every website I go to only explains how the solution works, not why other solutions do not work.
Lets first talk about the number of ways, DP(m,n) = DP(m-1, n) + DP(m, n-Sm). This in indeed correct because either you can use the mth denomination or you can avoid it. Now you say why don't we write it as DP[i] = DP[i-d1]+DP[i-d2]+...DP[i-dn]. Well this will lead to over counting , lets take an example where n=4 m=2 and S={1,3}. Now according to your solution dp[4]=dp[1]+dp[3]. ( Assuming 1 to be a base case dp[1]=1 ) .Now dp[3]=dp[2]+dp[0]. ( Again dp[0]=1 by base case ). Again applying the same dp[2]=dp[1]=1. Thus in total you get answer as 3 when its supposed to be just 2 ( (1,3) and (1,1,1,1) ). Its so because
your second method treats (1,3) and (3,1) as two different solution.Your second method can be applied to case where order matters, which is also a standard problem.
Now to your second question you say that minimum number of denominations can
be found out by DP[i] = Min{ DP[i-d1], DP[i-d2],...DP[i-dn] } + 1. Well this is correct as in finding minimum denominations, order or no order does not matter. Why this is linear / 1-D DP , well although the DP array is 1-D each state depends on at most m states unlike your first solution where array is 2-D but each state depends on at most 2 states. So in both case run time which is ( number of states * number of states each state depends on ) is the same which is O(nm). So both are correct, just your second solution saves memory. So either you can find it by 1-D array method or by 2-D by using the recurrence
dp(n,m)=min(dp(m-1,n),1+dp(m,n-Sm)). (Just use min in your first recurrence)
Hope I cleared the doubts , do post if still something is unclear.
This is a very good explanation of the coin change problem using Dynamic Programming.
The code is as follows:
public static int change(int amount, int[] coins){
int[] combinations = new int[amount + 1];
combinations[0] = 1;
for(int coin : coins){
for(int i = 1; i < combinations.length; i++){
if(i >= coin){
combinations[i] += combinations[i - coin];
//printAmount(combinations);
}
}
//System.out.println();
}
return combinations[amount];
}

Find a specific string in a cdata string using javascript

I've been reading up a bit on using data types in javascript, specifically CData. I have a specific use case with a numeric string I'm running a regex pattern on. It's already fairly performant for what I'm doing, but I'm interested in possibly making it more performant for larger applications.
I am representing multi-dimensional models as a single string of integers (doesn't have to be integers, but that's worked for me so far). I represent empty space with 0, occupied space as 1, and each successive dimensional divide with an integer, beggining with 2 for 2-dimensions.
3 1D:
000
3x3 2D:
00020002000
3x3x3 3D:
00020002000300020002000300020002000
There's a bunch of stuff involved with making the regex pattern, but essentially it looks like this for 2D (this is a super-dumbed-down version for ease):
var gridWidth = //total width of our grid
var columns = //width of our object to place in grid
var rows = //height of our object to place in grid
var grid = 00020002000;
// (0{number of columns})+(([0-2]{difference in width of grid and object})(0{number of columns again)).repeat(number of rows)
var reg = RegExp(("(0{" + columns + "})" + ("([0-2]{" + (gridWidth + 1 - columns) + "})(0{"+columns+"})").repeat(rows-1)) + "");
grid = grid.replace(reg, function(){
//the last 2 argument's aren't part of our grouping
var l = arguments.length - 2;
r = "";
for (var i = 1; i<l; ++i){
if (i%2){
r+= "1".repeat(columns); //repeat prototyped, just repeats string x times
} else {
r+= arguments[i];
}
}
return r;
});
CData integers seem to be somehow more performant than javascript strings from what I'm reading, though I'm not experienced with C or the finer points of higher-level programming. I'm a javascript code monkey - feel free to tell me I'm WAY off base with my train of thought.
So my question is, is it possible to take my grid (which is essentially an integer), turn it into/store it as CData, and run my regex pattern against it somehow in an effort to increase performance processing large numbers of object in a very large grid space?
(side note: I have been able to place 10000 objects of random sizes between 1x1 and 4x4 in a grid using divs in an average of about 14000ms in chrome, so it's performant for basic grid layouts [registers as 0ms sometimes with only a few dozen objects on a small grid.] Handling placing objects more efficiently may inspire greater uses)
"More performant" is all relative to what you're trying to accomplish.
The CData spec you were reading from is a draft. In the meantime, keep it simple - try arrays. The regex seems like a novel idea, but also seems to me that it would be quite difficult to maintain.

How to optimize 2 dimensional matrix reading speed?

I'm working on a 2D game. I have the game map saved on a js object {} called gameMap. My problem is that reading an item on the matrix takes too long. For collision detection I usually have to check 10 or 20 items of the map matrix which takes around 1ms and having 10 characters on screen collision detection becomes the bottleneck of the app, taking 10ms of the 16ms each frame should last. Also when the map gets too big times scale up.
Let's say Map has 1000 x 1000 items. Right now if I want to check what is at position (-100,200) I check gameMap['-100'][200]. My idea is to divide the map in quadrants that would group 100 x 100 items. So to check (-100,200) I would test gameMap[quadrantName][-100][200]. This would mean that while gameMap would be about the same size it would work with a lot less items, and probably read speed would scale up in a far smaller proportion. Does anyone know if this would make reading faster? What else can I do to improve reading speed?
First of all, a 10000x10000 array of bytes will consume 100MB! Do you really need such a large array. Perhaps you'd be better of storing just the coordinates of all your elements...
As to your question - you could convert your 2d array to a 1d array and access all cells via
gameMap[y * 10000 + x]
where 10000 would be the 'width' of your map. So there would be no need to divide the map into quadrants.

Connecting Rooms

I've created a simple algorithm for a game I'm working on that creates a cave like structure. The algorithm outputs a 2 dimensional array of bits that represent the open area's. Example:
000000000000000000000000
010010000000000111100000
011110000000011111111000
011111110000011111111100
011111111001111111111110
011000000000001111000000
000000000000000000000000
(0's represent wall, 1's represent open areas)
The problem is that the algorithm can sometimes create a cave that has 2 non connected sections (as in the above example). I've written a function that gives me an array of arrays that contain all the x, y positions of the open spots for each area
My question is, given a number of lists that contain all of the x,y coordinates for each open area what is the fastest way to "connect" these area's be a corridor that is a minimum of 2 thickness wide.
(I'm writing this in javascript but even just pseudo code will help me out)
I've tried comparing the distances from every point in one area to every other area in another area, finding the two points that have the closest distance then cutting out a path from those 2 two points but this approach is way to slow I'm hoping there is another way.
Given two caves A and B, choose a point x in A and y in B (at random will do, the two closest or locally closest is better). Drill a corridor of thickness 2 between A and B (use Bresenham's algorithm). If you have multiple disconnected caves, do the above for each edge (A,B) of the minimal spanning tree of the graph of all the caves (edge weight is the length of the corridor you'll drill if you choose this edge).
Edit for the edit: to approximate the distance between two caves, you can use hill climbing. It will return the global minimum for convex caves in O(n) rather than the naive O(n2). For non-convex caves, do multiple iterations of hill climbing with initial guess chosen in random.
If you need the exactly minimal solution, you can consider first building the frontiers of your caves and then applying O(nm) algorithm. This will eliminate the need to compare distances between interior points of your caves. Then as soon as you know the distances between each pair of caves, you build the minimal spanning tree, then you drill your tunnels.
Since I don't know too much from your description, here are some hints I would consider:
How do you look for the pair of nearest points? Do you use a naive brute-force approach and thus obtain a run time of O(n*n)? Or are you using a more efficient variant taking O(n log n) time?
If you have obtained the closest points, I'd use a simple line-drawing algorithm.
Another approach might be that you generate a structure that definitely has only one single connected area. Therefore you could do the following: First you take a random cell (x,y) and set it to 1. Then, you traverse all it's neighbours and for each of them you randomly set it to 1 or leave it at 0. For each cell set to 1, you do the same, i.e. you traverse it's neighbours and set them randomly to 1 or 0. This guarantees that you won't have two separate areas.
An algorithm to ensure this could be the following (in python):
def setCell(x,y,A):
if x>=len(A) or y>=len(A[0]) or x<0 or y<0:
return
A[x][y] = 1
def getCell(x,y,A):
if x>=len(A) or y>=len(A[0]) or x<0 or y<0:
return 1
return A[x][y]
def generate(height, width):
A = [[0 for _ in xrange(width)] for _ in xrange(height)]
from random import randint
import Queue
(x,y) = (randint(0, height-1), randint(0, width-1))
setCell (x,y,A)
q = Queue.Queue()
q.put((x,y))
while not q.empty():
(x,y) = q.get()
for (nx, ny) in [(x+1,y), (x-1,y), (x,y+1), (x,y-1)]:
if randint(0,8)<=6:
if getCell(nx,ny,A)==0:
setCell(nx,ny,A)
if randint(0,2)<=1:
q.put((nx,ny))
return A
def printField(A):
for l in A:
for c in l:
print (" " if c==1 else "X"),
print ""
Then printField(generate(20,30)) does the job. Probably you'll have to adjust the parameters for random stuff so it fits your needs.

Find in Multidiamentional Array

I have an multi dimensional array as
[
{"EventDate":"20110421221932","LONGITUDE":"-75.61481666666670","LATITUDE":"38.35916666666670","BothConnectionsDown":false},
{"EventDate":"20110421222228","LONGITUDE":"-75.61456666666670","LATITUDE":"38.35946666666670","BothConnectionsDown":false}
]
Is there any plugin available to search for combination of LONGITUDE,LATITUDE?
Thanks in advance
for (var i in VehCommLost) {
var item = VehCommLost[i];
if (item.LONGITUDE == 1 && item.LATITUDE == 2) {
//gotcha
break;
}
}
this is json string..which programming language u r using with js??
by the way try with parseJSON
Are the latitudes and longitudes completely random? or are they points along a path, so there is some notion of sequence?
If there is some ordering of the points in the array, perhaps a search algorithm could be faster.
For example:
if the inner array is up to 10,000 elements, test item 5000
if that value is too high, focus on 1-4999;
if too low, focus on 5001-10000, else 5000 is the right anwser
repeat until the range shrinks to the vicinity, making a straight loop through the remaining values quick enough.
After sleeping on it, it seems to me most likely that the solution to your problem lies in recasting the problem.
Since it is a requirement of the system that you are able to find a point quickly, I'd suggest that a large array is the wrong data structure to support that requirement. It maybe necessary to have an array, but perhaps there could also be another mechanism to make the search rapid.
As I understand it you are trying to locate points near a known lat-long.
What if, in addition to the array, you had a hash keyed on lat-long, with the value being an array of indexes into the huge array?
Latitude and Longitude can be expressed at different degrees of precision, such as 141.438754 or 141.4
The precision relates to the size of the grid square.
With some knowledge of the business domain, it should be possible to select a reasonably-sized grid such that several points fit inside but not too many to search.
So the hash is keyed on lat-long coords such as '141.4#23.2' with the value being a smaller array of indexes [3456,3478,4579,6344] using the indexes we can easily access the items in the large array.
Suppose we need to find 141.438754#23.2i7643 : we can reduce the precision to '141.4#23.2' and see if there is an array for that grid square.
If not, widen the search to the (3*3-1=) 8 adjacent grids (plus or minus one unit).
If not, widen to the (=5*5-9) 16 grid squares one unit away. And so on...
Depending on how the original data is stored and processed, it may be possible to generate the hash server-side, which would be preferable. If you needed to generate the hash client-side, it might be worth doing if you reused it for many searches, but would be kind of pointless if you used the data only once.
Could you comment on the possibility of recasting the problem in a different way, perhaps along these lines?

Categories

Resources