Я пытаюсь сделать метод выбора акций на Ruby, но у меня есть некоторые проблемы в моем коде - PullRequest
1 голос
/ 24 марта 2019

Я пытаюсь сделать метод выбора акций, который принимает массив цен на акции, по одному на каждый гипотетический день. Он должен возвращать пару дней, представляющих лучший день для покупки и лучший день для продажи. Дни начинаются с 0.

def stock_picker stocks
  pair = []

  if stocks.size < 2
    return "Please enter an array with a valid number of stocks"
  else
    buy_day = 0
    sell_day = 0
    profit = 0

    stocks.each_with_index do |buy, index|
      i = index
      while (i < stocks[index..-1].size)
        if ((buy - stocks[i]) > profit)
          profit = buy - stocks[i]
          buy_day = stocks.index(buy)
          sell_day = i
        end
        i+= 1
      end

    end
    pair = [buy_day,sell_day]
    return pair.inspect
  end
end

stock_picker([17,3,6,9,15,8,6,1,10])

Возвращается [1,4] вместо [0,7]

Ответы [ 2 ]

0 голосов
/ 24 марта 2019

Другой вариант - нарезать массив, перебирая его для нахождения наилучшей прибыли:

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] вернет индекс последнего [..]

Итак, возможно, вы захотите использовать первый вариант, чтобы сократить время между покупкой и продажей.

0 голосов
/ 24 марта 2019

Использование Array#combination:

stocks.
    each_with_index.
    to_a.
    combination(2).
    select { |(_, idx1), (_, idx2)| idx2 > idx1 }.
    reduce([-1, [-1, -1]]) do |(val, acc), ((v1, idx1), (v2, idx2))|
  val < v2 - v1 ? [v2 - v1, [idx1, idx2]] : [val, acc]
end
#⇒ [ 12, [1, 4] ]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...