0

i need some help to solve my problem with python. My task is to generate 4 Elements of my list "stones", which i want to put in my List "L". The letters are colours and +,-,.. are forms and i'm allowed to just use every colour and form one time in my 4 Elements, which is why i struggle with this task. my code so far:

L = []
stones = ["R+", "R-", "R*", "R_", "G+", "G-", "G*", "G_", "B+",  "B-", "B*", "B_", "W+", "W-", "W*", "W_"]
stone1 = random.choice(stones) 
L.append(stone1)
stones.remove(stone1)
#if stone1[1] in stones:
#del stones

as you can hopefully see, i get a random value of "stones" and can put it in my list L and i delete it out of the stones list. The problem now is that i dont know how to compare stone1 to the other stones.elements. f.e. if i get stone1=R+, i want to delete all items in "stones" which include R and +. The last 2 lines are garbage, so don't worry.. Thanks for your help!

7 Answers 7

3

Since you can have one of each color and form, just shuffle them separately. There is no need to have a starting list of every combination:

def get_stones():
    colors = list('RGBW')
    forms = list('+-*_')
    random.shuffle(colors)
    random.shuffle(forms)
    return [c+f for c,f in zip(colors,forms)]

for i in range(5):
    print(get_stones())

Output:

['B*', 'R-', 'W_', 'G+']
['W*', 'R+', 'G_', 'B-']
['B+', 'R_', 'G-', 'W*']
['B+', 'G*', 'W-', 'R_']
['G_', 'B-', 'W*', 'R+']

Note: If order doesn't matter you can drop one of the shuffles.

Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for your idea! I'm new to programming, so that's why i couldn't figure out, that it's like that easy. Again learnt something new :-)
Golf'd ftw: print [a+b for a,b in zip(*map(lambda l:random.shuffle(l)or l, [list('RGBW'),list('+-*_')]))]
@smassey, nice trick with the or, but yuck for clarity :^) Too bad there isn't a shuffled like sort vs. sorted.
@MarkTolonen no doubt! Code golfing is about tweetability, not readability ;) +1 for a std shuffled()
0

If you get your stone, I'd split it in

color = stone1[0]
form = stone1[1]

and then iterate through your stone list and eliminate every stone which contains either coloror form. Continue until len(L) = 4 and you're done.

Comments

0

You can do it like:

import random
L = []
stones = ["R+", "R-", "R*", "R_", "G+", "G-", "G*", "G_", "B+",  "B-", "B*", "B_", "W+", "W-", "W*", "W_"]
stone1 = random.choice(stones) 
L.append(stone1)
for character in stone1:
    copy_stones=stones[:]  # You need to make a copy, if not the for fails
    for stone in copy_stones:
        if character in stone:
            stones.remove(stone)

Comments

0
>>> L = []
>>> stones = ["R+", "R-", "R*", "R_", "G+", "G-", "G*", "G_", "B+",  "B-", "B*", "B_", "W+", "W-", "W*", "W_"]
>>> while stones: #continue until stones is empty since empty lists return False
       stone1 = stones.pop(random.randrange(len(stones))) #pop returns and removes an item from a list
       L.append(stone1)
       stones = [stone for stone in stones if stone1[0] not in stone and stone1[1] not in stone] #list comp that only copies values if neither characters are in the item


>>> L
['W_', 'R+', 'G*', 'B-']

Comments

0
stones = filter(lambda x: stone1[0] not in x and stone1[1] not in x, stones)

Tweak the conditional in the filter above to fit your need.

Comments

0
from itertools import product
from random import sample

# Define your colours and forms (easy to add more later)
colours = ['R', 'G', 'B', 'W']
forms = ['+', '-', '*', '_']

# Combine the colours and forms to show all combinations
possible_stones = [''.join(stone) for stone in product(colours, forms)]
print possible_stones
>>> ['R+', 'R-', 'R*', 'R_', 'G+', 'G-', 'G*', 'G_', 'B+', 'B-', 'B*', 'B_', 'W+', 'W-', 'W*', 'W_']

# Get a random sample of the forms and colours and then combine them
stones = zip(sample(colours, len(colours)), sample(forms, len(forms)))
print [''.join(stone) for stone in stones]
>>> ['B+', 'G*', 'R-', 'W_']

Comments

0

You saved the value to compare as stone1.

You could separate into two strings where string1 is the first character and string2 is the second character. Then use 1 loop and compare each item to the two strings/characters you're interested on ("R", +" in your example), and for each match remove the item from the list.

Also, use the least number of comparisons needed and one loop/pass. For example, if you found a match, then remove item and continue with the loop avoiding a second comparison.

L = []
stones = ["R+", "R-", "R*", "R_", "G+", "G-", "G*", "G_", "B+",  "B-", "B*",    "B_", "W+", "W-", "W*", "W_"]
stone1 = random.choice(stones) 
L.append(stone1)
stones.remove(stone1)

foo1 = stone1[0]
foo2 = stone1[1]      

for x in stones:
  if x.startswith(foo1):
    stones.remove(x)
  elif x.endswith(foo2):
    stones.remove(x)

2 Comments

thanks so much! but in my implementation, it does not remove all kind of wrong stones. it seems, that after every run, there is still one similar color and form in "stones". but i guess i fixed it now with another solution of this thread!
You were right. I fixed the comparisons. It works now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.