JasonMattingly
JasonMattingly

Reputation: 110

Loop isn't recording all solutions into an array

This loop searches through the stock_picker variable and determines which two days would be the best "buy" and "sell" days by checking for which two days would net the most profit. The loop correctly sees that my greatest profit would be 8 by buying on day zero and selling on day one.

However, I want the program to record ALL possible best buy and sell dates into an array. My profit would still be 8 if I bought on day 0 and sold on day 3, but the program does not record this. Instead it returns an array of [0,1,0,1] which tells me it sees the two solutions, but is for some reason not recording the second one. How can I return an array of [0,1,0,3]?

def stock_picker(prices)
  buy_and_sell_days = []

  best_profit = 0

  prices.each do |low|
    prices.each do |high|
      if prices.index(high) > prices.index(low)
        profit = high - low
        if profit > best_profit
          best_profit = profit
        end
        if high - low == best_profit
          buy_and_sell_days.push(prices.index(low), prices.index(high))
        end
      end
    end
  end

  p buy_and_sell_days
  p best_profit

end

stock_picker([1, 9, 2, 9])

(edited for format/legibility)

Upvotes: 0

Views: 56

Answers (1)

Nick Veys
Nick Veys

Reputation: 23939

The index method:

Returns the index of the first object in ary such that the object is == to obj.

So: prices.index(1) is 0 and prices.index(9) is 1

If you use the index method, there's not enough information for it to know to pick the second one over the first one, so you get [0, 1, 0, 1].

You could pass the index along with it so you can avoid this altogether. You could also store all possible profits and dates, and then grab the maximum when you're done. Easier! Here's both:

def stock_picker(prices)
  buy_and_sell_days = []
  buy_and_sell_days2 = {}

  best_profit = 0

  prices.each_with_index do |low, lidx|
    prices.each_with_index do |high, hidx|
      if hidx > lidx
        buy_and_sell_days2[high - low] ||= []
        buy_and_sell_days2[high - low] << [lidx, hidx]
        profit = high - low
        if profit > best_profit
          best_profit = profit
        end
        if high - low == best_profit
          buy_and_sell_days.push(lidx, hidx)
        end
      end
    end
  end

  p buy_and_sell_days
  p buy_and_sell_days2
  p buy_and_sell_days2.max_by { |profit, pairs| profit }
  p best_profit
end

stock_picker([1,9,2,9])
#> [0, 1, 0, 3]
#> {8=>[[0, 1], [0, 3]], 1=>[[0, 2]], -7=>[[1, 2]], 0=>[[1, 3]], 7=>[[2, 3]]}
#> [8, [[0, 1], [0, 3]]]
#> 8

Upvotes: 1

Related Questions