[Tutor] word challenge

Karl Pflästerer sigurd@12move.de
Fri Jul 18 18:07:01 2003


On 18 Jul 2003, gyro funch <- gyromagnetic@excite.com wrote:

> Hi, I thought that this might be an interesting challenge for those of
> you with a 'puzzling' disposition. ;-)

Yes it was very funny.  I have a possible solution.  Don't know if it's
very pythonesque but I like it.

> Suppose I have a phrase from which I want to extract a word made up of
> at least one letter from each of the words (more than one letter may
> be taken from each word if desired). The letters must be aligned in
> the order in which they were taken from the words.

> For instance, if I have the phrase: "handy cool phrase" I might
> extract the "h" from "handy", one "o" from "cool", and the "r","s",and
> "e" from "phrase" to give "horse".

> Each word must exist in some defined dictionary or word list.


I started playing like that:

phrase    = 'handy cool phrase'
phrasewos = ''.join(phrase.split()).split()
seq       = range(len(phrasewos))

So I had now a sequence where each digit represented an index to our
word list.  To shuffle it I used list comprehension:

[[x,y,z] \
 for x in seq \
 for y in seq[x+1:] \
 for z in seq[y+1:]]

So far so good but how could I build a function for a arbitrary number
of chars?  I let Python write it.

So here comes my solution:


--8<---------------cut here---------------start------------->8---
def shuffle_words(number, phrase):
    phrase = ''.join(phrase.split())
    seq    = range(len(phrase))
    seq    = eval(build_fun(number))
    words  = []
    for word in seq:
        wort = ''
        for index in word:
            wort += phrase[index]
        words.append(wort)
    return words


def build_fun(number):
    vals = '[[a0, '
    fun  = 'for a0 in seq ' 
    for i in range(1, number):
        vals += 'a' + str(i) + ', '
        fun  += 'for ' 'a' + str(i) + ' in seq[' + 'a' + str(i-1) + '+1:]'
    vals += '] '
    fun  += ']'
    return vals + fun

def filter_words(seq, dict):
    filter(lambda x: dict.has_key(x), seq)
--8<---------------cut here---------------end--------------->8---

`build_fun' is a function which creates a string (our list
comprehension)
`shuffle_words' takes our phrase and a number (the length of our words)
and builds all possible combinations according to our rules and returns
them in a list.
`filter_words' takes that list and a dictionary (the dictionary has
existing words as keys) and returns a list with the words found in the
dictionary.

Here an example:

>>> d = {'has': None, 'had': None}
>>> seq = shuffle_words(3, phrase)
>>> filter(lambda x: d.has_key(x), seq)
['had', 'has', 'has', 'has']
>>> 

As we see at the moment words which are multiple times in the list are
also multiple times returned; this may be what we want or not.  But
that's easy to change.


   Karl
-- 
Please do *not* send copies of replies to me.
I read the list