Filling 2D array with blocks - arrays

I am looking for ideas of how to write an algorithm that is going to populate 2d array with predefined set of blocks/arrays.
Let's say you have 2d array 5x5 (so 25 fields), and have 6 elements you want to randomly fit into it (accordingly 5, 5, 4, 4, 4, 3 piece straight blocks). What is important - I want to put those randomly either horizontally or vertically, but no cell can be left with nothing.
The end effect should look like this (given the blocks of X elements on the left side)
This is somewhat related to packaging algorithms, although here the idea is that I specify the container dimensions (2d array) let's say 8x4, and randomize X amount of stripes length 3-5 that will be fit into array. The sum of all lengths of stripes will be equal to array size (so no cell is left empty).
On top of that, I think, I could add a fail-safe feature, meaning that after putting most stripes into Array and last one cant fit, algorithm could find any empty cells and fill it with neighbouring element so that the stripes are longer, but not longer than 5 elements

Related

How to compare two elements in two different array with different length?

//example no instersection
60
40,41
65,75,85
33,43,53,63
//Here is an intersection (marked it)
[68]
08,18
28,38,48
65,66,67,[68]
these are ships coordinates, 4 different length 2d arrays and i should check if there are intersection between the elements.
So technically i am making a Battleship game in c# console and i must prevent the ships to intersect.
That means if i would check if there is a same number thats not good because it can be in a column or a row. I have no idea how should I check if at Row coordinates is there an intersection and for column coordinates too.

Add Random Number to List only if it's different than others

