Find in how many pieces where matrix sliced with recursion - c#

I recently got an assigment , where I have 4 on 5 matrix with 0 and 1(zero's represent the cut parts of the matrix). I need to find a way to calculate in how many pieces matrix will be sliced and as I mentioned zero's represent the cut parts of the matrix so if from one border to another goes straight line of zero's it means the matrix was sliced on that line , as for example(in this pic I've marked where matrix would be split, a line of zero's slice it) :
So guys I know that you won't entirely solve this code for me and I don't need that, but what I need is to understand this :
Firstly how should I tell a compiler in wich direction(when he is going threw matrix ) he should be going, I have an idea with enumarations.
Secondly , what kind of condition sentence I should use that the compiler would recognise the line of zero's(if there is such) ?
Any help would be appreciated :)

You did not specify any requirements for the algorithm (such as time and space complexity), so I guess one answer, that correlates to some specific solutions, would be:
Go in all 4 directions
Don't condition on 0s to create the line, but try to look at the 1s and find to which piece they belong.
A general algorithm for this can be implemented as follows:
Create a helper matrix of the same size, a function to give you a new symbol (for example by increasing some number any time a symbol is asked for), and a data structure to store collisions
Go in all 4 directions starting from anywhere
Whenever you find a 0 in the original matrix, issue some new symbol to each of the new directions you are going from there
Whenever you find 1, try to store the values in the helper matrix. If there is already a value there, then:
Store in the collisions data structure that you found a collision between 2 symbols
Don't continue in any direction from this one.
This will traverse each cell at most 4 time, so time complexity is O(n), and when you are done you will have a data structure with all the collisions.
Now all you need to do is combine all entries in the other data structure to collect how many unique pieces you really have.

Related

How to go about implementing a fast shortest path search for a 1-crate sokoban?

