I have a problem making this task: An n-vertex graph is a scorpion if it has a vertex 1(the sting) connected to a vertex two (the tail) connected a vertex 3 (the body) connected to the other vertexes (the feet). Some of the feet may be connected to other feet. Design an algorithm that decides whether a given drawing represents a scorpion and tell in which line is sting,tail , body and feets.
This is my data file to read from:
(+) is where is edge and (-) where are no edges
I'm trying to find the sting first but how basically i could search for connections with tail and body? also i have to use recursion
EDIT:
Ok now i habe found how much "+" there are in each line:
int[] B = new int[100];
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
int HowMuch = Regex.Matches(A[i,j], #"\+").Count;
Saving[i] += HowMuch;
}
if(Saving[i]>=3)
{
Console.WriteLine("It's a scorpion!");
Console.WriteLine("The body is in: " + i + " part");
}
}
And with recursion i'm trying to find path connections... How i should continue?
static void Find(string[,] A, int n, int j)
{
for (int i = 0; i < n; i++)
{
if(A[i,j]=="+")
{
j = i;
Find(A, n, j);
}
}
}
So, I'm giving you an idea on how to solve this. I took help from this. You should take a look there. There is a hint on that site.
My approach is slightly different from theirs.
From abstract point of view, you are asking, from an adjacency matrix, determine whether the given points are like this image(aka the scorpion). (taken from that site)
Now, how the adjacency matrix convert to scorpion? Let's look at your example.
I drawn the adjacency matrix and the graph by hand. I hope its not too difficult to understand.
Now how to solve it? You compute the degree for each node here. You can compute it from the adjacency matrix here. (The degree means the number of nodes one node is connected to, For example, for the graph i drawn there, the degree of 1 is 1, degree of 0 is 2 and so on...)
At first you find degree of all the nodes here(nodes means vertex and vice versa).
So, the sting should be the one with degree one. Now there is a problem with this, i'll get back to it. But for now lets not consider it.
The tail would be with degree 2. And it would be connected with the sting. So, you find the one node connected with sting and you are done. That is the tail.
The node that is connected with tail(apart from sting) is the body.
The body would be with degree >= 2. So if there is a vertex with that much degree, then that's the body for sure. And the nodes connected with it are the feets.
Now you may say, the feets are with degree 2 so why are not tail? Because they are not connected to sting.(which you have computed earlier)
You may also say, the feets are with degree 1 so why not sting? because its connected to some node that has degree > 2, which cannot be(as the tail has degree of 2)
Now thats all well and good, but consider a problem, If the graph is like this,
1-0-3-4
then what would be the sting and the what would be the feet? My answer is both. Both 1 and 4 can be leg or sting.
I hope you understand what i have said.
Clarification on the image if needed:
You said, where there is a + there is an edge. Notice the + on 1 and 3 on row 0. So, 0 is connected to 1 and 4. I've connected them just like that. And the connections are bidirectional. You can see that from adjacency matrix.
Related
I am having trouble with an assignment about finding the shortest total path in a grid, while visiting all the correct tiles in the correct order.
We are supposed to emulate manually inputting a word, like when using a controller to write something, and find the least amount of commands (up, down, left, right) needed to do so.
Our input is the grid, parameters, and the word we are supposed to work with.
I store them like this (with example inputs):
Height = 2;
Width = 2;
Content = "ABCC";
Word = "ABC";
grid = new char[Height, Width];
Contents = Content.ToCharArray();
Words = Word.ToCharArray();
int ch = 0;
for (int i = 0; i < Height; i++)
{
for (int j = 0; j < Width; j++)
{
if (ch < Contents.Length)
{
grid[i, j] = Contents[ch];
ch++;
}
}
}
The actual way I compute the shortest path is like so:
public void GridSearch( int a, int FirstX, int FirstY, int PathLength)
{
int NewPath;
int NewX;
int NewY;
int SecondX = 0;
int SecondY = 0;
for (int i = 0; i < Height; i++)
{
for (int j = 0; j < Width; j++)
{
if (grid[i, j] == Words[a])
{
SecondX = i;
SecondY = j;
NewPath = PathLength;
NewPath += Math.Abs(FirstX - SecondX);
NewPath += Math.Abs(FirstY - SecondY);
NewX = SecondX;
NewY = SecondY;
if (a < Words.Length-1)
{
GridSearch(a+1, NewX, NewY, NewPath);
}
else
{
if (FinalPath > NewPath ^ FinalPath == -1)
{
FinalPath = NewPath;
}
}
}
}
}
We are also supposed to "click" when on the correct tile, so I am adding the length of "Words" to the total of commands.
In this case, the shortest path between the letters would be 2 (right, down) and the length is 3, so 5 is the correct answer.
This is also what my program gets, however when I try to send it in, the automated checker says it only passes 1 out of 5 tests, which is an improvement over the 0 that I had until recently, but still not actually good.
Sadly it does not say which inputs it used to make my program fail, and after a day of trying things I am out of ideas on how to fix it, could anyone please point out the, no doubt, obvious mistake I am making and help me fix this program?
EDIT: The assignment instructions as written (since a commenter asked for them):
Some devices allow text entry using a grid of letters. The grid
contains a movable cursor, which begins in the upper-left-hand corner.
Arrow keys move the cursor up, down, left and right and Enter key
chooses the letter under cursor.
For example, if the input grid looks like this:
ABCDEFGH
IJKLMNOP
QRSTUVWX
YZ
we can enter the text "HELLO" with the following sequence of keys
(which is only one of many possible sequences):
right
right
right
right
right
right
right
Enter
left
left
left
Enter
down
left
Enter
Enter
right
right
right
Enter
Write a program that for a given grid (which may contain both
lowercase and uppercase letters) and text (which may also contain
non-alphabetic characters) determines and writes out the minimum
number of keystrokes required to enter the given text.
Caution: Each letter may appear more than once in the grid!
The input begins with numbers indicating the width and height of the
grid (each on its own line).
A single line follows containing the contents of the entire grid (in
row-major order, i.e. with one row after another).
The rest of the lines contain the text to be entered. ! You should
ignore any characters in the text that are not present in the grid.
Example:
Input:
3
3
ABCBFECDF
ABCDEFA
Output:
15
In this example, the grid has the form
ABC
BFE
CDF
It is possible to enter the text ABCDEFA in many possible ways; 15
keystrokes is the length of the shortest of these.
Revising my previous answer, it is likely that you have not counted the "enter" keystroke. I.e. you should add one to the candidate path length for each letter:
...
NewY = SecondY;
**NewPath++;**
if (a < Words.Length - 1)
...
This gives a correct length of 15 keypresses on your example set of "ABCBFECDF" / "ABCDEFA".
Note that this type of code greatly benefits from a type that represents a pair of x/y coordinate, like a Point or Vector2i, so you don't have to repeat a bunch of calculations for both x and y coordinates. I would also recommend following common coding conventions like
declare local variables in the smallest possible scope, not at the top of the method
Use "camelCasing" for local variables
Prefer pure methods whenever possible, i.e.
I would still recommend reading up on Djikstra or A*, since these should be more generally applicable and be more efficient.
I've been trying to come up with an algorithm which deals, as the title states,
X amount of Cards, per Y amount of Cards, over Z amount of Players of a normal (52 piece) Deck of Cards which is sorted or unsorted. I've been walking into a wall for the past few hours to come up with a working solution, while also Googling to find similar problems. Unfortunately without success, hence this question.
An example would be: dealing 2 Cards, per 1, over 2 Players would result in
Player 1 receiving 1 card
Player 2 receiving 1 card
Player 1 receiving 1 card
Player 2 receiving 1 card
Until now I have a solution with which I'm able to run my application, although the actual dealing algorithm isn't keeping the 'per' parameter into account. It will deal the right amount of cards to the Y amount of players, although each player will receive the total amount to be dealed in 1 go..
I was wondering if anyone here had to handle a similar problem in the past? Or could guide me into the right direction? :/
public List<Card>[] Deel(int per, int players, int cards)
{
_currentCard= 0;
List<Card>[] output = new List<Card>[players];
if (_cardsDistributed < _deck.Count)
{
for (int i = 0; i < players; i++)
{
List<Card> hand = new List<Card>();
for (int j = 0; j < cards; j++)
{
_currentCard= 0;
hand.Add(_deck[_currentCard]);
_deck.Remove(_deck[_currentCard]);
_cardsDistributed++;
}
output[i] = hand;
}
return output;
}
else
return null;
}
One way to think about this is to get a deck of cards and do it yourself, by hand, and write down the steps. For example, you have three players and you want to deal each player four cards, two at a time. So what do you do?
You take the deck in hand, hold it over the first player's pile, and deal two cards. The code for that is pretty simple:
player = 1
for i = 1 to 2
deal next card to player
Then you move to the second player's pile and deal two cards, and you do the same thing for the third player. So you need a loop to go through the players:
for player = 1 to 3
for i = 1 to 2
deal next card to player
At this point you've dealt two cards to each of the three players.
If you want to deal X cards Y at a time, and Y is smaller than X, then you need to go around to each player multiple times. How many? Well, how many times does Y go into X? The answer is X/Y.
If you were doing this by hand, you would start over at player 1, deal him two cards, move on to player 2, etc. Adding that in code is simple:
numRounds = 4/2
for round = 1 to numRounds
for player = 1 to 3
for card = 1 to 2
deal next card to player
Now, replace the constant values with X, Y, and Z, and try it with some other combination by following those exact steps. Deal six cards to each player, three at a time. Did it work? Try a few other combinations to verify that the steps you wrote down always work.
Once you've determined that the algorithm you've developed works, then writing the code to implement it on the computer is easy. There are, of course, some minor details like how to deal a card, but those are easy compared to figuring out the overall approach to the problem.
I was fortunate that I discovered this approach to problem solving early in my education. Casting an algorithmic problem into physical terms lets me build a model that I can play with, and write down the steps I took to solve the problem. After that, writing the program is a simple matter of duplicating those steps in code. It doesn't work for all problems, but it's very effective for a large number of different problems that you will encounter.
If I understood your question correctly you need something like this:
public List<Card>[] Deel(int per, int players, int cards)
{
List<Card>[] output = new List<Card>[players];
// init hand for each player
for (int i = 0; i < players; i++)
{
output[i] = new List<Card>();
}
// assume the number of cards is divided by 'per' without a remainder
// otherwise you need one more round to deal rest (cards % per) cards
int rounds = cards / per;
for (int round = 0; round < rounds; round++)
{
for (int i = 0; i < players; i++)
{
for (int j = 0; j < per; j++)
{
if (_deck.Count > 0)
{
output[i].Add(_deck[0]);
_deck.Remove(_deck[0]);
_cardsDistributed++;
}
else
{
// should throw an exception because the deck contains no more cards
// or maybe you need to check it before dealing
}
}
}
}
return output;
}
I am using quad-tree structure for my data processing application in c#, it is similar to hashlife algorithm. Getting data N x N (eg. 2000 x 2000) dimension data from quad-tree is very very slow.
how can i optimize it for extracting large data from quad tree.
Edit:
Here is the code i used to extract the data in recursive manner
public int Getvalue(long x, long y)
{
if (level == 0)
{
return value;
}
long offset = 1 << (level - 2);
if (x < 0)
{
if (y < 0)
{
return NW.Getvalue(x + offset, y + offset);
}
else
{
return SW.Getvalue(x + offset, y - offset);
}
}
else
{
if (y < 0)
{
return NE.Getvalue(x - offset, y + offset);
}
else
{
return SE.Getvalue(x - offset, y - offset);
}
}
}
outer code
int limit = 500;
List<int> ExData = new List<int>();
for (int row = -limit; row < limit; row++)
{
for (int col = -limit; col < limit; col++)
{
ExData.Add(Root.Getvalue(row, col));
//sometimes two dimension array
}
}
A quadtree or any other structure isn't going to help if you're going to visit every element (i.e. level 0 leaf node). Whatever code gets the value in a given cell, an exhaustive tour will visit 4,000,000 points. Your way does arithmetic over and over again as it goes down the tree at each visit.
So for element (-limit,-limit) the code visits every tier and then returns. For the next element it visits every tier and then returns and so on. That is very labourious.
It will speed up if you make the process of adding to the list itself recursively visiting each quadrant once.
NB: I'm not a C# programmer so please correct any errors here:
public void AppendValues(List<int> ExData) {
if(level==0){
ExData.Add(value);
} else{
NW.AppendValues(ExData);
NE.AppendValues(ExData);
SW.AppendValues(ExData);
SE.AppendValues(ExData);
}
}
That will append all the values though not in the raster-scan (row-by-row) order of the original code!
A further speed up can be achieved if you are dealing with sparse data. So if in many cases nodes are empty or even 'solid' (all zero or one value) you could set the nodes to null and then use zero or the solid value.
That trick works well in Hashlife for Conway Life but depends on your application. Interesting patterns have large areas of 'dead' cells that will always propagate to dead and rarely need considering in detail.
I'm not sure what 25-40% means as 'duplicates'. If they aren't some fixed value or are scattered across the tree large 'solid' regions are likely to be rare and that trick may not help here.
Also, if you actually need to only get the values in some region (e.g. rectangle) you need to be a bit cleverer about how you work out which sub-region of each quadrant you need using offset but it will still be far more efficient than 'brute' force tour of every element. Make sure the code realises when the region of interest is entirely outside the node in hand and return quickly.
All this said if creating a list of all the values in the quad-tree is a common activity in your application, a quad-tree may not be the answer you need. A map simply mapping (row,col) to value is pre-made and again very efficient if there is some common default value (e.g. zero).
It may help to create an iterator object rather than add millions of items to a list; particularly if the list is transient and destroyed soon after.
More information about the actual application is required to understand if a quadtree is the answer here. The information provided so far suggests it isn't.
I have a quick question that I haven't found out how to do efficiently (in C#).
I have a list array of Points (X,Y). I need to find which 3 points are the tightest cluster. It's for a mapping project.
What would the best way to do this be? There's only about 6 to 9 items in the list.
Thanks in advance.
Cheers!
For such small numbers, the brute force method should work just fine. With six points, there are 20 possible combinations of three points. With 9 points, there are 84 possible combinations. I wouldn't recommend this approach for a lot of points, but with just a handful, it's going to be plenty fast enough and it's dead simple to write.
You can easily generate the combinations:
for (int i = 0; i < points.Length - 2; ++i)
{
for (j = i + 1; j < points.Length - 1; j++)
{
for (k = j + 1; k < points.Length; k++)
{
// Here, your three points are
// points[i], points[j], and points[k]
// compute "tightness" and store
}
}
}
You'll need a structure to hold your combinations:
struct PointGroup
{
public readonly int i;
public readonly int j;
public readonly int k;
public readonly double tightness;
public PointGroup(int i, int j, int k, double tight)
{
this.i = i;
this.j = j;
this.k = k;
this.tightness = tight;
}
}
If you create one of those structures for each group and store them in an array, you can simply sort the array and take the best three.
Your bigger problem is coming up with a definition of "tight group." Also, you have to decide if a point can be in more than one of those "tightest" groups. Three possible ways to define tightness are:
The sum of the distances between the points is minimized.
The average distance from each point to the center of the group is minimized.
The circumference of the triangle formed by the three points is minimized.
Undoubtedly there are more.
If the points are not identical, this becomes a form of cluster analysis.
There are various algorithms that differ in how they measure and "cluster" points, though with only a few points, a brute force approach might be the easiest... You could just measure the distance between each pair of points, and sort...
You can simplify the problem as follows:
Don't check a Point against itself; distance is zero.
Exploit symmetry: distance from Point i to Point j is the same as Point j to Point i
Those eliminate a number of combinations.
But, given those, you have to calculate the distance between each pair and sort.
I have a System.Windows.Shapes.Polygon object, whose layout is determined completely by a series of points. I need to determine if this polygon is self-intersecting, i.e., if any of the sides of the polygon intersect any of the other sides at a point which is not a vertex.
Is there an easy/fast way to compute this?
Easy, slow, low memory footprint: compare each segment against all others and check for intersections. Complexity O(n2).
Slightly faster, medium memory footprint (modified version of above): store edges in spatial "buckets", then perform above algorithm on per-bucket basis. Complexity O(n2 / m) for m buckets (assuming uniform distribution).
Fast & high memory footprint: use a spatial hash function to split edges into buckets. Check for collisions. Complexity O(n).
Fast & low memory footprint: use a sweep-line algorithm, such as the one described here (or here). Complexity O(n log n)
The last is my favorite as it has good speed - memory balance, especially the Bentley-Ottmann algorithm. Implementation isn't too complicated either.
Check if any pair of non-contiguous line segments intersects.
For the sake of completeness i add another algorithm to this discussion.
Assuming the reader knows about axis aligned bounding boxes(Google it if not) It can be very efficient to quickly find pairs of edges that have theirs AABB's clashing using the "Sweep and Prune Algorithm". (google it). Intersection routines are then called on these pairs.
The advantage here is that you may even intersect a non straight edge(circles and splines) and the approach is more general albeit almost similarly efficient.
I am a new bee here and this question is old enough. However, here is my Java code for determining if any pair of sides of a polygon defined by an ordered set of points crossover. You can remove the print statements used for debugging. I have also not included the code for returning the first point of crossover found. I am using the Line2D class from the standard java library.
/**
* Checks if any two sides of a polygon cross-over.
* If so, returns that Point.
*
* The polygon is determined by the ordered sequence
* of Points P
*
* If not returns null
*
* #param V vertices of the Polygon
*
* #return
*/
public static Point verify(Point[] V)
{
if (V == null)
{
return null;
}
int len = V.length;
/*
* No cross-over if len < 4
*/
if (len < 4)
{
return null;
}
System.out.printf("\nChecking %d Sided Polygon\n\n", len);
for (int i = 0; i < len-1; i++)
{
for (int j = i+2; j < len; j++)
{
/*
* Eliminate combinations already checked
* or not valid
*/
if ((i == 0) && ( j == (len-1)))
{
continue;
}
System.out.printf("\nChecking if Side %3d cuts Side %3d: ", i, j);
boolean cut = Line2D.linesIntersect(
V[i].X,
V[i].Y,
V[i+1].X,
V[i+1].Y,
V[j].X,
V[j].Y,
V[(j+1) % len].X,
V[(j+1) % len].Y);
if (cut)
{
System.out.printf("\nSide %3d CUTS Side %3d. Returning\n", i, j);
return ( ... some point or the point of intersection....)
}
else
{
System.out.printf("NO\n");
}
}
}
return null;
}