-1

Trying to get the most occurring letter in a string.

So far:

puts "give me a string"
words = gets.chomp.split
counts = Hash.new(0)
words.each do |word|
  counts[word] += 1
end

Does not run further than asking for a string. What am I doing wrong?

sawa
  • 165,429
  • 45
  • 277
  • 381
blubg
  • 1
  • 1
  • 3
  • Can you adapt one or more of the answers to [this question](http://stackoverflow.com/questions/412169/ruby-how-to-find-item-in-array-which-has-the-most-occurrences) to your problem? – Ray Toal May 31 '15 at 05:12
  • How is the notion of word, or the method `split` relevant to your goal? – sawa May 31 '15 at 05:56
  • I thought I needed to split the string first by words before I could individually split the letters. I'm very new, and at the "Handholding/ Honeymoon stage". I don't really have a goal right now other than to learn as much as possible :/ – blubg May 31 '15 at 06:04

4 Answers4

1

If you're running this in irb, then the computer may think that the ruby code you're typing in is the text to analyse:

irb(main):001:0> puts "give me a string"
give me a string
=> nil
irb(main):002:0> words = gets.chomp.split
counts = Hash.new(0)
words.each do |word|
counts[word] += 1
end=> ["counts", "=", "Hash.new(0)"]
irb(main):003:0> words.each do |word|
irb(main):004:1* counts[word] += 1
irb(main):005:1> end
NameError: undefined local variable or method `counts' for main:Object
    from (irb):4:in `block in irb_binding'
    from (irb):3:in `each'
    from (irb):3
    from /Users/agrimm/.rbenv/versions/2.2.1/bin/irb:11:in `<main>'
irb(main):006:0> 

If you wrap it in a block of some sort, you won't get that confusion:

begin
  puts "give me a string"
  words = gets.chomp.split
  counts = Hash.new(0)
  words.each do |word|
    counts[word] += 1
  end
  counts
end

gives

irb(main):001:0> begin
irb(main):002:1*   puts "give me a string"
irb(main):003:1>   words = gets.chomp.split
irb(main):004:1>   counts = Hash.new(0)
irb(main):005:1>   words.each do |word|
irb(main):006:2*     counts[word] += 1
irb(main):007:2>   end
irb(main):008:1>   counts
irb(main):009:1> end
give me a string
foo bar
=> {"foo"=>1, "bar"=>1}

Then you can work on the fact that split by itself isn't what you want. :)

Andrew Grimm
  • 78,473
  • 57
  • 200
  • 338
0

This should work:

puts "give me a string"
result = gets.chomp.split(//).reduce(Hash.new(0)) { |h, v| h.store(v, h[v] + 1); h }.max_by{|k,v| v}
puts result.to_s

Output:

@Alan ➜  test rvm:(ruby-2.2@europa)  ruby test.rb
give me a string
aa bbb cccc ddddd
["d", 5]

Or in irb:

:008 > 'This is some random string'.split(//).reduce(Hash.new(0)) { |h, v| h.store(v, h[v] + 1); h }.max_by{|k,v| v}
 => ["s", 4]
errata
  • 23,596
  • 2
  • 22
  • 32
  • Got a big fat broken error: :( ruby example.rb example.rb:3: syntax error, unexpected '|', expecting '}' { |h, v| h.store(v, h[v] + 1); h } ^ example.rb:3: syntax error, unexpected '|', expecting '=' { |h, v| h.store(v, h[v] + 1); h } – blubg May 31 '15 at 05:48
-1

Rather than getting a count word by word, you can process the whole string immediately.

  str = gets.chomp
  hash = Hash.new(0)
  str.each_char do |c|
    hash[c] += 1 unless c == " " #used to filter the space
  end

After getting the number of letters, you can then find the letter with highest count with

max = hash.values.max

Then match it to the key in the hash and you're done :)

puts hash.select{ |key| hash[key] == max }

Or to simplify the above methods

hash.max_by{ |key,value| value }

The compact form of this is :

  hash = Hash.new(0)
  gets.chomp.each_char { |c| hash[c] += 1 unless c == " " }
  puts hash.max_by{ |key,value| value }
  • unfortunately I'm unable to send you a private message. I have a few questions regarding your method of achieving this for me re: max = hash.values.max (you used max twice, so I'm just curious about the max variable and the method). Also, is there any way to incorporate 'mode'? argh, so many things >_ – blubg May 31 '15 at 06:10
  • Yes, I used that to illustrate what you had in mind :) – Jason Adrian Bargas May 31 '15 at 06:19
  • The ` max = hash.values.max` ; where the first `max` is a variable where the result of hash.values.max is stored. The second `max` is a method that finds the maximum value contained from the resulting array of hash.values ; the method `values` returns an array of all values in the hash :) I hope this enlightens you hehe – Jason Adrian Bargas May 31 '15 at 06:25
-1

This returns the highest occurring character within a given string:

puts "give me a string"

characters = gets.chomp.split("").reject { |c| c == " " }
counts = Hash.new(0)

characters.each { |character| counts[character] += 1 }

print counts.max_by { |k, v| v }
Zoran
  • 4,196
  • 2
  • 22
  • 33
  • :( didn't return anything back blubg@zugzug:~/Documents $ ruby example.rb give me a string fdkjhfjksdhfsa blubg@zugzug:~/Documents $ – blubg May 31 '15 at 05:55
  • 2
    The only thing wrong with this is that it didn't output the result. Adding a `puts` to the last line works fine, as does the one above. Please try to debug a little before downvoting working answers. – errata May 31 '15 at 06:27
  • @blubg just updated the code. It was missing a `puts` or `print` statement - easy enough to fix :) I chose `print`, so the returned result comes out in `[x, 5]` format - a little nicer looking than just puts IMO. Hope it helps! – Zoran May 31 '15 at 06:29
  • I haven't down voted anything in this thread and have questioned why anyone would. I need 125 reputation before I could ever do that anyway :/ Also, thanks for editing that. It took me for ever to figure out why but I managed to do so! :) – blubg Jun 02 '15 at 06:53