-1

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)
joelatina
  • 1
  • 3
  • @JorgeLuis I was going to say the same thing but it gives a list of 16 tuples whereas the expected output according to the OP is 12. – ConventionalProgrammer May 08 '23 at 13:26
  • 1
    @ConventionalProgrammer Yes, I've noticed. But I thought it was an OP's mistake. I don't understad why are ignored `WWSW`, `WSWW`, `SWSS`, `SSWS`. – Jorge Luis May 08 '23 at 13:32
  • Actually that is exactly what I was looking for, I just neglected to consider a couple of outputs. That's why I wanted a program to do this for me! Thanks both of you I think we can consider this resolved. – joelatina May 08 '23 at 13:34
  • Does this answer your question? [How can I get "permutations with repetitions/replacement" from a list (Cartesian product of a list with itself)?](https://stackoverflow.com/questions/3099987/how-can-i-get-permutations-with-repetitions-replacement-from-a-list-cartesian) – Jorge Luis May 08 '23 at 14:06

1 Answers1

0

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')]
Jorge Luis
  • 813
  • 6
  • 21