Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get max consecutive occurrences of value in array

Tags:

arrays

ruby

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
like image 597
Damien Roche Avatar asked Apr 17 '15 13:04

Damien Roche


People also ask

How do you find maximum consecutive numbers in an array?

The idea is to use hashing. We traverse through the array and for every element, we check if it is the starting element of its sequence. If yes then by incrementing its value we search the set and increment the length. By repeating this for all elements, we can find the lengths of all consecutive sets in array.

How do you find consecutive elements in an array?

1) Sort all the elements. 2) Do a linear scan of the sorted array. If the difference between the current element and the next element is anything other than 1, then return false. If all differences are 1, then return true.


3 Answers

Similar to w0lf's answer, but skipping elements by returning nil from chunk:

array.chunk { |x| x == 1 || nil }.map { |_, x| x.size }.max
like image 69
Stefan Avatar answered Oct 07 '22 05:10

Stefan


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

like image 6
Sid Avatar answered Oct 07 '22 04:10

Sid


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 0s and 1s):

array.slice_when{|x,y| x < y }.map{|slice| slice.count 1 }.max
like image 5
Cristian Lupascu Avatar answered Oct 07 '22 05:10

Cristian Lupascu