wordplay problem

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • kdt
    New Member
    • Mar 2007
    • 50

    wordplay problem

    Hi

    I want to create a script that substitutes each full stop character (which represents the placement of a vowel) with all possible combinations of vowels.

    Code:
    >>> word = "c.ttl."
    >>> for l in vowels:
    	    word.replace(".", l)
    
    	
    'cattla'
    'cettle'
    'cittli'
    'cottlo'
    'cuttlu'
    However, for this I would expect 25 different combinations. Such as 'cattla', 'cattle' and so on. I've tried putting this into nested loops, but I need to make it run when there are any given number of "." characters that need replacing.

    Can anyone make a suggestion please. I'm in loop hell!

    Thanks
  • bartonc
    Recognized Expert Expert
    • Sep 2006
    • 6478

    #2
    You may want to start with"[CODE=python]
    >>> word = "c.ttl."
    >>> count = word.count('.')
    >>> count
    2
    >>> [/CODE]

    Comment

    • bartonc
      Recognized Expert Expert
      • Sep 2006
      • 6478

      #3
      Originally posted by bartonc
      You may want to start with"[CODE=python]
      >>> word = "c.ttl."
      >>> count = word.count('.')
      >>> count
      2
      >>> [/CODE]
      Here's where I went from there:[CODE=python]
      >>> parts = word.split('.')
      >>> parts
      ['c', 'ttl', '']
      >>> loopCount = len(vowels)
      >>> for i in range(loopCount **count):
      ... idx1 = i%loopCount # modulo
      ... idx2 = i/loopCount # integer division
      ... print vowels[idx1], vowels[idx2]
      ...
      a a
      e a
      i a
      o a
      u a
      a e
      e e
      i e
      o e
      u e
      a i
      e i
      i i
      o i
      u i
      a o
      e o
      i o
      o o
      u o
      a u
      e u
      i u
      o u
      u u
      >>> [/CODE]

      Comment

      • bartonc
        Recognized Expert Expert
        • Sep 2006
        • 6478

        #4
        It gets trickier as you go beyond count = 2, but this may help get you started:[CODE=python]
        >>> for i in range(loopCount **count):
        ... idx1 = i%loopCount # modulo
        ... idx2 = i/loopCount # integer division
        ... newWord = word.replace('. ', vowels[idx1], 1)
        ... print newWord.replace ('.', vowels[idx2])
        ... [/CODE]
        cattla
        cettla
        cittla
        cottla
        cuttla
        cattle
        cettle
        cittle
        cottle
        cuttle
        cattli
        cettli
        cittli
        cottli
        cuttli
        cattlo
        cettlo
        cittlo
        cottlo
        cuttlo
        cattlu
        cettlu
        cittlu
        cottlu
        cuttlu
        >>>

        Comment

        • bvdet
          Recognized Expert Specialist
          • Oct 2006
          • 2851

          #5
          Originally posted by kdt
          Hi

          I want to create a script that substitutes each full stop character (which represents the placement of a vowel) with all possible combinations of vowels.

          Code:
          >>> word = "c.ttl."
          >>> for l in vowels:
          	    word.replace(".", l)
          
          	
          'cattla'
          'cettle'
          'cittli'
          'cottlo'
          'cuttlu'
          However, for this I would expect 25 different combinations. Such as 'cattla', 'cattle' and so on. I've tried putting this into nested loops, but I need to make it run when there are any given number of "." characters that need replacing.

          Can anyone make a suggestion please. I'm in loop hell!

          Thanks
          This seems too complicated, but appears to work for any combination:[code=Python]def indexList(s, item, i=0):
          i_list = []
          while True:
          try:
          i = s.index(item, i)
          i_list.append(i )
          i += 1
          except:
          break
          return i_list

          def indices(idx, vowels, idxList=False, cnt=False):
          if idx:
          if not idxList:
          idxList = [[] for _ in range(len(vowel s)**len(idx))]
          cnt = len(vowels)**(l en(idx)-1)
          vowel_idx = -1
          for i, item in enumerate(idxLi st):
          if not i%cnt:
          vowel_idx += 1
          if vowel_idx == len(vowels):
          vowel_idx = 0
          idxList[i].append(vowels[vowel_idx])
          indices(idx[1:], vowels, idxList, cnt/len(vowels))
          return idxList

          def word_list(word, vowels):
          idx = indexList(word, '.')
          wordList = []
          for item in indices(idx, vowels):
          w = list(word)
          for i, j in enumerate(idx):
          w[j] = item[i]
          wordList.append (''.join(w))
          return wordList

          vowels = ['a', 'e', 'i', 'o', 'u']
          word = ".m.g.ne"

          wordList = word_list(word, vowels)

          for word in wordList:
          print word,[/code]
          Output:
          >>> amagane amagene amagine amagone amagune amegane amegene amegine amegone amegune amigane amigene amigine amigone amigune amogane amogene amogine amogone amogune amugane amugene amugine amugone amugune emagane emagene emagine emagone emagune emegane emegene emegine emegone emegune emigane emigene emigine emigone emigune emogane emogene emogine emogone emogune emugane emugene emugine emugone emugune imagane imagene imagine imagone imagune imegane imegene imegine imegone imegune imigane imigene imigine imigone imigune imogane imogene imogine imogone imogune imugane imugene imugine imugone imugune omagane omagene omagine omagone omagune omegane omegene omegine omegone omegune omigane omigene omigine omigone omigune omogane omogene omogine omogone omogune omugane omugene omugine omugone omugune umagane umagene umagine umagone umagune umegane umegene umegine umegone umegune umigane umigene umigine umigone umigune umogane umogene umogine umogone umogune umugane umugene umugine umugone umugune
          >>>
          Maybe someone else can improve on this.

          Comment

          • kdt
            New Member
            • Mar 2007
            • 50

            #6
            Hi bartonc, was waiting for you to post :) Thanks also bvdet for your code, which will probably take me a while to work through.
            I was having a look at recursive algorithms last night and not really getting anywhere. I found the following code in the python mailing list, but quite frankly lambdas and maps scare me. It seems pretty efficient but I guess I'll need to study it to get a better idea of whats going on. If either of you would be able to give me an idea on how to start on this recursively, it would be appreciated.

            Code:
            def magic_algorithm(listin, count):
                for i in listin:
                    if type(i)!=type(''):
                        raise TypeError, 'all items in list passed to magic_algorithm must be strings'
                l=len(listin)
                return map(''.join, map(lambda x, count=count, l=l, listin=listin:
                    map(lambda y, x=x, count=count, l=l, listin=listin: listin[((x/(l**y)) %l)], range(count)), xrange(l**count)))
            
            n = magic_algorithm(['a','e','i','o','u'],5)
            
            for l in n:
                print l
            Cheers

            Comment

            • bvdet
              Recognized Expert Specialist
              • Oct 2006
              • 2851

              #7
              Originally posted by kdt
              Hi bartonc, was waiting for you to post :) Thanks also bvdet for your code, which will probably take me a while to work through.
              I was having a look at recursive algorithms last night and not really getting anywhere. I found the following code in the python mailing list, but quite frankly lambdas and maps scare me. It seems pretty efficient but I guess I'll need to study it to get a better idea of whats going on. If either of you would be able to give me an idea on how to start on this recursively, it would be appreciated.

              Code:
              def magic_algorithm(listin, count):
                  for i in listin:
                      if type(i)!=type(''):
                          raise TypeError, 'all items in list passed to magic_algorithm must be strings'
                  l=len(listin)
                  return map(''.join, map(lambda x, count=count, l=l, listin=listin:
                      map(lambda y, x=x, count=count, l=l, listin=listin: listin[((x/(l**y)) %l)], range(count)), xrange(l**count)))
              
              n = magic_algorithm(['a','e','i','o','u'],5)
              
              for l in n:
                  print l
              Cheers
              kdt,
              Look closely and you may notice that my code uses recursion The first function indexList() returns a list of the index numbers (variable 'idx') of the '.' character in the variable 'word'. Function indices() compiles a list of lists of letter combinations found in the list vowels. It uses recursion for each element in the list 'idx'. Function word_list() compiles a list of words. A word is appended for each element in the list returned by indices(). The variable 'word' is converted into a list, and the letters compiled into the letter combinations list are assigned by slice to the characters in the positions defined in the list 'idx'.

              You may be able to incorporate function magic_algorithm () into your script. It more or less serves the same purpose as my function indices(), albeit more efficiently. HTH :)

              Comment

              • kdt
                New Member
                • Mar 2007
                • 50

                #8
                hi bvdet,

                Thanks for the explanation. I'll have a proper look at this later today.

                Thanks again :)

                Comment

                • KaezarRex
                  New Member
                  • Sep 2007
                  • 52

                  #9
                  I think I found a simple recursive solution to your problem. If there is a stop character in the word, then for each vowel it replaces only the first stop character, and it calls the method again for each of those new words. When a word doesn’t have any more stop characters in it, the word is printed and the method is not called again.

                  [CODE=python]def recurse(word):

                  if word.count(".") :
                  for l in vowels:
                  recurse(word.re place(".", l, 1))
                  else:
                  print word[/CODE]

                  good luck!

                  Comment

                  • bartonc
                    Recognized Expert Expert
                    • Sep 2006
                    • 6478

                    #10
                    Originally posted by KaezarRex
                    I think I found a simple recursive solution to your problem. If there is a stop character in the word, then for each vowel it replaces only the first stop character, and it calls the method again for each of those new words. When a word doesn’t have any more stop characters in it, the word is printed and the method is not called again.

                    [CODE=python]def recurse(word):

                    if word.count(".") :
                    for l in vowels:
                    recurse(word.re place(".", l, 1))
                    else:
                    print word[/CODE]

                    good luck!
                    Very elegant! Thank you. I'm reposting, as there seems to be an indentaion error in your post:
                    [CODE=python]
                    >>> def recurse(word):
                    ... if word.count(".") :
                    ... for l in vowels:
                    ... recurse(word.re place(".", l, 1))
                    ... else:
                    ... print word[/CODE]

                    Comment

                    • kdt
                      New Member
                      • Mar 2007
                      • 50

                      #11
                      Hi all,

                      Sorry to resurrect an old post, but I have a more complex feature I need to add.
                      Given some patterns such as "...t...s." I need to make all possible combinations given a separate list for each position. The length of the pattern is fixed to 9, so thankfully that reduces a bit of the complexity.

                      For example I have the following:

                      pos1 = ['a',' t']
                      pos2 = ['r', 's']
                      pos3 = ['n', 'f']

                      So if the pattern contains a '.' character at position 1 it could be 'a' or 't'. For the pattern '.s.' all combinations would be:

                      asn
                      asf
                      tsn
                      tsf

                      Thanks

                      Comment

                      • bartonc
                        Recognized Expert Expert
                        • Sep 2006
                        • 6478

                        #12
                        Originally posted by kdt
                        Hi all,

                        Sorry to resurrect an old post, but I have a more complex feature I need to add.
                        Given some patterns such as "...t...s." I need to make all possible combinations given a separate list for each position. The length of the pattern is fixed to 9, so thankfully that reduces a bit of the complexity.

                        For example I have the following:

                        pos1 = ['a',' t']
                        pos2 = ['r', 's']
                        pos3 = ['n', 'f']

                        So if the pattern contains a '.' character at position 1 it could be 'a' or 't'. For the pattern '.s.' all combinations would be:

                        asn
                        asf
                        tsn
                        tsf

                        Thanks
                        I'd start by making a tuple out of the separate variables in order to afford indexing on the position of the dot:[CODE=python]posTuple = (('a', 't'), ('r', 's'), ('n', 'f'))
                        # note the use of tuples inside, as well. Tuples are much more efficient than lists, as they are a fixed length type.[/CODE]

                        Comment

                        • kdt
                          New Member
                          • Mar 2007
                          • 50

                          #13
                          Originally posted by bartonc
                          I'd start by making a tuple out of the separate variables in order to afford indexing on the position of the dot:[CODE=python]posTuple = (('a', 't'), ('r', 's'), ('n', 'f'))
                          # note the use of tuples inside, as well. Tuples are much more efficient than lists, as they are a fixed length type.[/CODE]
                          Hi bartonc,

                          Unfortunately I need to use lists as I need to append values, as in the following (surely there's a more elegant way of doing this):

                          Code:
                          pos1 =[]
                          pos3 =[]
                          pos4 =[]
                          pos5 =[]
                          pos6 =[]
                          pos7 =[]
                          pos8 =[]
                          
                          for key in gOutList.keys():
                              if not key[0] in pos1:
                                  pos1.append(key[0])
                              if not key[2] in pos3:
                                  pos3.append(key[2])
                              if not key[3] in pos4:
                                  pos4.append(key[3])
                              if not key[4] in pos5:
                                  pos5.append(key[4])
                              if not key[5] in pos6:
                                  pos6.append(key[5])
                              if not key[6] in pos7:
                                  pos7.append(key[6])
                              if not key[7] in pos8:
                                  pos8.append(key[7])

                          Comment

                          • bartonc
                            Recognized Expert Expert
                            • Sep 2006
                            • 6478

                            #14
                            Originally posted by kdt
                            Hi bartonc,

                            Unfortunately I need to use lists as I need to append values, as in the following (surely there's a more elegant way of doing this):

                            Code:
                            pos1 =[]
                            pos3 =[]
                            pos4 =[]
                            pos5 =[]
                            pos6 =[]
                            pos7 =[]
                            pos8 =[]
                            
                            for key in gOutList.keys():
                                if not key[0] in pos1:
                                    pos1.append(key[0])
                                if not key[2] in pos3:
                                    pos3.append(key[2])
                                if not key[3] in pos4:
                                    pos4.append(key[3])
                                if not key[4] in pos5:
                                    pos5.append(key[4])
                                if not key[5] in pos6:
                                    pos6.append(key[5])
                                if not key[6] in pos7:
                                    pos7.append(key[6])
                                if not key[7] in pos8:
                                    pos8.append(key[7])
                            Because you didn't provide any data to work on, I can't be sure if this is what you are after:[CODE=python]
                            >>> tempKeys = ("key#%i" %i for i in range(8))

                            >>> keyDict = dict(zip(tempKe ys, ("" for i in range(8))))
                            >>> keyDict
                            {'key#1': '', 'key#0': '', 'key#3': '', 'key#2': '', 'key#5': '', 'key#4': '', 'key#7': '', 'key#6': ''}
                            >>> posList = [[] for i in range(8)]
                            >>> posList
                            >>> for i, key in enumerate(keyDi ct.keys()):
                            ... if key not in posList[i]:
                            ... posList[i].append(key) # didn't make my keys as tuple
                            ...
                            >>> posList
                            [['key#1'], ['key#0'], ['key#3'], ['key#2'], ['key#5'], ['key#4'], ['key#7'], ['key#6']]
                            >>> [/CODE]

                            Comment

                            • kdt
                              New Member
                              • Mar 2007
                              • 50

                              #15
                              Hi,

                              Managed to get this done by modifying KaezarRex's code - thanks.
                              Code:
                              >>> sList = [['t','v'],['y','k','l']]
                              >>> patt ='..g'
                              >>> def recurse(pattern, sList):
                                  if pattern.count('.'):
                                      j=pattern.find('.')
                                      for i in sList[j]:
                                          recurse(pattern.replace ('.', i,1), sList)
                                  else:
                                      print pattern
                              
                              
                              >>> recurse(patt, sList)
                              tyg
                              tkg
                              tlg
                              vyg
                              vkg
                              vlg
                              Last edited by kdt; Sep 17 '07, 09:29 PM. Reason: forgot code tags

                              Comment

                              Working...