1
«CROSSES AND ZEROES
2
3
«THE CHAIN» THE LAST LETTER OF THE WORD IS THE FIRST LETTER OF NEXT WORD. STUDENT
4
«TRANSLATOR» TRANSLATE WORD-COMBINATIONS INTO ENGLISH 1) ПРЕКРАСНАЯ ПОГОДА 2) ЛЕТНИЕ КАНИКУЛЫ 3) ИЗУЧАТЬ МАТЕМАТИКУ 4) СКУЧАТЬ ПО РОДИТЕЛЯМ 5) ХОРОШАЯ НОВОСТЬ 6) ПРОВЕСТИ НЕДЕЛЮ В ДЕРЕВНЕ 7) ИНТЕРЕСНЫЕ МЕСТА ШКОЛЬНЫЙ ВЕЧЕР
5
« RIDDLES» IT RUNS, BUT HAS NO LEGS? CHILDREN DONT LIKE TO DRINK ESPECIALLY WHEN ITS WARM? ITS WHITE.ITS COLD. WE CAN SKATE ON IT. WHAT IS IT? WHAT MAN CANT LIVE INSIDE THE HOUSE OF LITTLE OLD WOMAN WITH 12 CHILDREN: SOME SHORT, SOME LONG, SOME COLD, SOME HOT. WHAT IS SHE?
6
Scoring
You scored / = %
This beats or equals
% of test takers
also scored 100%
The average score is
Your high score is
Your fastest time is
Keep scrolling down for answers and more stats …
|
|
The Comparator
approach won’t work. Sorting uses only local comparisons, but your problem is a global ‘optimisation’ one.
To illustrate, here are the actual comparisons from Arrays.sort(array, comparator)
. Note that some of the swaps break correct choices made earlier, because they have only local knowledge.
start: dog,elephant,giraffe,rhinoceros,tiger
dog, elephant (swap)
-> elephant,dog,giraffe,rhinoceros,tiger
dog, giraffe (OK)
-> elephant,dog,giraffe,rhinoceros,tiger
giraffe, rhinoceros (swap)
-> elephant,dog,rhinoceros,giraffe,tiger
dog, rhinoceros (swap)
-> elephant,rhinoceros,dog,giraffe,tiger
elephant, rhinoceros (swap)
-> rhinoceros,elephant,dog,giraffe,tiger
giraffe, tiger (swap)
-> rhinoceros,elephant,dog,tiger,giraffe
dog, tiger (swap)
-> rhinoceros,elephant,tiger,dog,giraffe
elephant, tiger (OK)
-> rhinoceros, elephant, tiger, dog, giraffe
My friend gave me a problem that he says is easy, but I can’t figure out a good algorithm to use to do it.
You are given an input of 100 random English words. You have to find the longest string of words where the last letter in one word matches the first letter in the next word. You can only use each word once.
For example, if you were given the words «cat», «dog», «that», the longest string you could make would be «cat -> that». If you were given the words «mouse», «moose», «unicorn», the longest string you could make would just be one word (since none of those words link). If you were given the words «bird», «dish», «harb», the longest string you could make would be «harb -> bird -> dish» (or «dish -> harb -> bird» or «bird -> dish -> harb»).
I came up with the idea of modeling this as a directed cyclic graph. Each node would just be a word, with vertices going to each word/node that started with the letter this word ended with.
+-------+ +------+
| cat |-----------| that |
+-------+ / +------+
| |
|/ |
+-------+ / |
| the |--------------+
+-------+
This problem appears to be a longest path search, which is NP-Hard.
Is there a better way to do it? Or even some sort of approximation algorithm that could be used? Or some way to exploit qualities of English to reduce the search space?
asked Aug 11, 2013 at 7:11
15
I think this is related to the longest path (LP) problem that you mentioned, but it’s a little different. The primary difference is that the LP problem has a higher degree of connectivity than what your suggested problem does. By restricting your connections to the last and first letters, you remove a large number of potential combinations.
Here’s how I would recommend tackling this one:
- For each word in the list, count the possible connections in and connections out.
- Discard any words that have 0 ins and 0 outs.
- Identify an initial set of «starter words» with the lowest numbers of ins and outs, and the outs must be greater than 0.
- Each starter word receives its own working copy of the ins / outs connection count. This forms the head of the chain.
- For each chain, identify a list of «next words» based upon:
- last letter of starter or previous word
- lowest number of of ins and outs connections (again, the outs must be greater than 0)
- For each
next word
, repeat step 5 until the chain terminates.
Keep in mind that:
-
You’ll need to keep track of the length of the chains and have some global mechanism to identify the longest chain.
-
You’ll also need to remove each word from the working copy of the connection counts in order to avoid a recursive loop.
-
At some point, your chain will terminate and you have to select a word with a 0 connection out count.
-
You may have to recalculate ins / outs as words are removed from the working lists. At first glance, I don’t think this will be necessary as the overall sets will be relatively small. If you scaled out to 1000 words, then having static counts may slow down the algorithm from converging.
I kind of saw this as a packing problem. To me, the connections in and out identify the shape to be packed. The lower the connections, the more odd the shape. The more odd the shape, the sooner I want to pack it as I perceived having decreasing odds of being able to pack an odd shape the later I got into the chain.
As an example:
{dog, gopher, alpha, cube, elegant, this, that, bart}
dog 0, 1
gopher 1, 0
alpha 0, 0
cube 0, 1
elegant 1, 2
this 3, 0
that 2, 1
bart 0, 2
//alpha is dropped with 0 in and 0 out.
//two candidates found: dog, cube
//chain 1
dog => gopher
//chain 2
cube => elegant => that => this
//Note 1: the following chain won't occur due to selection rules
//that takes priority over this because of output count
cube => elegant => this
//Note 2: this chain won't occur either due to selection rules
bart => that => this
answered Aug 14, 2013 at 17:54
5
If you make 26X26 matrix to represent directed graph of vertex as each alphabet and words as edge.
For example word — APPLE connect vertex A and E with edge directed from A to E.
Now the problem reduces to finding largest Eulerian trail (path which includes maximum number of edges, visiting each edge once wit possible repetition of vertices) in the graph.
One of the O(E) algorithm would be to start randomly from a pair of vertices.
Find a path between them. Than keep relaxing the path till it is possible.
update
@GlenH7 I solved a similar question on www.hackerearth/jda recently, there was relative marks with respect to best solution and I scored the highest marks with the following approch-
Given list of words. Find the longest chain that can be formed by them. A chain is valid if every word begin with a letter *ending at the ending of last word.
Approch =
1)make the graph of alphabets as vertices and words as edges.
In place of using multiple edges use one with weight equal to
number of edges.
2)find the strongly connected component of graph with
maximum edges. Temporarily discard other edges.
3)For each vertex make its indegree equal to its outdegree.
4)Now their exists eulerian circuit in graph. Find it.
5)Now in remaining graph(w.r.t orignal graph find the longest
trail with first vertex in chosen strongly connected
component. I think this is NP hard.
6)Include the above trail in Elerian circuit converting eulerian
circuit into trail.
Why — I accept that this question is most probably NP hard(guess, not mathematically speaking). But the above approach works best when there is a long list(1000+) of uniformly distributed words(i.e. not intended to be w.c. for above approach).
Let us assume that after converting given list to graph mentioned above, it luckily turns out to be a eulerian graph(see http://en.wikipedia.org/wiki/Eulerian_path for conditions), then without any doubt we can say that answer to above question is P and is actually the eulerian path in the graph(see http://www.graph-magics.com/articles/euler.php for a very simple approch to do so and see this to verify that your graph has single http://www.geeksforgeeks.org/strongly-connected-components/ and if not temporarily clean other small scc because eulerian path exists for single scc). Thus for not lucky cases(which are almost all cases) I try to convert them to lucky cases(i.e eulerian trail condition are fulfilled). How to do this? I tried do increasing depth search for irrelevant edges(the set of edges in a path staring from vertex with outdegree greater than indegree and ending at vertex with indegree greater than outdegree). Increasing depth search means that first I searched for all such set of one edge in path than two edges in path and so on. It may seem at first look that ith depth search would take O(nodes^i) thus total time complexity of O(nodes + nodes^2 + nodes^3 + ….) till it is a lucky case. But amortized analysis will revel it is O(edges). Once it is reduced lucky case find eulerian circuit.
Till here it was all polynomial time. This would give almost the best solution. But to further increase your solution(perfect solution is NP hard) try some greedy approach in remaining graph to find a long trail staring with one of vertices in chosen scc. Now add this to above found eulerian trail to further increase it.
answered Jun 25, 2014 at 20:25
1
Idea:
First, create two maps (hashes), say, S, and E, from alphabet letters to words; the first, S, maps starting letters to words, the second, E, does the same with ending letters.
E.g., if the dictionary is made of:
bird, dish, dog, harb
we have:
S:
a -> [ ]
b -> [ bird ]
c -> [ ]
d -> [ dish, dog ]
...
h -> [ harb ]
...
and,
E:
a -> [ ]
b -> [ harb ]
c -> [ ]
d -> [ bird ]
...
g -> [ dog ]
h -> [ dish ]
...
Next, using S and E for fast lookups, create a forest (set of trees), of the same size as the dictionary, with roots at each word, and not allowing a word to appear more than once in a tree — cache the trees’ depths as you construct them:
bird (depth: 2)
dish
harb
dog
dish (depth: 3)
harb
bird
dog
dog (depth: 0)
harb (depth: 2)
bird
dish
dog
Finally, iterate over the forest and find the tree(s) of greatest depth.
The solution(s) will be on the descendant axis of those trees.
E.g.,
dish / harb / bird / dog
above.
answered Mar 7, 2016 at 15:33
YSharpYSharp
8986 silver badges10 bronze badges
level 1
It would be a fairly easy beginner programming project, in say, Python.
Read in list of words, reverse each word, sort new list, reverse again.
level 2
Don’t even have to go through that much trouble:
egrep 'oid$' /etc/dictionaries-common/words
level 2
You could get more specific than that if you’re looking for a single ending and don’t want to make a whole dictionary:
Go through each word from last letter to first and check if it matches the ending string.
You could even just use str.endswith() to avoid parsing the string. Then the whole program would basically be
for word in dictionary: if(str.endswith(“oid”)): print(word)
level 1
The standard «dictionary» order is called the lexicographic order.
You want the antilexicographic order.
level 2
Antilexicographic means ordered by the reversed alphabet, i.e. Z — A, but OP is asking to lexicographically sort by the final letter of each word.
level 1
…I don’t know! This is very hard to Google, because anywhere you put the word ‘reverse’ is gonna think you want things in reverse alphabetical order (Z–A) rather than like… alphabetical reverse order, I guess?
For your specific case though, Wolfram Alpha is good: https://www.wolframalpha.com/input/?i=words+ending+in+oid
level 1
Get a .txt version of the dictionary, and Control-F?
level 1
Looks like this website here for cheating at Scrabble can do just that for ya!
level 2
I guess this isn’t a dictionary, and I believe a commenter already mentioned a rhyming dictionary, which would be the way to go if you’re looking for something book-wise.