devwanderer - 1 year ago 37
Ruby Question

# Finding index and size of consecutive repeated elements in an array

An array consists of

`1`
,
`2`
, and
`0`
s. I am trying to identify the maximum repetition and its starting index within the array.

Example:

``````2 2 1 0 2 2 2 0 1 1
``````

The method should accept an integer arguement, which can be one of the numbers
`1`
or
`2`

If we demonstrate these inputs on above array, the outputs would be:

``````find_duplicates(2)
=>    3,4

find_duplicates(1)
=>    2,8
``````

where the first number indicates the size of the duplication, and second is the starting index of it.

I tried looping through the array and compare with
`arr[i+1]`
or
`arr[-1]`
, but this is not the correct approach. Any help will be greatly appreciated.

Edit:
I had not pasted what I had tried at the time I asked the question, this is not something I would do if I could feel some confidence on the way I followed:

``````def find_status(arr,participant)
status = Array.new

for i in 0...arr.length do
current_line=arr[i]
cons=0
for j in 0...current_line.length do
#I worked on lots of if/else/case statements here, this is just one of them
if current_line[j] == participant
cons+=1   #count consecutive
if current_line[j]!=participant
cons=0
end
end
status[i] = cons
end
end
return status
end
``````

``````def max_run(arr, target)
_,b = arr.each_with_index.
chunk  { |n,_| n==target }.
select { |tf,_| tf==true }.
max_by { |_,a| a.size }
b ? [b.size, b.first.last] : nil
end

arr = [1,1,2,2,2,3,1,1,1,1,2,2,2,2,3,3]

max_run(arr,1) #=> [4, 6]
max_run(arr,2) #=> [4, 10]
max_run(arr,3) #=> [2, 14]
max_run(arr,4) #=> nil
``````

For `target = 2`, the steps are as follows:

``````enum0 = arr.each_with_index
#=> #<Enumerator: [1, 1, 2, 2, 2, 3, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3]
#    :each_with_index>
``````

We can see the elements that will be generated by this enumerator by converting it to an array:

``````enum0.to_a
#=> [[1, 0], [1, 1], [2, 2], [2, 3], [2, 4], [3, 5], [1, 6], [1, 7], [1, 8],
#     [1, 9], [2, 10], [2, 11], [2, 12], [2, 13], [3, 14], [3, 15]]
``````

Continuing,

``````enum1 = enum0.chunk  { |n,_| n==target }
#=> #<Enumerator: #<Enumerator::Generator:0x007f9beb9b0850>:each>
``````

Carefully examine the return value here. You can think of `enum1` as a "compound enumerator". It will generate the following values:

``````enum1.to_a
#=> [[false, [[1, 0], [1, 1]]], [true, [[2, 2], [2, 3], [2, 4]]],
#    [false, [[3, 5], [1, 6], [1, 7], [1, 8], [1, 9]]],
#    [true, [[2, 10], [2, 11], [2, 12], [2, 13]]], [false, [[3, 14], [3, 15]]]]
``````

Continuing,

``````c = enum1.select { |tf,_| tf==true }
#=> [[true, [[2, 2], [2, 3], [2, 4]]],
#    [true, [[2, 10], [2, 11], [2, 12], [2, 13]]]]
_,b = c.max_by { |_,a| a.size }
#=> [true, [[2, 10], [2, 11], [2, 12], [2, 13]]]
b #=> [[2, 10], [2, 11], [2, 12], [2, 13]]
b ? [b.size, b.first.last] : nil
#=> [[2, 10], [2, 11], [2, 12], [2, 13]] ? [4, [2,10].last]
#=> [4, 10]
``````