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.