Хорошо, извините, я так и не смог четко объяснить проблему, но вот решение.
Нам нужны две функции combinations
и runvector(v)
.combinations(s,k)
генерирует уникальные комбинации мультимножества длины k
.Для s='xxyy'
это будет ['xx','xy','yy']
.runvector(v)
преобразует мультимножество, представленное в виде отсортированного вектора, в более простую структуру - вектор выполнения.runvector('cddeee')=[1,2,3]
.
Для решения проблемы мы будем использовать рекурсивные генераторы.Мы проходим через все комбинации, которые вписываются в box1 и обращаемся к остальным блокам, забаняя значения, которые мы уже выбрали.Чтобы выполнить запрет, combinations
будет поддерживать битовый массив вызовов.
В python подход выглядит следующим образом:
def fillrest(banned,out,rv,b,i):
if i == len(rv):
yield None
return
for comb in combinations(b,rv[i],banned):
out[i] = comb
for rest in fillrest(banned,out,rv,b,i+1):
yield None
def balls(a,b):
rv = runvector(a)
banned = [False for _ in b]
out = [None for _ in rv]
for _ in fill(out,rv,0,b,banned):
yield out[:]
>>> print list(balls('abbccc','xyyzzz'))
[['x', 'yy', 'zzz'],
['x', 'yz', 'yzz'],
['x', 'zz', 'yyz'],
['y', 'xy', 'zzz'],
['y', 'xz', 'yzz'],
['y', 'yz', 'xzz'],
['y', 'zz', 'xyz'],
['z', 'xy', 'yzz'],
['z', 'xz', 'yyz'],
['z', 'yy', 'xzz'],
['z', 'yz', 'xyz'],
['z', 'zz', 'xyy']]
Вывод в формате 'box', но можетлегко объединить в простые строки: 'xyyzzzz'
, 'xyzyzz'
...