Ruby 打印过程中的一个递归回溯问题
我被分配到学校的以下任务: 您得到了一个由一行正方形组成的拼图,每个正方形包含一个整数,如下所示: 6,4,1,3,3,1,4,1,1,0 初始方块上的粗体数字是一个标记,可以沿行移动到其他方块。 在拼图的每一步中,您都可以将标记移动到当前所占方格中整数表示的方格数。 标记可以沿行向左或向右移动,但不能超过任意一端。 拼图的目标是将标记移动到行远端的0 程序将检查您当前所在的索引,并根据数组中该索引处的整数向左或向右移动若干个正方形。它根据数组的边界来决定,如果它不能向左移动所需数量的正方形,它将向右移动,反之亦然。 在这个程序中,第一步必须向右移动6,因为它不能在不越界的情况下向左移动6个空格。然后,它必须向左移动4,因为它不能向右移动4,它继续这样 我已经得到了这项工作,印刷过程值得额外的信贷。我让它打印流程,但它出故障了 这是我的密码:Ruby 打印过程中的一个递归回溯问题,ruby,recursion,recursive-backtracking,Ruby,Recursion,Recursive Backtracking,我被分配到学校的以下任务: 您得到了一个由一行正方形组成的拼图,每个正方形包含一个整数,如下所示: 6,4,1,3,3,1,4,1,1,0 初始方块上的粗体数字是一个标记,可以沿行移动到其他方块。 在拼图的每一步中,您都可以将标记移动到当前所占方格中整数表示的方格数。 标记可以沿行向左或向右移动,但不能超过任意一端。 拼图的目标是将标记移动到行远端的0 程序将检查您当前所在的索引,并根据数组中该索引处的整数向左或向右移动若干个正方形。它根据数组的边界来决定,如果它不能向左移动所需数量的正方形,它
def self.solvable(start, board)
return false if start>= board.length || start<0
return false if @@infinite[start] == -1
return true if board[start] == 0
@@infinite[start] = -1
if solvable(board[start] + start, board)
puts "Shifted right " + board[start].to_s + " spaces, from index " + start.to_s + " to index " + (board[start] + start).to_s
return true
else
puts "Shifted left " + board[start].to_s + " spaces, from index " + start.to_s + " to index " + (start - board[start]).to_s
end
return solvable(start - board[start], board)
end
print "Enter an array of numbers: "
input = gets.chomp!
board = input.each_char.map(&:to_i)
@@infinite = input.each_char.map(&:to_i)
puts solvable(0, board)
def自身可解性(启动、板)
如果开始>=board.length|start假设,则返回false
我假设游戏开始于位置0
。每次移动都会增加或减少位置的整数。目标是在第一次移动后回到位置0
我们得到了一个整数数组,arr
,以及从数组的位置到索引的映射。对于位置p
而言,arr
的索引由p%arr.size
给出
如果我们处于位置p
,我们获得的值可能会移动到位置p+n
或p-n
,其中
n = arr[p % arr.size]
对于给出的示例:
arr = [6, 4, 1, 3, 3, 1, 4, 1, 1, 0]
(arr.size#=>10
)和p
最初为零
n = arr[0 % 10]
#=> arr[0] => 6
所以我们可以移动到+6或-6位置。如果我们移动到+6,我们计算
n = arr[6 % 10]
#=> 4
n = arr[-6 % 10]
#=> 3
因此,我们可以移动到位置6+4#=>10
或6-4#=>2
。如果我们移到-6,我们计算
n = arr[6 % 10]
#=> 4
n = arr[-6 % 10]
#=> 3
因此,我们可以移动到位置-6-3
或-6+3=>-3
注意,arr[9]#=>0
可以被视为吸收状态
代码
我选择使用的方法是递归的
def onward_to_zero(arr, pos=0)
n = arr[pos % arr.size]
return [] if n.zero?
return [-n] if (pos-n).zero?
return [n] if (pos+n).zero?
if rand < 0.5
rv = onward_to_zero(arr, pos-n)
return [-n] + rv unless rv.empty?
rv = onward_to_zero(arr, pos+n)
return [n] + rv unless rv.empty?
else
rv = onward_to_zero(arr, pos+n)
return [n] + rv unless rv.empty?
rv = onward_to_zero(arr, pos-n)
return [-n] + rv unless rv.empty?
end
[]
end
讨论
<注意>代码>如果Rand<0.5 使我考虑在大约一半的时间内增加位置之前减少位置。如果我总是在增加之前考虑减少,反之亦然,我可以很容易地得到堆栈级别太深的错误。
然而,即使使用这种概率机制,该方法也会给出各种各样的结果,并且仍然可能导致堆栈级别的错误太深。下面是我通过运行第一个示例10次得到的结果
[6, -4, 1, -3]
[-6, 3, 1, -1, -1, 4]
[6, 4, 6, 4, 6, 4, 6, 4, 6,..., -1, -1, 4] (824 elements)
[6, 4, -6, -3, 4, 1, -4, -1,..., -4, 1, -3] (386 elements)
[-6, 3, 1, -1, -1, 4]
[-6, -3, 4, 1, 4]
[-6, 3, 1, -1, 1, -1, -1, 4]
[-6, -3, -4, -1, -4, 1, -3, 6, 4, 6, 4]
[-6, -3, -4, 1, -1, -1, -4, -1, 4, 1, 4, 6, 4]
[-6, 3, -1, 4]
不完全清楚。如何决定移动哪一边?此外,无法运行您的代码,请更新并通过粘贴使其正常工作。这将增加有人帮助的可能性。我非常怀疑你的作业是数字序列6,4,1,3,3,1,4,1,1,0
而不是别的,甚至不是问题。你必须先陈述你的问题,而不是希望读者能通过研究你的代码来解决问题,这是对读者时间的浪费,而且考虑到你的代码是错误的,可能无论如何都不会起作用。最好的办法是编辑您的问题,并将您收到的实际问题一字不差地剪切粘贴到答案的开头。@Stefan,据我所知,您的意思是,如果arr
是给定的数组,在移动+6、+4之后,将您带到索引10,索引10处的值是arr[10%10]#=>arr[0]=>6
?索引-6处的值是arr[-6%10]#=>arr[4]=>3
。对的这就解释了结尾处神秘的0,它显然可以被视为一种吸收状态。@Stefan,我被索引1和索引6都有一个4这一事实吓坏了,但主要原因是,我急于找到解决方案,没有仔细阅读这个问题。然而,我并不为此道歉,因为这种一贯的行为导致我在过去能够处理许多有趣的问题,这些问题通常比实际问题更有趣。此外,没有造成任何伤害,因为你总是在那里纠正我,导致我修改我原来的答案。如果你不打算回来查看答案,为什么要问一个问题?
arr = [7, 26, 33, 18, 7, 13]
onward_to_zero(arr)
#=> [-7, -13, 7, 13]
# pos-> -7 -20 -13 0
[6, -4, 1, -3]
[-6, 3, 1, -1, -1, 4]
[6, 4, 6, 4, 6, 4, 6, 4, 6,..., -1, -1, 4] (824 elements)
[6, 4, -6, -3, 4, 1, -4, -1,..., -4, 1, -3] (386 elements)
[-6, 3, 1, -1, -1, 4]
[-6, -3, 4, 1, 4]
[-6, 3, 1, -1, 1, -1, -1, 4]
[-6, -3, -4, -1, -4, 1, -3, 6, 4, 6, 4]
[-6, -3, -4, 1, -1, -1, -4, -1, 4, 1, 4, 6, 4]
[-6, 3, -1, 4]