Другой вариант - нарезать массив, перебирая его для нахождения наилучшей прибыли:
res = ary.each_with_index.with_object([]) do |(buy_val, i), res|
highest_val = ary[i..].max
highest_idx = ary[i..].each_with_index.max[1] + i
res << [highest_val - buy_val, i, highest_idx]
end.max_by(&:first)
#=> [12, 1, 4]
Где 12
- прибыль, 1
- индекс покупки, а 4
- индекс продажи.
Чтобы понять, как это работает, запустите эту расширенную версию, это стоит больше, чем любое письменное объяснение:
res = []
ary.each_with_index do |buy_val, i|
p buy_val
p ary[i..]
p highest_val = ary[i..].max
p highest_idx = ary[i..].each_with_index.max[1] + i
res << [highest_val - buy_val, i, highest_idx]
p '----'
end
res #=> [[0, 0, 0], [12, 1, 4], [9, 2, 4], [6, 3, 4], [0, 4, 4], [2, 5, 8], [4, 6, 8], [9, 7, 8], [0, 8, 8]]
Из стандартной библиотеки Ruby я использовал Enumerable # each_with_index , Enumerable # each_with_object , Enumerable # max и Enumerable # max_by .
Для получения индекса максимума я любезно украл у Чака (
https://stackoverflow.com/a/2149874), спасибо и +1. Я не искал лучшего варианта.
Согласно комментарию Кэри Свовеланд в связанном сообщении:
[..] a.index(a.max)
вернет индекс первого и
a.each_with_index.max[1]
вернет индекс последнего [..]
Итак, возможно, вы захотите использовать первый вариант, чтобы сократить время между покупкой и продажей.