Reputation:
Is there a more elegant way to achieve this below:
Input:
array = [1, 1, 1, 0, 0, 1, 1, 1, 1, 0]
Output:
4
My algo:
streak = 0
max_streak = 0
arr.each do |n|
if n == 1
streak += 1
else
max_streak = streak if streak > max_streak
streak = 0
end
end
puts max_streak
Upvotes: 5
Views: 1930
Reputation: 2943
Edit: Another way to do this (that is less generic than Stefan's answer since you would have to flatten and split again if there was another number other than 0 and 1 in there, but easier to use in this case):
array.split(0).max.count
You can use:
array.chunk { |n| n }.select { |a| a.include?(1) }.map { |y, ys| ys.count}.max
ref: Count sequential occurrences of element in ruby array
Upvotes: 6
Reputation: 40526
You can use Enumerable#chunk
:
p array.chunk{|x| x}.select{|x, xs| x == 1}.map{|x, xs| xs.size }.max
This is more concise, but if performance was important, I'd use your approach.
Edit: If you're in Ruby 2.2.2, you can also use the new Enumerable#slice_when
method (assuming your input array consists of only 0
s and 1
s):
array.slice_when{|x,y| x < y }.map{|slice| slice.count 1 }.max
Upvotes: 5
Reputation: 2289
How about
array = [1, 1, 1, 0, 0, 1, 1, 1, 1, 0]
array.split(0).group_by(&:size).max.first
#=> 4
The only bad thing - split(0)
Note: This only works with rails's ActiveSupport(extends Array with #split)
For ruby-only implementation
array.join.split("0").group_by(&:size).max.first #=> 4
Upvotes: 0
Reputation: 114168
Similar to w0lf's answer, but skipping elements by returning nil
from chunk
:
array.chunk { |x| x == 1 || nil }.map { |_, x| x.size }.max
Upvotes: 6