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!

asked Nov 9, 2015 at 22:21

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.

answered Nov 9, 2015 at 22:40
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.

answered Nov 9, 2015 at 22:25

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)
answered Nov 9, 2015 at 22:30

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-']
answered Nov 9, 2015 at 22:36

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.

answered Nov 9, 2015 at 22:39

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_']
answered Nov 9, 2015 at 22:52

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)
answered Nov 9, 2015 at 22:28

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

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.