Given 2 positions (x1,y1) and (x2,y2) print the sum of all elements within the area of rectangle in O(1) time - arrays

A 2D matrix is given to you. Now user will give 2 positions (x1,y1) and (x2,y2),
which is basically the upper left and lower right coordinate of a rectangle formed within the matrix.
You have to print sum of all the elements within the area of rectangle in O(1) running time.
Now you can do any pre computation with the matrix.
But when it is done you should answer all your queries in constant time.
Example : consider this 2D matrix
1 3 5 1 8
8 3 5 3 7
6 3 9 6 0
Now consider 2 points given by user (0, 2) and (2, 4).
Your solution should print: 44.
i.e., the enclosed area is
5 1 8
5 3 7
9 6 0

Since your question seems to be related to homeworks, i am just posting a clue... It is a formula that may inspire you :
What does this sum of terms represent ?
Rewrite your problem using mathematical tools, indexes like i and j ...

maybe this can also help:
courtosy of: http://www.techiedelight.com/calculate-sum-elements-sub-matrix-constant-time/

Related

How do I generate a 2D Array with values, each with neighbours of different, non-repeating values?

I have a square 2D Array, which I wish to fill with values between 1 to 4.
For this to be correct, the neighbours of any of the values inside the array would need to look like this, as an example:
x 2 x
3 1 1
x 4 x
The x values are irrelevant to the middle value 1. As we can see, the neighbours of middle value 1 do not appear more than once, aside from itself
An incorrect value's neighbours would look like this:
x 2 x
3 1 2
x 4 x
One of the neighbours of middle value 1 appear more than once (the value of 2 appears twice), and we don't want this.
I have made a LUA solution for this problem, but it is very slow, as all it does is add 2 rules to the generation and runs through all combinations until it finds a valid one.
The rules being:
Corner neighbours (in our case the xs) cannot have the same value as the middle value
The next value OVER the relevant neighbours cannot have the same value as the middle value.
Explanation for rule 2:
y y y y
y 1 y x
y y y y
The x in this instance cannot have the value of 1, this applies for every vertical and horizontal direction (up-down-left-right)
EDIT: I now know I can just repeat a tileable pattern, but this is not what I wanted, as I do not want a clear repetition to be observable
You can simply repeat a pattern to get the desired array.
Row 1: 1 2 3 4 1 2 3... repeated for the required number of columns
Row 2: 3 4 1 2 3 4 1... repeated similarly
Row 3: Same as row 2
Row 4: Same as row 1
Row 5: Start repeating pattern from row 1
...continued for the required number of rows.
Here's an example for a 6x6 grid:
1 2 3 4 1 2
3 4 1 2 3 4
3 4 1 2 3 4
1 2 3 4 1 2
1 2 3 4 1 2
3 4 1 2 3 4
This is guaranteed to follow both rules, since:
The diagonal for a value of x here will always be 5 - x, and x != (5 - x) for x in [1,2,3,4].
The next over value for 1 will always be 3 and vice versa (in any direction), and same for 2 and 4.
Edit: In your comment, you've mentioned that you needed the array to be more "varied". Any form of randomness would mean that we can't use any patterns. In that case, your current solution can not be improved, since you can't use any pattern for optimisation.
You can use a Block that if repeated any number of times in any direction does not Break the neigbour-constraint. One such Block (I'm sure there are others, but this is the most trivial I think) would be:
1 1 2 2
3 3 4 4
2 2 1 1
4 4 3 3
You can repeat this Block any number of times in any direction and every cell will always have unique neighbors.
For example, if you need a 6x8-array just repeat the Block once to the right and down, and then slice according to the size you want:
1 1 2 2 1 1
3 3 4 4 3 3
2 2 1 1 2 2
4 4 3 3 4 4
1 1 2 2 1 1
3 3 4 4 3 3
2 2 1 1 2 2
4 4 3 3 4 4
Fun Fact: On further inspection one might recognize, that Abhinav Mathur and I came up with a somewhat similar solution. If you rotate my Block and swap the 2 with the 3, the pattern is the same. But his formulation with repeating rows instead of the whole block is probably easier to implement in most cases.
I write this as a second answer as there is a new requirement: Don't use any repeating pattern!
TLDR
Just fill the array row for row, left to right. With following constraint:
You want to fill the value x, then you only have to consider the values in the colored cells.
If the green cell is filled, then there is only one possibility for x (the one value that is not in either the green or red cells)
If the green cell is empty (you are at the left border). Then there are two options (one of the values that is not in the red cells). But the value that you choose has to be one of the values in the blue cells too (this is always possible) or otherwise it will be impossible to fill the value y later! If the blue cells aren't filled (right border) you can just ignore this secondary constraint.
Explanation
You can separate this into two independent problems. Think of your array like a chessboard and solve the numbers in the light and dark fields separately as they don't care about each other (light and dark don't share any neighbors because their neighbors are always of the opposite color respectively).
So you split your chessboard in light and dark (just to better understand, you don't have to actually separate the arrays).
Then you solve them separately with some simple constraints. The value (green) is not allowed to be equal to one of the values two cells apart (red):
Just fill the values row by row from left to right. You can only actually choose a value at the left border as the rest will be constrained by the other three values above. At this left border you have to be careful. The chosen value in the green cell has to be the same as one of the values in the blue cells. Otherwise the next cell (red) will be impossible!
Just do this for the light and dark cells and then put them back together:
This should be relatively easy to implement and really fast, as it is not brute-forcing anything but directly constructing a valid solution. When saying choose a number or fill values I mean to just get the possible values and choose one at random.
You can try yourself in excel too, it's like a really boring sudoku as there is actually not much to choose, it is really constrained :).

2D array minimum sum of Y elements and just two rows that we can chose to get minimum

With given 2d array[X][Y], i have to find the smallest possible sum of Y elements but:
the sum must be created by using just 2 rows,
each value must be from different index
Example:
for array
7 3 7 9
2 20 10 6
8 8 8 8
Result should be 18, as we get 3 + 7 from 1st row and 2 + 6 from 2nd.
I've been thinking about few hours but i can't figure out how to deal with it.
Try this one here.
Method 1 (Naive Approach): Check every possible submatrix in given 2D
array. This solution requires 4 nested loops and time complexity of
this solution would be O(n^4).
Method 2 (Efficient Approach): Kadane’s algorithm for 1D array can be
used to reduce the time complexity to O(n^3).

Algorithm to distribute set of numbers in 2D array without neighboring themselves

i want algorithm to distribute a set of numbers like (0,1...15) in big 2D array with known dimensions without letting the number neighboring itself as example :
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7
3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10
6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 10 11 12 13
if you look to any number you will never see it neighboring itself in any direction ?
I will describe an algorithm for doing what you want that hopefully will fulfill your needs.
First take the original array of numbers, and split it however you want into 4 arrays of approximately equal size (In your example, this could look like (0,1,2,3),(4,5,6,7),(8,9,10,11),(12,13,14,15) if that makes sense). Label these sub-arrays arr1, arr2, arr3, arr4, respectively.
Now, to fill the array, fill the rows as follows: If the row is of an even index (zero-th, second, fourth, etc.), then fill the first element in the row with a radnom number from arr1, otherwise if the row is of an odd index, fill the row with a number from the second arr3. Then, fill the next element of the array with an random number from the arr following the previous one. For example, if the first element of the row was a number from arr1, then the next element in the row would be an element of arr2, and the following from arr3, and then arr4, and then back to arr1, etc. And that's it.
Why it works: In case you're wondering why it works, first consider the 2d array as a graph. Including diagonals, the 2d array becomes a graph with chromatic number 4, meaning that it takes 4 unique elements to color the graph. These colors are basically what arr1, ..., arr4 are, so when filling in the graph with numbers from the arr's we are effectively "coloring" the graph.
To see how the graph is colored, consider a 4x4 array. It can be four colored as such:
[[ 1 , 2 , 3 , 4 ],
[ 3 , 4 , 1 , 2 ],
[ 1 , 2 , 3 , 4 ],
[ 3 , 4 , 1 , 2 ]]
Note that this is analagous to what the algorithm above does, but instead of the number 1-4, it gets numbers from the arrays, arr1, ... , arr4. It is also relatively clear to see that the 4-coloring holds for any m x n array, proving the validity of our algorithm (This is not a particularly rigorous proof, but hopefully you get the idea).
There are some things to note. First, you need an initial array of length at least 4 otherwise as if you don't, you will have less than 4 "colors" to work with, and it is easy to see that you cannot color this graph with only 3 colors. Additionally, this algorithm could certainly be improved to, let's say, appear "more random" as right now, while the numbers are distributed equally, they will appear not be very random, as a number from arr1 for example will only be able to be found in certain places in the final array. However, this algorithm does distribute the numbers roughly equally (best if arr1, arr2, arr3, arr4 are all the same size) and does what the question asks, so I believe it is valid.
For more reading about graph coloring, I would recommend reading the Wikipedia page (more math intensive), or this cool problem that is related (4 color map theorem, perhaps you're familiar with it?).
Hope this answer helps, leave a comment question if you have any.

HeIp understanding Fibonacci Search

On the internet I only find code for the algorithm but I need understand in form of text first because I have trouble understand things from code only. And other description of the algorithm are very complicated for me (on Wikipedia and other sites).
Here is what I understand for far:
Let say we want search in array the element 10:
Index i 0 1 2 3 4
2 3 4 10 40
Some fibonacci number here:
Index j 0 1 2 3 4 5 6 7 8 9
0 1 1 2 3 5 8 13 21 34
First thing we do is find fibonacci number that is greater-equal to array length. Array length is 4 so we need take fibonacci number 5 that is in index position j=5.
But where we divide the array now and how continue? I really don't understand it.. Please help understand for exam...
The algorithm goes in the following way:
The length of the array is 5, so the fibonacci number which is greater than or equal to 5 is 5. The two numbers which are preceding in the Fibonacci sequence are 2 [n-2] and 3 [n-1] - (2, 3, 5).
So, arr[n-2] i.e. arr[2] is compared with the number to be searched which is 10.
If the element is smaller than the number, then the sequence is shifted 1 time to the left. Also, the previous index is saved for next iteration to give an offset for the index. In this case, since 4 is smaller, n-2 becomes 1 (1, 2, 3). arr[1 + 2(prev)] = arr[3] = 10. So, the index of the number is 3.
If the element is larger, the sequence is shifted 2 times to the left.
Always the min(n-2+offset,n)th element is compared with number to get the matching result.

I don't understand the required (matlab)

I'm in the beginning of matlab course and trying to do some home work; for the next problem I don't understand what's required. any help?
Write a function called bottom_left that takes two inputs: a matrix N and a scalar n, in that order, where each dimension of N is greater than or equal to n. The function returns the n-by-n square array at the bottom left corner of N.
This is quite simple even for me.
You have a matrix: [1 2 3 4;5 6 7 8;9 10 11 12;13 14 15 16]
and you have a scalar: 2
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
"The function returns the n-by-n square array at the bottom left corner of N"
N=2
therefore
the output is the 2 x 2 array in the bottom left corner:
9 10
13 14
thats it. The additional info "where each dimension of N is greater than or equal to n" is just to confuse a bit what to do since the input matrix is given and does not needs to be created. Now, being this a homework you can find out how to get such array for any given matrix.
What you need to do first is to test if one of the dimensions of your Matrix N (I'm going to assume it's not a square Matrix) is lower than the scalar n. If both of the dimensions are higher then n, then we need to simply put the left lower block of the Matrix N into the variable out. The last operation is done by Matrix Indexing, which for more information you can visit this Link
function [ out ] = bottom_left( N, n )
[m,b]=size(N); % m is number of rows, b is number of columns
if (min(m,b)>=n) % to test if one of the dimensions is lower then the scalar n
out=N((m-n+1):m,1:n); % extracting the lower left n-by-n bloc from the Matrix by Indexing
end
end

Resources