Sasha Kolsky
Sasha Kolsky

Reputation: 463

Count consecutives

I need to write a method that does the following

consecutive_count("aaabbcbbaaa") == [["a", 3], ["b", 2], ["c", 1], ["b", 2], ["a", 3]]

I got the code, but it looks ugly and I'm trying to see a better solution, please advice.

Here is my code:

def consecutive_count(str)

  el = str[0]; count = 0; result = []
  str.split("").each do |l|

    if (el != l)
      result << [el, count]
      count = 1
      el = l
    else
      count +=1
    end

  end
  result << [el, count] if !el.nil?

  return result

end

Upvotes: 0

Views: 101

Answers (5)

hirolau
hirolau

Reputation: 13901

Regexp solution:

my_s = "aaabbcbbaaa"
p  my_s.scan(/(.)(\1*)/).map{|x,y| [x, y.size + 1]}
#=> [["a", 3], ["b", 2], ["c", 1], ["b", 2], ["a", 3]]

or

a, result = "aaabbcbbaaa", []
result << a.slice!(/(\w)\1*/) until a.empty?

and then map the result with counts.

Upvotes: 0

Holger Just
Holger Just

Reputation: 55758

A solution which does not involve regex magic (although those are a bit shorter and probably faster) is this:

str.each_char.each_with_object([]) do |char, result|
  if (result.last || [])[0] == char
    result.last[1] += 1
  else
    result << [char, 1]
  end
end

Depending on your level of understanding, it might better transport your intended meaning which might help to debug the thing in 6 month :)

Upvotes: 0

Arup Rakshit
Arup Rakshit

Reputation: 118271

Here is one way :

s = "aaabbcbbaaa"
s.chars.chunk{|e| e }.map{|item,ary| [item,ary.size]}
# => [["a", 3], ["b", 2], ["c", 1], ["b", 2], ["a", 3]]

Upvotes: 3

sawa
sawa

Reputation: 168091

"aaabbcbbaaa".scan(/(?<s>(?<c>.)\k<c>*)/).map{|s, c| [c, s.length]}
# => [["a", 3], ["b", 2], ["c", 1], ["b", 2], ["a", 3]]

or

"aaabbcbbaaa".scan(/((.)\2*)/).map{|s, c| [c, s.length]}
# => [["a", 3], ["b", 2], ["c", 1], ["b", 2], ["a", 3]]

Upvotes: 3

uno_ordinary
uno_ordinary

Reputation: 458

You can try:

def consecutive_count(str)
  result = {}
  array = str.split(//).uniq
  array.each.map {|char| result[char] = 0}
  array.each do |char|
    while str.starts_with?(char) do        
      result[char] += 1
      str[0] = ""
   end
  result
end

Upvotes: -1

Related Questions