471,356 Members | 1,714 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,356 software developers and data experts.

wordplay problem

50
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.

Expand|Select|Wrap|Line Numbers
  1. >>> word = "c.ttl."
  2. >>> for l in vowels:
  3.         word.replace(".", l)
  4.  
  5.  
  6. 'cattla'
  7. 'cettle'
  8. 'cittli'
  9. 'cottlo'
  10. '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
Sep 4 '07 #1
15 1652
bartonc
6,596 Expert 4TB
You may want to start with"
Expand|Select|Wrap|Line Numbers
  1. >>> word = "c.ttl."
  2. >>> count = word.count('.')
  3. >>> count
  4. 2
  5. >>> 
Sep 4 '07 #2
bartonc
6,596 Expert 4TB
You may want to start with"
Expand|Select|Wrap|Line Numbers
  1. >>> word = "c.ttl."
  2. >>> count = word.count('.')
  3. >>> count
  4. 2
  5. >>> 
Here's where I went from there:
Expand|Select|Wrap|Line Numbers
  1. >>> parts = word.split('.')
  2. >>> parts
  3. ['c', 'ttl', '']
  4. >>> loopCount = len(vowels)
  5. >>> for i in range(loopCount**count):
  6. ...     idx1 = i%loopCount # modulo
  7. ...     idx2 = i/loopCount # integer division
  8. ...     print vowels[idx1], vowels[idx2]
  9. ...     
  10. a a
  11. e a
  12. i a
  13. o a
  14. u a
  15. a e
  16. e e
  17. i e
  18. o e
  19. u e
  20. a i
  21. e i
  22. i i
  23. o i
  24. u i
  25. a o
  26. e o
  27. i o
  28. o o
  29. u o
  30. a u
  31. e u
  32. i u
  33. o u
  34. u u
  35. >>> 
Sep 4 '07 #3
bartonc
6,596 Expert 4TB
It gets trickier as you go beyond count = 2, but this may help get you started:
Expand|Select|Wrap|Line Numbers
  1. >>> for i in range(loopCount**count):
  2. ...     idx1 = i%loopCount # modulo
  3. ...     idx2 = i/loopCount # integer division
  4. ...     newWord = word.replace('.', vowels[idx1], 1)
  5. ...     print newWord.replace('.', vowels[idx2])
  6. ...     
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
>>>
Sep 4 '07 #4
bvdet
2,851 Expert Mod 2GB
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.

Expand|Select|Wrap|Line Numbers
  1. >>> word = "c.ttl."
  2. >>> for l in vowels:
  3.         word.replace(".", l)
  4.  
  5.  
  6. 'cattla'
  7. 'cettle'
  8. 'cittli'
  9. 'cottlo'
  10. '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:
Expand|Select|Wrap|Line Numbers
  1. def indexList(s, item, i=0):
  2.     i_list = []
  3.     while True:
  4.         try:
  5.             i = s.index(item, i)
  6.             i_list.append(i)
  7.             i += 1
  8.         except:
  9.             break
  10.     return i_list
  11.  
  12. def indices(idx, vowels, idxList=False, cnt=False):
  13.     if idx:
  14.         if not idxList:
  15.             idxList = [[] for _ in range(len(vowels)**len(idx))]
  16.             cnt = len(vowels)**(len(idx)-1)
  17.         vowel_idx = -1
  18.         for i, item in enumerate(idxList):
  19.             if not i%cnt:
  20.                 vowel_idx += 1
  21.             if vowel_idx == len(vowels):
  22.                 vowel_idx = 0
  23.             idxList[i].append(vowels[vowel_idx])
  24.         indices(idx[1:], vowels, idxList, cnt/len(vowels))
  25.     return idxList
  26.  
  27. def word_list(word, vowels):
  28.     idx = indexList(word, '.')
  29.     wordList = []
  30.     for item in indices(idx, vowels):
  31.         w = list(word)
  32.         for i, j in enumerate(idx):
  33.             w[j] = item[i]
  34.         wordList.append(''.join(w))
  35.     return wordList
  36.  
  37. vowels = ['a', 'e', 'i', 'o', 'u']
  38. word = ".m.g.ne"
  39.  
  40. wordList = word_list(word, vowels)
  41.  
  42. for word in wordList:
  43.     print word,
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.
Sep 4 '07 #5
kdt
50
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.

