如何移动和合并矩阵的元素以获得以下结果?
向右移动:
[[0,0,2,2,0,2],[8,4,2,2,0,2]]
==> [[0,0,0,0,4,2],[0,0,8,4,4,2]]
或
向左移动:
[[0,0,2,2,0,2],[8,4,2,2,0,2]]
==> [[4,2,0,0,0,0],[8,4,4,2,0,0]]
它就像2048游戏。例如,当用户进行左移时,每个数字都在列表的左侧,如果并排的2个数字相等,则tere是两个数字的相加。
我想用循环来做。
我尝试了一些我在互联网上找到的代码,但作为一个初学者,我没有找到一个简单的代码来理解如何做到这一点。
提前感谢您的帮助。
答案 0 :(得分:1)
如果我没有误解你的意思,我会写一些代码,希望这会有所帮助:
a = [[0, 0, 2, 2, 0, 2], [8, 4, 2, 2, 0, 2]]
f = lambda x: [2 * x[0]] if x[0] == x[1] else x
def move_left(l):
c, l = [], l + [0] if len(l) % 2 else l
for i in range(0, len(l), 2):
c = c + f(l[i:i + 2])
c = list(filter(lambda x: x != 0, c))
return c + ([0] * (len(l) - len(c)))
def move_right(l):
c, l = [], l + [0] if len(l) % 2 else l
for i in range(len(l), 0, -2):
c = f(l[i - 2:i]) + c
c = list(filter(lambda x: x != 0, c))
return ([0] * (len(l) - len(c))) + c
for i in a:
print(move_left(i))
输出:
[4, 2, 0, 0, 0, 0]
[8, 4, 4, 2, 0, 0]
您似乎正在使用 Python3.x ,因此您应该使用list(filter(lambda x: x != 0, c))
来获取列表。
答案 1 :(得分:0)
以下是将元素移动到右侧的示例:
def move_right(matrix):
for row in matrix:
for i, number in reversed(list(enumerate(row))):
if number == row[i-1]:
row[i] = number + row[i-1]
row[i-1] = 0
row.sort(key=lambda v: v != 0)
return matrix
然后做:
matrix = [[0,0,2,2,0,2],[8,4,2,2,0,2]]
print(move_right(matrix))
输出:
[[0, 0, 0, 0, 4, 2], [0, 0, 8, 4, 4, 2]]
工作原理:
row = [0, 0, 2, 2, 0, 2]
然后我们使用enumerate()函数检查该行中的数字的循环。然后我们应用reversed()来向后遍历列表,以便在一个回合中不将先前的和与另一个元素组合。
e.g: [4,4,8] => [0, 8, 8] => [0, 0, 16]. This should actually equal [0, 0, 8]
对于当前行,这将输出结果:
i number
5 2
4 0
3 2
2 2
1 0
0 0
然后我们使用索引(i)来引用列表中的前一个数字。例如在索引2处。当前数字是2,而前一个数字(i-1)是2.因为它们等于'如果'声明将执行。
然后将当前元素分配给自身和前一个元素的总和。 row[i] = number + row[i-1]
前一个数字将变为0,与当前数字合并。 row[i-1] = 0
在我们遍历每个号码后,该行将为:[0, 0, 0, 4, 0, 2]
。然后对代码row.sort(key=lambda v: v != 0)
进行排序,以便将零推到左侧。有关详细信息,请参阅here。
当向左移动元素而不是向右移动元素时,需要将其更改为row.sort(key=lambda v: v != 0, reverse=True)
以将零推向另一个方向。