In one of my university courses (in Data-structures and Algorithmics), we are given a bonus assignment based on the game Sokoban:
With one Major exception: We only have one crate to push to our goal.
Example input
8 8
MMMMMMMM
M.....?M
M....TTM
M....TTM
M..!...M
M....+.M
M......M
MMMMMMMM
Here the first line gives the dimensions (b x h) of the board (8 by 8 in this case). This is followed up by h lines oh b characters. The meaning of these characters is as follows: . A walkable space, ? the goal (red point in the gif), ! the crate, and + is our position.
We are asked to output the shortest solution to the puzzle. (Note that a puzzle might be unsolveable.) We output this in 2 lines, the first tells us how many moves, and the second tells us the correct path. For the example, this would be:
Example Output
10
WWNNNWNEEE
Now, finding an algorithm that works isn't really an issue. Seeing as we're looking for the shortest path, and the nodes on this specific graph are in essence unweighted, I've implemented a breadth first search. In broad strokes, my current implementation looks like this:
0. Since the maze doesn't change, describe each state as a whole number based on the coordinates
of the crate and the player. - This defines a state uniquely and reduces memory costs.
1. Create a dictionary of visited states.
2. Get the input positions of the goal, crate and player.
3. Set up a Queue of move sequences.
4. Pop a move sequence from the Queue.
5. If this move sequence wins the game, go to step 8.
6. Make new move sequences which are copies of the original, each with a different legal move appended.
7. Append these new move sequences to the Queue.
8. Go to step 4
9. Print the output.
This is, of course a relatively simple algorithm. The problem is that it isn't fast enough. In one of the final test cases, we're thrown a 196 x 22 maze like "level" which has a solution that takes 2300 steps. We're asked to solve this level within 10 seconds, but it takes my algorithm more than 10 minutes.
Because of that, I'm kinda at a loss. I've already managed to increase the algorithm's speed 10 fold, and I still have 2 orders of magnitude to go...
Hence why I'm asking here: What makes this algorithm so slow, and how can I speed it up?
Yes, your comprehensive BFS search will be slow. You spend a large amount of your tree search in moves that are utterly wasted, your player thrashing around the maze area to no avail.
Change the focus of your goal: first, solve the maze for the crate rather than sending the player every which way. Include a heuristic for moving the crate closer to the goal spot. Make sure that the crate moves are possible: that there is a "push from " spot available for each move.
One initial heuristic is to make a maze fill by raw distance to the goal start at either the goal (what I've done here) and increment the steps through the maze, or start at the box and increment from there.
MMMMMMMM
M54321?M
M6543TTM
M7654TTM
M876567M <== crate is on the farther 6
M987678M <== player is on the nearer 7
Ma98789M
MMMMMMMM
Here, you would first try to find legal pushes to move the box along the path 654321?. You can also update this by making a penalty (moving the player without pushing) for any direction change.
These heuristics will give you a very good upper bound for a solution; you can then retrace decision points to try other paths, always keeping your "shortest solution" for any position.
Also keep track of where you've been, so that you don't waste time in position loops: never repeat a move (position and direction).
Does that help you get going?
Instead of using a pure dfs search of the player's movements, consider only the crate moves available to you at the time. For instance, in the very first frame of your gif, at the beginning of the simulation, the only crate move possible is the top one to the right one square.
An analogy would be for a game of chess on the first move, you would not consider any queen or bishop moves since they are all blocked by pawns.
After you've successfully found the sequence of crate moves leading to the solution, come back and trace the player moves necessary to construct the sequence of crate moves.
This improves time complexity because the time complexity will be based on the number of crates present in the map instead of total squares.

Algorithm to find the shortest path in a matrix

I tried to find an algorithm for the following problem, but I couldn't.
you have a matrix, 10X6 if it matters. (10 on x dimension 6 on y dimension).
the algorithm receives 2 point, the opening point and the target point.
the array is full of 0's and 1's and it should find the shortest path of 1's between them, and return the first point in this path (the next point in the way to the target).
But here's the catch:
each point can get the value only of the following points:
the point above it.
the point underneath it.
the point left to it.
the point right to it.
and to make things even harder: for every point, the value of other point may be different. for example:
the opening point is 0,0. the value of 0,1 is 1;
the opening point is 0,2. the value of 0,1 is 0.
I can calculate the value so it shouldn't matter for you...
So I thought the only way to solve it is with recursion because of the last condition but if you find another way, you're welcome.
The solution should be in LUA, C# or JAVA.
You can simply interpret your matrix as a graph. Every cell (i,j) corresponds to a node v(i,j) and two nodes are connected if an only if their corresponding cells are neighbors and both are set to 1.
The example matrix below has the four vertices v(0,0), v(0,1), v(1,0), and v(1,1), with edges {v(0,0),v(0,1)} and {v(0,1),v(1,1)} (the vertex v(1,0) is isolated).
1 1
0 1
As your graph is unweighted, you can simply use a breadth-first search (BFS) to find a shortest path. For pseudocode see: http://en.wikipedia.org/wiki/Breadth-first_search#Pseudocode
Your restriction that every entry in a matrix only knows its neighboring entries does not matter. When talking about graphs, this means that ever vertex knows its neighbors, which is exactly what you need in the BFS. Using a different graph when searching from different starting points does not make the problem harder either.
Just two comments to the poseudocode linked above:
It only checks whether there is a connection or not. If you actually want to have the shortest path, you need to change the following. When a new vertex u is added to the queue when seen from its neighbor t, you have to store a link at u pointing to t. When you finally found your target, following back the links gives you the shortest path.
Using a set to store which elements are already visited is inefficient. In your case, just use a boolean matrix of the same size as your input matrix to mark vertices visited.

Generating 3x3x3 "block" big structure randomly

I am in progress of making my first 3D game, but I stuck into one part. I have never been good with algortihms or even math, so I am kinda having hard time with this :(
Anyways, I want to generate 3x3x3 ( of course if algorithm would on any size it would be great ! ) "structure" or whatever it should be called. 1 unit is one block/cube. I don't want it to be full of blocks, but generate shapes randomly, so that some parts would have block and some would be empty. All the blocks should be connected to atleast one other block ( not diagonally, but "straight" ).
I hope that you understand what I am after :)
I quickly made a small picture with paint if it helps at all. However I would like it to be a lot emptier and it'd be great if upper part would be more frequently emptier than lower part.
Why don't you just create a few structures and then use random numbers to determine one of those. If you make like 7 different ones the users/players will hardly notice any form of repetition.
Btw: There shouldn't be so many different structures matching your criteria if you ignore all structures that are rotational symmetric.
As an extension to #FlyOn's comment, I would suggest you think about the problem as a system of rules. Write/diagram out the rules. Ask yourself questions like this:
When generating an adjacent position, what are the valid 3-space movements to get to that position?
(Each coordinate block in your solid has 6 face-adjacent coordinate blocks, 8 point-adjacent coordinate blocks and 12 edge-adjacent coordinate blocks. 6+8+12+1=27=3^3)
How can you restrict your random generation to, itself, only generate face-adjacent coordinates so that you don't have to apply that rule after the random?
If you are at position (0, 0, 0), and the random adjacent block chosen is (0, 0, -1), what are the tests that are required to determine if that is valid?
Write up the logic and write some unit-test-style methods that call the logic methods with tests. See if they work as you expect as you test them with different inputs.
Logic puzzles in 3-space are terribly entertaining :).
An example algorithm you could implement:
- pick a random position in the 3x3x3
- pick a random direction out of the possible straight options (remove options that would take you outside the cube, )
- go to that position (so set it to '1' in your 3x3x3 array or something like that)
- start over
optional:
* also remove options where you've already been
* first generate a random number for the amount of spots you want filled, then stop the algorithm once you have that many.
* allow all directions, and simply enter the 'other side' of the cube (this may cause parts to be not connected to other parts)

