Reputation: 639
How would it be possible to remove the same number of duplicates for each character in a string until only one instance is left of one of the characters stopping the process of removing duplicates from the remaining characters?
If I have a string:
string = "aaaabbbxxxxx44444oooooo9999999"
You can see that the character b
is the character with the least number of duplicates (i.e. there's b
followed by two more b
s) so, if we remove 2 duplicates from each character set, we'd be left with the following without losing any characters used in the original string but minimising the number of duplicates for each character:
string = "aabxxx444oooo99999"
Also lets assume our string contains no white space and if it is jumbled:
string_b = "aabb4keekkk447abae777err99r9"
You can sort it first:
string_b = stringb.chars.sort.join
#=> string_b = "4447777999aaaabbbeeeekkkkrrr"
Before applying your reduce duplicates method:
string_b = "4779aabeekkr"
Upvotes: 0
Views: 1054
Reputation: 11882
You should put this in a method.
def convert str
return str if str.empty?
letter_array = str.chars.group_by {|x| x}.values
drop_size = letter_array.map(&:size).min - 1
letter_array.map {|x| x.drop drop_size}.join
end
To run this in irb console
2.2.1 :230 > convert 'aaaabbbxxxxx44444oooooo9999999'
=> "aabxxx444oooo99999"
2.2.1 :231 > convert ''
=> ""
2.2.1 :232 > convert 'abc'
=> "abc"
2.2.1 :233 > convert 'abcabcddd'
=> "abcdd"
2.2.1 :234 > convert " "
=> " "
You want to test with various inputs (eg empty string) to make sure that it works.
Upvotes: 1
Reputation: 521
If you don't require the original order or chars, then you can do:
string_b = "aabb4keekkk447abae777err99r9"
h = string_b.chars.group_by { |c| c }.map { |c, a| [c, a.size] }.to_h
#=> {"a"=>4, "b"=>3, "4"=>3, "k"=>4, "e"=>4, "7"=>4, "r"=>3, "9"=>3}
# #to_h is optional here
n = h.values.min - 1
#=> 3
# use map(&:last) instead of #values if not using #to_h previously
h.map { |k, v| k * (v - n) }.sort.join
#=> "4779aabeekkr"
Upvotes: 2