我有一些挑战需要解决..
机器人位于4x4网格的左上角。机器人可以向上,向下,向左或向右移动,但不能两次访问同一地点。机器人正试图到达网格的右下角。
打印机器人到达目的地的唯一方式。
我试图通过检查网格中的所有可能路径并计算所有导致退出位置的路径来解决它。像建造一个有所有可能运动的树一样的东西。
(0,0)
(0,1) (1,0)
(1,1) (0,2) (1,1) (2,0)
(0,1)(1,2)(2,1) (2,1)(3,0) *** ***
*** ***
我写了一些代码......
class Robot
def self.count_possible_ways
board = Array.new(4,0) { Array.new(4,0) }
@@count = 0
find_possible_ways(board)
print_output(board)
puts "Ile razy: #{@@count}"
end
def self.find_possible_ways(board)
entry_position_yx = [0,0]
exit_position_yx = [3,3]
actual_position = entry_position_yx
board[actual_position[0]][actual_position[1]] = 1
find_possible_ways_2(board,actual_position)
end
def self.find_possible_ways_2(board,actual_position)
puts "Actual position: (#{actual_position[0]},#{actual_position[1]})"
check_possible_moves(board,actual_position)
end
def self.check_possible_moves(board,actual_position)
if actual_position[1] != 0
if board[actual_position[0]][actual_position[1]-1] == 0
board[actual_position[0]][actual_position[1]-1] = 1
actual_position = [actual_position[0],actual_position[1]-1]
if actual_position == [3,3]
@@count +=1
else
find_possible_ways_2(board,actual_position)
end
end
end
if actual_position[1] != 3
if board[actual_position[0]][actual_position[1]+1] == 0
board[actual_position[0]][actual_position[1]+1] = 1
actual_position = [actual_position[0],actual_position[1]+1]
if actual_position == [3,3]
@@count +=1
else
find_possible_ways_2(board,actual_position)
end
end
end
if actual_position[0] != 0
if board[actual_position[0]-1][actual_position[1]] == 0
board[actual_position[0]-1][actual_position[1]] = 1
actual_position = [actual_position[0]-1,actual_position[1]]
if actual_position == [3,3]
@@count +=1
else
find_possible_ways_2(board,actual_position)
end
end
end
if actual_position[0] != 3
if board[actual_position[0]+1][actual_position[1]] == 0
board[actual_position[0]+1][actual_position[1]] = 1
actual_position = [actual_position[0]+1,actual_position[1]]
if actual_position == [3,3]
@@count +=1
else
find_possible_ways_2(board,actual_position)
end
end
end
end
def self.print_output(board)
board.each do |row|
puts row.join(" ")
end
end
end
Robot.count_possible_ways
..但我的问题是....在每一步(就像路径的每个新分支)我想创建一个新的独立数组。我无法检查同一阵列上的每个可能的路径。我认为必须使用递归,但我不知道如何编码。
我不确定我是否解释得很好,但每次我的路径分成两条新路径时,我都需要创建一个新对象(数组)。
答案 0 :(得分:3)
是的,递归是可行的方法。
<强>代码强>
def paths(grid, partial_path = [[0,0]], paths = [])
return paths if grid.empty?
last_cell = partial_path.last
grid.each do |cell|
if adjacent?(last_cell,cell)
pp = partial_path + [cell]
if cell == [3,3]
paths << pp
else
paths(grid-[cell], pp, paths)
end
end
end
paths
end
def adjacent?(a,b)
ra, ca = a
rb, cb = b
((ra==rb) && (ca==cb+1 || ca==cb-1)) ||
((ca==cb) && (ra==rb+1 || ra==rb-1))
end
<强>计算强>
grid = Array.new(16) { |i| i.divmod(4) } - [[0, 0]]
#=> [[0, 1], [0, 2], [0, 3], [1, 0], [1, 1], [1, 2], [1, 3], [2, 0],
# [2, 1], [2, 2], [2, 3], [3, 0], [3, 1], [3, 2], [3, 3]]
paths(grid).size
#=> 184
paths(grid).values_at(34, 72, 138)
#=> [[[0, 0], [0, 1], [0, 2], [1, 2], [1, 1], [1, 0], [2, 0],
# [3, 0], [3, 1], [3, 2], [2, 2], [2, 3], [3, 3]],
#
# [[0, 0], [0, 1], [1, 1], [1, 2], [1, 3], [2, 3], [2, 2],
# [2, 1], [2, 0], [3, 0], [3, 1], [3, 2], [3, 3]],
#
# [[0, 0], [1, 0], [2, 0], [2, 1], [1, 1], [0, 1], [0, 2],
# [1, 2], [2, 2], [2, 3], [3, 3]]]
如果允许机器人也沿着对角线移动,请将adjacent
更改为:
def adjacent?(a,b)
((a.first-b.first).abs <= 1) && ((a.last-b.last).abs <= 1)
end
进行更改后,paths(grid).size #=> 96371
。
(105 paths not shown)
答案 1 :(得分:0)
修改强>
在它上面睡一晚;意识到,我已经监督了你问题中的“所有问题”,所以我的答案是错误的,因为你得到的只是最短的。 我不删除“答案”,因为它可能对其他人有用
虽然这听起来像'家庭作业',或者听起来像是这样,但我用一种完全不同的算法回答:
你只需要一个阵列......
由于机器人不允许“返回”,即两次使用一个点,你可以使用逻辑,用于印刷电路板设计:只需编号可能(空)邻居方块... ( - 代表空的)
第1次
1 - - -
- - - -
- - - -
- - - -
第二
1 2 - -
2 - - -
- - - -
- - - -
最后
1 2 3 4
2 3 4 5
3 4 5 6
4 5 6 7
现在从7(最高)回到较低的...... 7-6-5-4-3-2-1 ......
不是一个聪明的算法吗? (由你自己编码; - )
即便如此(S:开始,E:结束和X被阻止)......(可能是你的下一个作业)
S - - - X -
- - X - - -
- - X - - -
X X X X - X
E - - - - -
- &GT;
S 2 3 4 X 8
2 3 X 5 6 7
3 4 X 6 7 8
X X X X 8 X
E C B A 9 A