Ruby Programming

I am doing some Ruby programming lately. And, I come across this problem which involve traversing an array:

Problem Text:

Write a program which will accept two rows of integers separated by commas. The program should count the occurrence of every digit from first row in the second row. The program should print the corresponding digit along with count of how many times it appears in second row separated by hyphen (one output per line).

For example, let us suppose the following two string inputs are supplied to the program:
1,2,3,4,5,6,7,8,9
1,2,3,3,4,4,5,5,6,6,6,7,7,7,7,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9

Then, the output of the program should be:


1-1 (as 1 only appears once)
2-1 (as 2 only appears once)
3-2 (as 3 appears twice)
4-2
5-2
6-3
7-4
8-5
9-10

I hacked an easy solution which has some imperative programming ancestry:

keys = gets
input = gets

dict = {}
keys.split(",").map { |s| s.to_i }.each do |key|
  input.split(",").map { |s| s.to_i }.each do |val|
    if key == val
      dict[key] ||= []
      dict[key] << val
    end
  end
end

keys.split(",").map { |s| s.to_i }.each do |key|
  unless dict.assoc(key).nil?
    puts "#{key}-#{dict.assoc(key).last.size}"
  else
    puts "#{key}-0"
  end
end

But then, I got some time to think over, and came up with one tidy solution:

keys = gets
input = gets

keys.split(",").map{|a| a.to_i}.each do |key|
  puts "#{key}-#{input.split(",").map{|a| a.to_i}.count(key)}"
end

And, then, again, I tried to be smarter, and used Hash to minimize some passes:

keys = gets
input = gets

hash = input.split(",").map{|a| a.to_i}
  .inject(Hash.new(0)) {|hash, key|hash[key]+=1; hash}
keys.split(",").map{|a| a.to_i}.each {|key| puts "#{key}-#{hash[key]}"}

Yet, I did something which was not required. I use map() to convert character to integer. This step was not required, because we were just interested in the characters and not the arithmetic on those characters. So, I could have altogether eliminated the map{|a| a.to_i} step.

Advertisements
Ruby Programming