.
def longest_path(arr)
return nil if arr.empty?
h = { len: arr.first.first, path: [] }
return h if arr.size == 1
arr[1..-1].reduce([h]) do |l,row|
h = l.first
left = { len: h[:len]+row.first, path: h[:path]+[:l] }
mid = l.each_cons(2).to_a.zip(row[1..-2]).map do |(h1,h2),v|
if h1[:len] >= h2[:len]
{ len: h1[:len]+v, path: h1[:path]+[:r] }
else
{ len: h2[:len]+v, path: h2[:path]+[:l] }
end
end
h = l.last
right = { len: h[:len]+row.last, path: h[:path]+[:r] }
[left, *mid, right]
end.max_by { |h| h[:len] }
end
a = [ [3],
[7,4],
[2,4,6],
[8,5,9,3]]
longest_path a
#=> {:len=>23, :path=>[:l, :r, :r]}
, 23. 3 (:l) 7 (:r) 4 9 : 3+7+4+9 => 23.
, . , : , ..
a .
arr = a
arr.empty?
h = { len: arr.first.first, path: [] }
return h if arr.size == 1
As
arr[1..-1] => [[7, 4], [2, 4, 6], [8, 5, 9, 3]]
reduce [h] [7, 4] -:
l = [{ len: arr.first.first, path: [] }]
row = [7, 4]
:
h = l.first
left = { len: h[:len]+row.first, path: h[:path]+[:l] }
mid = []
h = l.last
right = { len: h[:len]+row.last, path: h[:path]+[:r] }
[left, *mid, right]
mid => [], each_cons(2) 1.
. (7) 10 (3), "" (:l) .
[left, *mid, right] reduce, l arr:
l = [{:len=>10, :path=>[:l]}, {:len=>7, :path=>[:r]}]
row = [2, 4, 6]
:
left = { len: h[:len]+row.first, path: h[:path]+[:l] }
l.each_cons(2).to_a.zip(row[1..-2]).map do |(h1,h2),v|
if h1[:len] >= h2[:len]
{ len: h1[:len]+v, path: h1[:path]+[:r] }
else
{ len: h2[:len]+v, path: h2[:path]+[:l] }
end
end
h = l.last
right = { len: h[:len]+row.last, path: h[:path]+[:r] }
[left, *mid, right]
left right arr. mid:
pairs = l.each_cons(2).to_a
vals = pairs.zip(row[1..-2])
vals - , . map, :
h1 = {:len=>10, :path=>[:l]}
h2 = {:len=> 7, :path=>[:r]}
v = 4
h1[:len]
h2[:len]
10 > 7, :
{ len: h1[:len]+v, path: h1[:path]+[:r] }
mid. l reduce [left, *mid, right]:
l = [{:len=> 5, :path=>[:l]}, {:len=>14, :path=>[:l, :r]},
{:len=>13, :path=>[:r, :r]}]
. reduce :
d = [{:len=>20, :path=>[:l, :l, :l]}, {:len=>19, :path=>[:l, :r, :l]},
{:len=>23, :path=>[:l, :r, :r]}, {:len=>16, :path=>[:r, :r, :r]}]
, . :
d.max_by { |h| h[:len] }