Expand|Select|Wrap|Line Numbers
  1. def magic_algorithm(listin, count):
  2.     for i in listin:
  3.         if type(i)!=type(''):
  4.             raise TypeError, 'all items in list passed to magic_algorithm must be strings'
  5.     l=len(listin)
  6.     return map(''.join, map(lambda x, count=count, l=l, listin=listin:
  7.         map(lambda y, x=x, count=count, l=l, listin=listin: listin[((x/(l**y)) %l)], range(count)), xrange(l**count)))
  8.  
  9. n = magic_algorithm(['a','e','i','o','u'],5)
  10.  
  11. for l in n:
  12.     print l
  13.  
  14.  
Cheers
Sep 5 '07 #6
bvdet
2,851 Expert Mod 2GB
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.

Expand|Select|Wrap|Line Numbers
  1. def magic_algorithm(listin, count):
  2.     for i in listin:
  3.         if type(i)!=type(''):
  4.             raise TypeError, 'all items in list passed to magic_algorithm must be strings'
  5.     l=len(listin)
  6.     return map(''.join, map(lambda x, count=count, l=l, listin=listin:
  7.         map(lambda y, x=x, count=count, l=l, listin=listin: listin[((x/(l**y)) %l)], range(count)), xrange(l**count)))
  8.  
  9. n = magic_algorithm(['a','e','i','o','u'],5)
  10.  
  11. for l in n:
  12.     print l
  13.  
  14.  
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 :)
Sep 5 '07 #7
kdt
50
hi bvdet,

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

Thanks again :)
Sep 6 '07 #8
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.

Expand|Select|Wrap|Line Numbers
  1. def recurse(word):
  2.  
  3.    if word.count("."):
  4.       for l in vowels:
  5.          recurse(word.replace(".", l, 1))
  6.       else:
  7.          print word
good luck!
Sep 6 '07 #9
bartonc
6,596 Expert 4TB
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.

Expand|Select|Wrap|Line Numbers
  1. def recurse(word):
  2.  
  3.    if word.count("."):
  4.       for l in vowels:
  5.          recurse(word.replace(".", l, 1))
  6.       else:
  7.          print word
good luck!
Very elegant! Thank you. I'm reposting, as there seems to be an indentaion error in your post:
Expand|Select|Wrap|Line Numbers
  1. >>> def recurse(word):
  2. ...     if word.count("."):
  3. ...         for l in vowels:
  4. ...             recurse(word.replace(".", l, 1))
  5. ...     else:
  6. ...         print word
Sep 6 '07 #10
kdt
50
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
Sep 17 '07 #11
bartonc
6,596 Expert 4TB
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:
Expand|Select|Wrap|Line Numbers
  1. posTuple = (('a', 't'), ('r', 's'), ('n', 'f'))
  2. # note the use of tuples inside, as well. Tuples are much more efficient than lists, as they are a fixed length type.
Sep 17 '07 #12
kdt
50
I'd start by making a tuple out of the separate variables in order to afford indexing on the position of the dot:
Expand|Select|Wrap|Line Numbers
  1. posTuple = (('a', 't'), ('r', 's'), ('n', 'f'))
  2. # note the use of tuples inside, as well. Tuples are much more efficient than lists, as they are a fixed length type.
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):

Expand|Select|Wrap|Line Numbers
  1. pos1 =[]
  2. pos3 =[]
  3. pos4 =[]
  4. pos5 =[]
  5. pos6 =[]
  6. pos7 =[]
  7. pos8 =[]
  8.  
  9. for key in gOutList.keys():
  10.     if not key[0] in pos1:
  11.         pos1.append(key[0])
  12.     if not key[2] in pos3:
  13.         pos3.append(key[2])
  14.     if not key[3] in pos4:
  15.         pos4.append(key[3])
  16.     if not key[4] in pos5:
  17.         pos5.append(key[4])
  18.     if not key[5] in pos6:
  19.         pos6.append(key[5])
  20.     if not key[6] in pos7:
  21.         pos7.append(key[6])
  22.     if not key[7] in pos8:
  23.         pos8.append(key[7])
  24.  
