def last_two_different(arr, count)
arr.reverse_each.
lazy.
chunk(&:itself).
first(count).
flat_map(&:last).
reverse
end
last_two_different [6, 4, 3, 2, 2], 2 #=> [3, 2, 2]
last_two_different [3, 4, 3, 3, 2], 2 #=> [3, 3, 2]
last_two_different [3, 4, 3, 3, 2], 3 #=> [4, 3, 3, 2]
last_two_different [3, 4, 3, 3, 2], 4 #=> [3, 4, 3, 3, 2]
last_two_different [1, 2], 2 #=> [1, 2]
last_two_different [1, 1], 2 #=> [1, 1]
last_two_different [1], 2 #=> [1]
last_two_different [], 2 #=> []
Шаги следующие.
arr = [6, 4, 3, 2, 2]
count = 2
enum0 = arr.reverse_each
#=> #<Enumerator: [6, 4, 3, 2, 2]:reverse_each>
Мы можем преобразовать этот перечислитель в массив, чтобы увидеть значения, которые он сгенерирует.
enum0.to_a
#=> [2, 2, 3, 4, 6]
Сначала предположим, что мы написали следующее.
enum1 = enum0.chunk(&:itself)
#=> #<Enumerator: #<Enumerator::Generator:0x00005c29be132b00>:each>
enum1.to_a
#=> [[2, [2, 2]], [3, [3]], [4, [4]], [6, [6]]]
Нам нужны первые count #=> 2
элементы, сгенерированные enum1
, из которых мы могли бы извлечь желаемый результат. Это говорит нам о том, что нам нужен ленивый перечислитель.
enum2 = enum0.lazy
#=> #<Enumerator::Lazy: #<Enumerator: [6, 4, 3, 2, 2]:reverse_each>>
enum3 = enum2.chunk(&:itself)
#=> #<Enumerator::Lazy: #<Enumerator:
# #<Enumerator::Generator:0x00005c29bdf48cb8>:each>>
enum3.to_a
#=> [[2, [2, 2]], [3, [3]], [4, [4]], [6, [6]]]
a = enum3.first(count)
#=> [[2, [2, 2]], [3, [3]]]
b = a.flat_map(&:last)
#=> [2, 2, 3]
b.reverse
#=> [3, 2, 2]