I've been doing interview prep questions and this is a question that I've had trouble with as I'm unsure how to implement the solution. So here's the setup. You're given an 8x8 grid of letters and a list of words, and you must return the longest word in the list that can be formed by starting at a letter on the grid and then moving about the grid in the way that a knight would in chess. For example, if you had the list ["word", "string", "test"] and the following grid:
Y W E Z T N U W
O P A A C Q G F
T E L Z X C V B
N M M W F R T O
U I O N A S D F
B E J O L Z V C
T B N M Q W E R
T A S G X Z R S
Then you would return "test", because this can be formed by starting at the bottom left corner of the grid for 'T', jumping up two and to the right one to get the 'E', jumping down two and right one to get the 'S', and then left two and up one to get the 'T', and none of the other words can be formed on this grid.
I think you'd use a branch and bound algorithm but I'm totally lost on how to set that up. Could anyone help? I'm trying to implement in python.
Note: letters can be repeated in the grid, i.e. you can jump on the same letter as many times as you want.
My solution is:
for every word in the array, iterate through the matrix to find the first letter then you can use a breath first search (BFS) or a depth first search (DFS) on the first letter's neighbors( in this case it would be the 8 positions a knight can jump to) to see if they match up. you can implement BFS or DFS iteratively using a queue or stack respectively.
Related
I would like to perform the Edmond matching algorithm or Blossom algorithm on a Graph (example Graph in picture), but how to I start with a empty matching set?
The Algorithm work this way:
Given: Graph G and matching M in G
Task: find matching M' with |M'| =
[M| + 1, or |M'| = IM| if M maximum
1 let F be the forest consisting of all M-exposed nodes; 2 while there
is outer node x and edge {x, y) with y \in V(F), add (x, y} and
matching edge covering y to F;
3 if there are adjacent outer nodes x, y in same tree, then shrink
cycle (M-blossom) in F \cup {x, y) and go to Step 2;
4 if there are adjacent outer nodes x, y in different trees, then
augment M along M-augmenting path P(x) \cup {x, y} \cup P(y);
5 in reverse order, undo each shrinking and re-establish near-perfect
matchings in blossoms.
You don’t begin the algorithm with an empty M. You have to provide one, generally by generating it with a greedy algorithm that parses all edges e of the graph G and adds each e to M if M + e form a matching.
I recently faced this problem in an interview:
Given below matrix:
[[ R R R R R R],
[ R B B B R R],
[ B R R R B B],
[ R B R R R R]]
Find out if any group of only R's or only B's surrounded by Opposite colour in the 4 directions: up, down, left, right corners.
ex: Answer for the above matrix -> Valid set of B's surrounded by R's in the second row.
[[ R R R R R R],
[ R **B B B** R R],
[ B R R R B B],
[ R B R R R R]]
I tried doing a BFS for a specific colour in all directions but was unable to come up to solution.
Can someone guide me to the solution.
To find the groups of B cells surrounded by R cells, think of the matrix as a graph whose vertices are all the B cells, with edges connecting adjacent B cells. Use BFS (or DFS) to find the connected components of this graph, but ignore the connected components that contain cells on the boundary. Each (non-boundary) connected component contains a set of B cells surrounded by R cells. Then, to find the groups of R cells surrounded by B cells, similarly compute the non-boundary connected components of the graph whose vertices are the R cells.
Since the number of vertices and edges of both graphs is O(mn) and the set of connected components of a graph can be found in time that is linear in the graph's size, the running time of this algorithm is O(mn).
I'll start of with an example, to clarify what kind of algorithm I'm looking for:
For example, there are the words one, two and three. Those could be arranged like that:
three
w
one
or
t
h
t r
w e
one
More examples:
t
eight
t r
w e
one
eightwo
h
r
one
e
n
eightwo
n h
e r
one
e
eightwo
h
r
one
nine
etc.
How could I achieve this algorithm, for getting the
a) the least character count?
b) tightest arrangement?
c) for any combination?
This is not homework nor a interview question, I'm trying to rebuild the QlockTwo with a slightly different design.
I've been reviewing Eugene Myers' Diff Algorithm Paper. This is the algorithm that is implemented in the popular diff program.
On page 12 of the paper, it presents the pseudo-code for the algorithm to find the longest common sub-sequence of A and B:
LCS(A, N, B, M)
If N > 0 and M > 0 Then
Find the middle snake and the length of an optimal path for A and B.
Suppose it is from (x, y) to (u, v).
If D > 1 Then
LCS(A[1..x], x, B[1..y], y)
Output A[x+1..u]
LCS(A[u+1..N], N-u, B[v+1..M], M-v)
Else If M > N Then
Output A[1..N].
Else
Output B[1..M].
Suppose A = "A" and B = "B". In this case, N = 1 and M = 1. The middle snake would be (x, y) = (0, 1) and (u, v) = (0, 1) because there are no diagonals. In this case D = 1 because the algorithm has only taken one step.
The algorithm says that the only thing to do in this scenario is to Output B[1..M], equal to "B", because N > 0, M > 0, D = 1, and M = N. But this seems wrong, because there is no common sub-sequence between "A" and "B". The paper's commentary that "If D <= 1 then B is obtained from A by either deleting or inserting at most one symbol" is incorrect because "A" must be removed and "B" added.
What am I misinterpreting here?
You are misunderstanding the definition of D-path and snake.
From page 4:
Let a D-path be a path starting at (0,0) that has exactly D non-diagonal
edges. A 0-path must consist solely of diagonal edges. By a simple induction, it follows that a D-path must consist of a (D − 1)-path followed by a non-diagonal edge and then a possibly empty sequence of diagonal edges called a snake
So, in your example where A = "A" and B = "B", the optimal path is a 2-path (one horizontal and one vertical), and the middle snake is an empty string. We know from inspection the LCS is an empty string, but we'd like to show the algorithm working to prove it.
First of all we need to find the middle snake. If you follow the algorithm to find the middle snake on page 11, you will see that the length of the shortest edit script is 2 and (x,y) = (u,v) = (1,0) or (0,1). In other words, it is an empty snake in the middle of the path.
The algorithm pseudocode has some non-obvious notational conventions:
A[m..n] is an empty string if n < m.
In the recursive calls to LCS, the first call uses ceiling(D/2) as D and the second call uses floor(D/2). This is made more clear in the text above the algorithm on page 12.
So, in this example case, assume the first call to LCS finds a middle snake with (x,y) = (u,v) = (1,0), then since D=2, the result is the expansion of:
LCS(A[1..1], 1, B[1..0], 0) // Output nothing since M = 0
Output A[2..1] // Output nothing since it is an empty string.
LCS(A[2..1], 0, B[1..1], 1) // Output nothing since N = 0
This is correct since these strings have no common sub-sequence.
I currently work on a problem where I want to try to find an algorithm which does the following: Given a square grid graph G and start node S and an end node E, where E and S in G, find a path P from S to E with maximum value and |P| <= k. If it makes it easier, one can possibly make G a DAG.
The grid cells are either 0 or 1.
As an example:
S--o--o--o
| : | |
o--o..o..o
: | : |
o--o--E--o
| : | |
o--o--o--o
S := "Starting State"
E := "Ending State"
- := "Edge value is 1"
. := "Edge value is 0"
Solution with k = 5 (from what I see)
S o o o
|
o--o o o
|
o o--E o
o o o o
S and E lie arbitrarily, so one cannot assume just down and right movement, but I can transform the graph to a DAG with some loss to optimality I assume.
Edge value is a cost, G is a grid graph where every node is connected to its four neighbours.
First of all, is this problem already known in literature? I did not find anything about it. Is it in NP or does someone has an idea for a fast algorithm? I asked the search engine of my choice, and somebody asked something maybe related to it on StackOverflow , but their problem description does not match 100%, since their goal is last row, where mine is a distinct node.
Aight, a warning first: I've thought this up on the spur of the moment. I seem to remember reading about something like it before, but I can't remember where, so while it seems correct I can't be sure of it. If I spot a flaw later, I'll come back and edit this post and notify you.
Let L(k, v) be the value of the path of length at most k from S to some node v, and suppose v has predecessors {u1, u2, ... um}. Since G is a DAG, it must be that
L(k, v) = max { L(k-1, u1) + w(u1, v), L(k-1, u2) + w(u2, v), ..., L(k-1, um) + w(um, v) }
where w(u,v) is the weight of the edge from u to v.
To put this to use, what we're going to do is find the highest value path of length < R to every node within a radius of R of S. That then gives us enough information to calculate the highest-value path of length < R+1 to every node within a radius R+1 of S. So:
First, throw away any node that is more than distance k from S, as it can't possibly be part of the optimum path. We have O(k^2) nodes remaining.
Now initialize a collection L and set L[S] = 0. Leave all other entries undefined.
Next, apply the L[v] rule to each node in the graph (ignore the k parameters)
If a predecessor u of a node v doesn't have a value for L[u] defined yet, ignore u when calculating L[v].
If no predecessor u of v has L[u] defined, leave L[v] undefined.
Repeat Step 3 k-1 more times.
If L[E] has a value, return it. Else there is no length k path from S to E.
This is O(k^3) time. You could probably speed it up for large graphs by only considering nodes both within distance 1 of S and distance k-1 of E during the first execution of Step 3, and only nodes within distance 2 of S and distance k-2 of E during the second execution, and so-on, but that'll still be cubic time.