Find object pattern in array in C#

I'm looking for an efficient way to find a object pattern in an array.
Here is the problem that I have to tackle. I'm writing a tangible interface application that collects data from the webcam, converts it in to a black and white image from which I create an array. The array that is created looks similar to this:
1111111111111111111111111111
1111110001111111111000111111
1111100000111111110000011111
1111100000111111110000011111
1111110001111111111000111111
1111111111111111111111111111
Where the zeros represent the color black in the image. I have about 32 (4 rows with 8 circles in each) circles and I need to find an efficient way to find their coordinates. I don't need the whole shape, just a set of coordinates for each circle.
Thank you for the help.
Regards,
Teodor Stoyanov
Three options that I can see immediately (Tuple is used to represent the coordinates in your matrix):
You could use a BitArray for
each point in the matrix, the bit is set if the coordinate has an O, cost would be
O(row length x column length) for storage. Retrieval is O(1) if you know the coordinates you want to check otherwise, O(n) if you just want to find all O's
You could use a List<Tuple<int,int>>
to only store the coordinates for
each O in the matrix, cost would be
O(m) for storage, m being the number of O's. Retrieval is also O(m)
Alternatively to option 2 you could
use a Dictionary<Tuple<int, int>,
bool>, which allows O(1) retrieval
time if you know the coordinates you
want to check.
Pick an arbitrary 0 and do a flood fill from it. Average the coordinates of all the 0s you find to get the center of the circle. Erase the 0s you flooded and repeat.
There really isn't an easy way to do this, but the best thing you can do is tinker around with Artificial Neural Networks. They allow you to feed in data and get an output over many different data inputs. If you build the network right, it'll self-adjust its weights over many iterations.
Sorry, but I doubt you're going to get the exact solution spelled out for you in code. Although I haven't used any of these libraries or resources, a quick glance over them makes them look pretty decent:
http://franck.fleurey.free.fr/NeuralNetwork/
http://sourceforge.net/projects/neurondotnet/

Metric to compare how similar two 2D linear lines are

Is there an algorithm ( preferably in C# implementation) that allows me to compare how similar two lines are? In my case I have one reference line, and I have a lot of secondary lines, I need to choose, out of so many secondary lines, which is the closest to the reference line.
Edit: It is a 2D line, with start and stop points. When you compare the similarities, you to take into account of the full blown line. The direction of the line ( i.e., whether it's from left to right or vice versa) is not important. And yes, it has to do with how close it is from one another
I know this is kind of subjective ( the similarity, not the question), but still, I am sure there are people who have done work on this.
Obvious metrics include slope, length, and distance between midpoints. You could calculate those and then find weightings that you like.
If you want to kind of wrap them all up into one thing, try the sum of the distances between the endpoints.
You're going to have to try a few things and see which cases irritate you and then figure out why.
lines (and in general hyperplanes) sit on an object call Grassmanian; e.g. lines in the plane sit in Gr(1,3), which is isomorphic to the 2-dimensional projective space, and yours is the simplest non trivial one: Gr(2,4). It is a compact metric space, which comes with a standard metric (arising from the plucker embedding - see the link above). However, this metric is a little expensive to compute, so you may want to consider an approximation (just as you'd consider using dot product instead of angle in 2 dimensions - it works find for small angles)
A more detailed explantion (based in the metric defined in the linked wikipedia article):
For each line l take two points (x1,y1,z1) and (x2,y2,z2) on it. Let A be the 4 by 2 matrix whose columns are (1,x1,y1,z1)^t and (1,x2,y2,z2)^t. Define P to be the 4 by 4 matrix
A(A^tA)^(-1)A^t. Then P is dependent only on l and not of the choice of the two points.
The metric you want is the absolute value of the top eigen value of the difference between the matrices corresponding to the two lines.
If you are talking about lines in the graphical sense, then I would look at a combination of things like line length and angle.
Depending on your situation, you may be able to make optimizations such as using the square of the length (saves a square root) and dy/dx for angle (saves a trig function, but watch for the divide-by-zero case).

Categories