Hi, the following project is the first small step in an anagram solver
that I am coding. I have four letters "a", "b", "c", "d" and the aim of the following code is to produce all possible permutations of these
letters, given that the first letter is always "a". (I have used two functions to systematically switch round the letters of the preceding list)

Put simply, I want to return the following output:

a b c d ("print LETTERS")
a c b d (first "print iterations") - produced by switching letters 2 and 3
a c d b (the next four lists are all from "print iterations" within the
a d c b while loop, the first of these four is produced by switching
a d b c letters 3 and 4 from the preceding list, and the next by
a b d c switching letters 2 and 3, and so on.

The program should then end with "Close" since the next list produced
by my code is "a", "b", "c", "d" - in other words the variable iterations
is now the same as the variable LETTERS - which should cause the while loop to stop. Unfortunately it doesn't, and I end up with an infinite loop.

Can anyone tell me why?

LETTERS = ["a", "b", "c", "d"]
print LETTERS

### FUNCTION: Main
def main():
	
	letters = ["a", "b", "c", "d"]
         
		
	iterations = replace_one_two(letters)
	print iterations

	### Continue switching letters until we arrive back at the start
	### i.e. when iterations = LETTTERS
	while iterations != LETTERS:
	
		iterations = replace_three_four(iterations)
		print iterations
		iterations = replace_one_two(iterations)
		print iterations
		
	print "Close"


###  FUNCTION: Switch letters in 2nd and 3rd position
def replace_one_two(name):

	left = name[1]
	right = name[2]

	name.remove(left)
	name.remove(right)

	name.insert(1, right)
	name.insert(2, left)
	
	return name


###  FUNCTION: Swith letters in 3rd and 4th position
def replace_three_four(name):
	
	left = name[2]
	right = name[3]
	
	name.remove(left)
	name.remove(right)
	
	name.insert(2, right)
	name.insert(3, left)
	
	return name


	
main()

This approach should work:

# 

def replace_one_two(name):
    """Switch letters in 2nd and 3rd position"""
    left = name[1]
    right = name[2]
    name.remove(left)
    name.remove(right)
    name.insert(1, right)
    name.insert(2, left)
    return name


def replace_three_four(name):
    """Switch letters in 3rd and 4th position"""
    left = name[2]
    right = name[3]
    name.remove(left)
    name.remove(right)
    name.insert(2, right)
    name.insert(3, left)
    return name

LETTERS = ["a", "b", "c", "d"]
letters = ["a", "b", "c", "d"]

while True:
    iterations = replace_three_four(letters)
    print letters
    iterations = replace_one_two(letters)
    print letters
    if letters == LETTERS:
        break

"""my output -->

['a', 'b', 'd', 'c']
['a', 'd', 'b', 'c']
['a', 'd', 'c', 'b']
['a', 'c', 'd', 'b']
['a', 'c', 'b', 'd']
['a', 'b', 'c', 'd']

"""

Sneekula, thanks for the response.

I like your way of doing it, particularly because you have dispensed with the rather messy beginning of my code, and I will be sure to make these changes.

I remain curious however about why my code doesn't work, any suggestions about this?

The standard anagram solver solution is to sort all of the letters in the words and place them in a dictionary, so to find the anagrams for "dog", you look up "dgo" in the dictionary and, it will give you 'dog' and 'god'. You don't have to mess with all possible combinations of the letters.

Sneekula, thanks for the response.

I like your way of doing it, particularly because you have dispensed with the rather messy beginning of my code, and I will be sure to make these changes.

I remain curious however about why my code doesn't work, any suggestions about this?

Because the while loop goes all the way through its code block and then checks the condition. In your case iterations would meet the condition after the 'iterations = replace_three_four(iterations)', but goes through a change in the next statement which makes it miss the exit conditions.

Sneekula just lucked out, since he didn't use the external change that your code does. His corrected code should be ...

def replace_one_two(name):
    """Switch letters in 2nd and 3rd position"""
    left = name[1]
    right = name[2]
    name.remove(left)
    name.remove(right)
    name.insert(1, right)
    name.insert(2, left)
    return name


def replace_three_four(name):
    """Switch letters in 3rd and 4th position"""
    left = name[2]
    right = name[3]
    name.remove(left)
    name.remove(right)
    name.insert(2, right)
    name.insert(3, left)
    return name

LETTERS = ["a", "b", "c", "d"]
letters = ["a", "b", "c", "d"]

while True:
    letters = replace_three_four(letters)
    print letters
    if letters == LETTERS:
        break    
    letters = replace_one_two(letters)
    print letters
    if letters == LETTERS:
        break

Edited 7 Years Ago by vegaseat: n/a

Because the while loop goes all the way through its code block and then checks the condition. In your case iterations would meet the condition after the 'iterations = replace_three_four(iterations)', but goes through a change in the next statement which makes it miss the exit conditions.

Many thanks for vegaseat, that has answered my question.

"The standard anagram solver solution is to sort all of the letters in the words and place them in a dictionary, so to find the anagrams for "dog", you look up "dgo" in the dictionary and, it will give you 'dog' and 'god'. You don't have to mess with all possible combinations of the letters."

Woooee, when I say anagram solver what I mean is a question like: You are given 9 letters, find all possible 4 letter words, 5 letter words, 6 letter words etc. I may be wrong, but I think I would need to find permutations (or at least combinations) for this type of question.

Thanks for all the help,
Paul.

hm, how about using the standard lib ? (python 2.6)

from itertools import permutations
letters = "abcd"
for p in permutations(letters):
    print ''.join(p)
""" my output --->
abcd
abdc
acbd
acdb
adbc
adcb
bacd
badc
bcad
bcda
bdac
bdca
cabd
cadb
cbad
cbda
cdab
cdba
dabc
dacb
dbac
dbca
dcab
dcba
"""

Edited 7 Years Ago by Gribouillis: n/a

hm, how about using the standard lib ? (python 2.6)

from itertools import permutations
letters = "abcd"
for p in permutations(letters):
    print ''.join(p)
""" my output --->
abcd
abdc
acbd
acdb
adbc
adcb
bacd
badc
bcad
bcda
bdac
bdca
cabd
cadb
cbad
cbda
cdab
cdba
dabc
dacb
dbac
dbca
dcab
dcba
"""

Looks like an important part of learning Python is to know what all those wonderful modules can do for you!

This question has already been answered. Start a new discussion instead.