我有一个小小的多米诺骨牌游戏,它的工作方式是这样的:我得到了N*N
4格砖,我需要对其进行排序,以便每两个相邻的图块都具有相同的编号。磁贴可以旋转。例如,这是我的2 * 2木板:
a,b,c,d = [1,2,3,4], [7,9,6,2], [6,8,8,5], [3,5,0,0]
可以通过以下方式将其可视化:
print(print_2_tiles(a,b,'a','b'))
print(print_2_tiles(d,c,'d','c'))
##############
#**1**##**7**#
#4*A*2##2*B*9#
#**3**##**6**#
##############
##############
#**3**##**6**#
#0*D*5##5*C*8#
#**0**##**8**#
##############
可以看出,“赢得”此板的唯一方法是我订购磁贴的方法,因为<a,b>
仅通过2连接,<a,d>
仅通过3连接,依此类推。上的<a,c>,<b,d>
根本没有连接。任何瓷砖的旋转或移动都不会获得“胜利”。
我将函数编写为:
但是,这只是16 * 12 * 8选项的简单情况,由于存在唯一的连接器(例如,连接<a,c>
的'2'在其他图块中不存在),因此我可以排除很多选项。如果我得到更大的面板(更大的字母也可能使事情复杂化... ),例如5 * 5,则选项的数量将为100 * 96 * 92 ...并且蛮力将不切。
我如何才能有效地找到正确的订单(保证董事会有一个正确的订单)?
这是我的努力:
import numpy as np
from itertools import combinations, product
# returns list of [<connector element>, <indices of element in a>, <indices of element in b>]
def find_connections(a,b):
intersected_elem = np.array(list(set(a).intersection(b)))
possible_connections = []
for val in intersected_elem:
x = list(np.where(np.array(a) == val)[0])
y = list(np.where(np.array(b) == val)[0])
possible_connections.append([val,x,y])
return possible_connections
def str_tile(t, name):
template = '''#######
#**{}**#
#{}*{}*{}#
#**{}**#
#######'''
up,right,down,left = t
return template.format(up,left,name.upper(),right,down)
def print_2_tiles(a,b, name_a, name_b):
res = ''
for line in zip(str_tile(a,name_a).splitlines(), str_tile(b,name_b).splitlines()):
res += ''.join(line)
res += '\n'
return res[:-1]
def find_final_connections(tiles_ls):
tiles_combinations = list(combinations(tiles_ls, 2))
a_idx,b_idx = 0,1
final_connections = []
for comb in tiles_combinations:
connections = find_connections(comb[0], comb[1])
print('({},{})'.format(a_idx,b_idx), connections, end='\t')
if len(connections):
print('this meants {},{} are connected via {} in directions {},{}'.format(a_idx,b_idx, connections[0][0], connections[0][1][0], connections[0][2][0]))
final_connections.append((a_idx,b_idx))
else:
print()
# is there a neater way, using enumerate on itertools.combinations?
b_idx += 1
if b_idx == len(tiles_ls):
a_idx += 1
b_idx = a_idx + 1
print(final_connections)
a,b,c,d = [1,2,3,4], [7,9,6,2], [6,8,8,5], [3,5,0,0]
tiles_ls = [a,b,c,d]
find_final_connections(tiles_ls) # returns a 4-elem list -> success
print('#'*30)
a,b,c,d = [1,2,3,4], [7,9,6,2], [6,8,8,5], [0,5,0,0]
tiles_ls = [a,b,c,d]
find_final_connections(tiles_ls) # returns a 3-elem list -> fail
答案 0 :(得分:0)
是否确定暴力破解无法做到?
我会尝试一种系统的解决方案,您依次选择每个多米诺骨牌并将其放在左上角,尝试所有四个旋转。然后选择另一个多米诺骨牌并将其放置在第二个位置,尝试所有四个旋转,并检查是否与第一个匹配。
依此类推,在任何阶段,您都可以从其余的多米诺骨牌中挑选一个多米诺骨牌,尝试四轮旋转并检查与已知邻居的兼容性。
最好将其写为递归过程。