我會做到以下幾點。
def circular_dependencies?(arr)
(2..arr.size).any? { |n| arr.combination(n).any? { |comb| is_cycle?(comb) } }
end
def is_cycle?(comb)
a = comb.flat_map { |s| s.split /\s+=>\s+/ }.rotate
a.each_slice(2).all? { |l,f| l==f }
end
arr = ["a =>", "b => c", "c => f", "d => a", "e =>", "f => b"]
circular_dependencies?(arr)
#=> true
arr = ["a =>", "b => c", "c => f", "d => a", "e =>", "f => a"]
circular_dependencies?(arr)
#=> false
當
arr = ["a =>", "b => c", "c => f", "d => a", "e =>", "f => b"]
和n = 3
enum = arr.combination(n)
#=> #<Enumerator: ["a =>", "b => c", "c => f", "d => a", "e =>",
# "f => a"]:combination(3)>
我們可以將此枚舉轉換成數組,以查看將要傳遞給它的元素是塊:
enum.to_a
#=> [["a =>", "b => c", "c => f"],
# ["a =>", "b => c", "d => a"],
# ["a =>", "b => c", "e =>"],
# ["a =>", "b => c", "f => b"],
# ["a =>", "c => f", "d => a"],
# ["a =>", "c => f", "e =>"],
# ["a =>", "c => f", "f => b"],
# ["a =>", "d => a", "e =>"],
# ["a =>", "d => a", "f => b"],
# ["a =>", "e =>", "f => b"],
# ["b => c", "c => f", "d => a"],
# ["b => c", "c => f", "e =>"],
# ** ["b => c", "c => f", "f => b"],
# ["b => c", "d => a", "e =>"],
# ["b => c", "d => a", "f => b"],
# ["b => c", "e =>", "f => b"],
# ["c => f", "d => a", "e =>"],
# ["c => f", "d => a", "f => b"],
# ["c => f", "e =>", "f => b"],
# ["d => a", "e =>", "f => b"]]
W母雞組合
comb = ["b => c", "c => f", "f => b"]
傳遞給is_comb?
我們計算
a = comb.flat_map { |s| s.split /\s+=>\s+/ }
#=> ["b", "c", "c", "f", "f", "b"]
b = a.rotate
#=> ["c", "c", "f", "f", "b", "b"]
enum = a.each_slice(2)
#=> #<Enumerator: ["c", "c", "f", "f", "b", "b"]:each_slice(2)>
enum.to_a
#=> [["c", "c"], ["f", "f"], ["b", "b"]]
enum.all? { |l,f| l==f }
#=> true
在技術方面,你想檢測有向圖中的循環。這裏有很多很好的討論:http://stackoverflow.com/questions/261573/best-algorithm-for-detecting-cycles-in-a-directed-graph,當然還有Google。 –
問題不是很清楚。除了'「=>」',''=>「'和'」=>「'以外,還有哪些用於劃分兩個節點的子字符串?或者,您是否需要首先使用這種人造格式來陳述您的問題?難道不能像'[[a,nil],[「b」,「c」],[「c」,「f」],...]'? – sawa