What I'm trying to do is to take a list like this:
['WS','SB'...]
And write a python program that will produce an output like this for each string in the list:
['WWWW','WWWS','WWSS','WSSS','SSSS','SSSW','SSWW','SWWW','WSSW','SWWS','WSWS,'SWSW']
Essentially, I want all possible 4-character strings that can be written with those 2 characters. The order of the characters in the input doesn't really matter, but the order in the output does. These strings are meant to represent a 2x2 grid in which each quadrant is tagged with one of the two characters.
I do NOT want the output strings to include combinations of characters that do not exist as a single item in the input. So, in this example I would not want 'WWBB' as an output, B should only be paired with itself or S.
I also do NOT want output strings of a length shorter than 4, so 'WWW' should not be included in the output.
My program is in python so I have attempted to use several different methods from itertools to do this including combinations, permutations, and combinations_with_replacement. I have also tried formatting the inputs as lists, sets, and tuples but have not been successful.
Of these, combinations_with_replacement has come the closest to producing my desired output. However, none of these methods has returned all of the possible combinations as I have laid them out above. Specifically, these strings are being excluded from the outputs for all of these methods:
'WSSW','SWWS','WSWS,'SWSW'
Here is my best attempt at this. Note that for the input I ended up listing 'WS' and 'SW' as separate items to ensure that I got combinations in both directions, but in reality these two inputs should mean the same thing and the program should return all possible 4-character strings regardless of the order of the characters in the input.
import itertools
# define all texture pairs that can be in the same tile
texture_pairs = ['WS','SW','SB','BS','GW','WG','Gb','bG','gB','Bg']
tilesets = []
#determine all possible tiles for each texture pair & create a string in the form 'TTTT' representing the texture for each of the 4 tile quadrants, clockwise from the top left quadrant
def generate_tileset(texture_pair):
return list(itertools.combinations_with_replacement(texture_pair,4))
for texture_pair in texture_pairs:
tileset = generate_tileset(texture_pair)
tilesets.append(tileset)
print(tileset)
If you use itertools.product
, the output gives all of the possible combinations:
import itertools
# Define all texture pairs that can be in the same tile
texture_pairs = ['WS','SW'] # Deleted some of the pairs.
tilesets = []
# Determine all possible tiles for each texture pair
# and create a string in the form 'TTTT' representing the texture
# for each of the 4 tile quadrants, clockwise from the top left quadrant
def generate_tileset(texture_pair):
return list(itertools.product(texture_pair, repeat=4))
for texture_pair in texture_pairs:
tileset = generate_tileset(texture_pair)
tilesets.append(tileset)
print(tileset)
This yields:
[('W', 'W', 'W', 'W'), ('W', 'W', 'W', 'S'), ('W', 'W', 'S', 'W'), ('W', 'W', 'S', 'S'), ('W', 'S', 'W', 'W'), ('W', 'S', 'W', 'S'), ('W', 'S', 'S', 'W'), ('W', 'S', 'S', 'S'), ('S', 'W', 'W', 'W'), ('S', 'W', 'W', 'S'), ('S', 'W', 'S', 'W'), ('S', 'W', 'S', 'S'), ('S', 'S', 'W', 'W'), ('S', 'S', 'W', 'S'), ('S', 'S', 'S', 'W'), ('S', 'S', 'S', 'S')]
[('S', 'S', 'S', 'S'), ('S', 'S', 'S', 'W'), ('S', 'S', 'W', 'S'), ('S', 'S', 'W', 'W'), ('S', 'W', 'S', 'S'), ('S', 'W', 'S', 'W'), ('S', 'W', 'W', 'S'), ('S', 'W', 'W', 'W'), ('W', 'S', 'S', 'S'), ('W', 'S', 'S', 'W'), ('W', 'S', 'W', 'S'), ('W', 'S', 'W', 'W'), ('W', 'W', 'S', 'S'), ('W', 'W', 'S', 'W'), ('W', 'W', 'W', 'S'), ('W', 'W', 'W', 'W')]