Sep 17 '07 #13
bartonc
6,596 Expert 4TB
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):

Expand|Select|Wrap|Line Numbers
  1. pos1 =[]
  2. pos3 =[]
  3. pos4 =[]
  4. pos5 =[]
  5. pos6 =[]
  6. pos7 =[]
  7. pos8 =[]
  8.  
  9. for key in gOutList.keys():
  10.     if not key[0] in pos1:
  11.         pos1.append(key[0])
  12.     if not key[2] in pos3:
  13.         pos3.append(key[2])
  14.     if not key[3] in pos4:
  15.         pos4.append(key[3])
  16.     if not key[4] in pos5:
  17.         pos5.append(key[4])
  18.     if not key[5] in pos6:
  19.         pos6.append(key[5])
  20.     if not key[6] in pos7:
  21.         pos7.append(key[6])
  22.     if not key[7] in pos8:
  23.         pos8.append(key[7])
  24.  
Because you didn't provide any data to work on, I can't be sure if this is what you are after:
Expand|Select|Wrap|Line Numbers
  1. >>> tempKeys = ("key#%i" %i for i in range(8))
  2.  
  3. >>> keyDict = dict(zip(tempKeys, ("" for i in range(8))))
  4. >>> keyDict
  5. {'key#1': '', 'key#0': '', 'key#3': '', 'key#2': '', 'key#5': '', 'key#4': '', 'key#7': '', 'key#6': ''}
  6. >>> posList = [[] for i in range(8)]
  7. >>> posList
  8. >>> for i, key in enumerate(keyDict.keys()):
  9. ...     if key not in posList[i]:
  10. ...         posList[i].append(key)  # didn't make my keys as tuple
  11. ...         
  12. >>> posList
  13. [['key#1'], ['key#0'], ['key#3'], ['key#2'], ['key#5'], ['key#4'], ['key#7'], ['key#6']]
  14. >>> 
Sep 17 '07 #14
kdt
50
Hi,

Managed to get this done by modifying KaezarRex's code - thanks.
Expand|Select|Wrap|Line Numbers
  1. >>> sList = [['t','v'],['y','k','l']]
  2. >>> patt ='..g'
  3. >>> def recurse(pattern, sList):
  4.     if pattern.count('.'):
  5.         j=pattern.find('.')
  6.         for i in sList[j]:
  7.             recurse(pattern.replace ('.', i,1), sList)
  8.     else:
  9.         print pattern
  10.  
  11.  
  12. >>> recurse(patt, sList)
  13. tyg
  14. tkg
  15. tlg
  16. vyg
  17. vkg
  18. vlg
Sep 17 '07 #15
kdt
50
Because you didn't provide any data to work on, I can't be sure if this is what you are after:
Expand|Select|Wrap|Line Numbers
  1. >>> tempKeys = ("key#%i" %i for i in range(8))
  2.  
  3. >>> keyDict = dict(zip(tempKeys, ("" for i in range(8))))
  4. >>> keyDict
  5. {'key#1': '', 'key#0': '', 'key#3': '', 'key#2': '', 'key#5': '', 'key#4': '', 'key#7': '', 'key#6': ''}
  6. >>> posList = [[] for i in range(8)]
  7. >>> posList
  8. >>> for i, key in enumerate(keyDict.keys()):
  9. ...     if key not in posList[i]:
  10. ...         posList[i].append(key)  # didn't make my keys as tuple
  11. ...         
  12. >>> posList
  13. [['key#1'], ['key#0'], ['key#3'], ['key#2'], ['key#5'], ['key#4'], ['key#7'], ['key#6']]
  14. >>> 
Thanks mate,

Thats definately nicer :)
Sep 17 '07 #16

Post your reply

Sign in to post your reply or Sign up for a free account.

Similar topics

reply views Thread by Bruce Davis | last post: by
11 posts views Thread by Kostatus | last post: by
9 posts views Thread by Sudesh Sawant | last post: by
117 posts views Thread by Peter Olcott | last post: by
17 posts views Thread by Jon Slaughter | last post: by
28 posts views Thread by Jon Davis | last post: by
6 posts views Thread by Ammar | last post: by
2 posts views Thread by Mike Collins | last post: by
reply views Thread by XIAOLAOHU | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.