I'm designing a game in Scratch. The game is suppose to have a Spaceship travel through space, avoiding asteroids. These asteroids start at a fixed X position on the right side of the screen and go to the left, horizontally until they hit a fixed X position and they'll disappear. The asteroids will start in groups between 2-6 (it's a random number generated), and each set is about 1 second apart.
Assuming the game throws out up to 6 asteroids at once, I want to make sure each asteroid is distant from the next. I tried using two variables and comparing the distance, but this did not work. I can put the group of asteroids Y spawning position into a list. So say for instance in my list, I have:
0, 100, 5, 30, -20
As you can see, there are two items in that list that are close together. What I'm trying to do, is prevent this, so the third item would be something else, like -50, for instance, and then if a six item is generated, ensure it's also distant.
Can someone pseudocode how to achieve something like this? It doesn't matter what programming language it's in, I can probably translate the general idea into Scratch.
There is a way to do this without a trial-and-error loop.
Instead of picking random positions, pick random distances, then scale them to fit the screen.
Roughly, the approach is as follows.
The lists below represent the distances between neighboring asteroids (ordered by Y coordinate), as well as distances between the outermost asteroids and the edges of the screen.
For example, if a group contains 6 asteroids, then you need lists of 7 elements each.
Create a list L1 of minimal distances. Obviously, these are all fixed values.
Create a list L2 of random numbers. Take them from some arbitrary, fixed range with a positive lower bound, e.g. [1..100].
Calculate the total 'slack' = height of screen minus sum(L1).
Calculate a multiplication factor = slack divided by sum(L2).
Multiply every element of L2 with the multiplication factor.
Add every value from L1 to the value in L2 at the same index.
L2 now contains a list of distances that:
obey the minimal distances specified in L1
together equal the height of the screen
The final step is to position every asteroid relative to its neightbor, based on the distances in L2.
Note: if step 3 gives a negative number, then obviously there is not enough room on screen for all asteroids. What's worse, a naive 'trial-and-error' algorithm would then result in an infinite loop. The solution is of course to fix your parameters; you cannot fit 6 asteroids in 360 pixels with a minimal distance of 100.
To do this, you need to do through each previous entry in the array, compare that value to the new value, and if any element is too close change the value. This process needs to repeat until a suitable number is found. If this number is less then some minimum distance, then a variable tooClose is set to yes and the value will be reset. At the begining of the loop tooClose is set to yes so that at least one random number will be generated. Then, at the beginning of the loop, the value is randomized, and tooClose is set to no, then, I loop through all the previous entries with the value i, comparing each element and setting tooClose to yes if it is too close. The comparison between numbers is done with a subtraction, followed by an absolute value, which will ensure the result is positive, giving the difference between the two numbers as a positive value.
Here is a screenshot of the code:
And here is the project:
https://scratch.mit.edu/projects/408196031/

Extract multiple parts of a matrix without using loops

I have a huge 3D matrix and there is a loop. In every iteration, I would like to extract some different parts (for example: 10000) out of it, then the convolution between those part and a patch is calculated.
I know it could easily be done using a loop but it is very time consuming.
Is there any alternative solution to work much faster than loop?
Let's suppose you have :
1) A row vector idx containing the row indexes of the top left corners of your parts.
2) A row vector idy containing the column indexes of the top left corners of your parts.
3) A row vector idz containing the indexes along the 3rd coordinate of the left corners of your parts.
We'll first have to create, from idx, idy and idz 3 vector containing ALL the indexes of the elements you need to extract from your matrix. Then we'll split the extracted matrix in blocks the same size of your patch using mat2cell, and then we'll apply the convn function to each block using cellfun.
Totidx=bsxfun(#plus,idx,[0:(size(patch,1)-1)]'); \\i-th column of this is the column vector idx(i):(idx(i)+size(patch,1)-1)
Totidx=reshape(Totidx,1,numel(Totidx)); \\ Creates the vector needed containing all indexes along first dimension.
Doing the same for idy and idz, we obtain 3 vectors Totidx, Totidy, Totidz containing all indexes needed.
Now we can extract the values from your initial matrix, say A :
ExtractedA=A(Totidx,Totidy,Totidz);
Apply mat2cell : NPatch denotes your number of extracted patches
B=mat2cell(ExtractedA,size(patch,1)*ones(1,NPatch),size(patch,2)*ones(1,NPatch),size(patch,3)*ones(1,NPatch));
Then you can apply your convn function to every cell of the cell array B : patch denotes the patch you want to convolute your extracted parts with
fun=#(M) convn(M,patch,'valid');
out=cellfun(fun,B,'uniformoutput',false);
Every cell of the cell array out is now one of the output you wanted

Find the largest rectangle with no repeated elements

Find the max size of rectangular contiguous submatrix of unique (i.e. non repeated within a given submatrix) element.
How can I solve this?
You should set a maximum value to 0. Iterate the rows of the matrix and if they are not repeating (whatever that means), compare its size to the maximum. If it is bigger, then store the new maximum value and use that for further iterations. In case you found a new maximum, store whatever you need to store. So, the algorithm looks like this:
maximum <- 0
for all rows as row
if (row is not repeating) then
if (row rectangle size > maximum) then
maximum <- new maximum
store whatever you need to store
end if
end if
end for
Note, that if you do not have further information, then it is pointless to do a binary search, since you will have to check the size of each rectangle. If you have further knowledge about your rectangles, then the algorithm might be optimized.
A first idea (recursion): Maybe identify pairs in the whole array, this will identify constraints to respect. If there is a value v at both positions x0,y0 and x1,y1 then you cannot have a rectangle containing these positions, so this will let you construct some possible rectangles from these values and recurse on them?
Another one (dynamic programming): start with elementary arrays (size 1x1) and try to merge them respecting the constraint?

Choosing 6 different cells from a 50 cell array by using rand(start,end) only 6 times

I was trying to think of an algorithm which chooses 6 random cells from an array with 50 cells, such that the probability for each cell to be picked is equal.
I need to find a solution that uses the function Random(start,end) no more than 6 times.
I can't use any extra data structure, and it is important that the probability for each cell to be picked will be equal and independent.
Call Random(0,49). Read the resulting cell, then shuffle everything after it in the array down one place so that you have a 49-cell array with the picked value missing.
Call Random(0,48) and repeat 6 times.
Put the cells in a list, shuffle it, take six of 'em

Resources