Reputation: 21
So I made a random number generator which is supposed to count the frequency of the numbers and display them in sorted order. I'm trying to use .sort but I can't figure out where to put it to sort the values of the hash in order. What I have so far:
MIN_VALUE = 1
count = 0
puts "Enter a number of random integers to generate"
resp = gets.to_i
p "number of integers generated is #{resp}"
puts "Now enter the maximum value the integers can be"
max_value = gets.to_i
p "max value is set to #{max_value}"
size = Array.new(resp)
while (count < resp)
int_value = (rand(MIN_VALUE..max_value))
size.push(int_value)
count = count + 1
end
puts size
freq = Hash.new(0)
size.each { |x| freq[x] += 1 }
freq.map{ |key, value| "#{key}x#{value}" }.join(',')
freq.each do |key,value|
puts "Frequency of #{key} is: #{value}"
end
Any help is greatly appreciated!
Upvotes: 2
Views: 142
Reputation: 11193
More or less the same soup, generating random numbers in an Integer#times loop:
upper_number = 10
sample_size = 100
freq = Hash.new(0) # initializing the hash with a default value of zero, for counting
sample_size.times { freq[rand((1..upper_number))] += 1 } # here the loop generating and counting
freq #=> {5=>13, 7=>10, 1=>11, 2=>13, 8=>13, 9=>6, 3=>6, 6=>9, 10=>11, 4=>8}
Then you can sort by frequencies (reverse order: -v
) and by sample value (k
), [-v, k]
:
freq.sort_by{ |k, v| [-v, k] }.to_h #=> {2=>13, 5=>13, 8=>13, 1=>11, 10=>11, 7=>10, 6=>9, 4=>8, 3=>6, 9=>6} # for this run
freq.sum { |_, v| v} #=> 100 # of course
Upvotes: 1
Reputation: 110685
Suppose
arr = [4, 1, 3, 4, 2, 5, 1, 3, 4, 3, 4]
You can use the form of Hash::new that takes an argument, called its default value (which often, as here, is zero), to obtain the frequency of the elements of arr
:
freq = arr.each_with_object(Hash.new(0)) { |n,h| h[n] += 1 }
#=> {4=>4, 1=>2, 3=>3, 2=>1, 5=>1}
We see that
freq[1]
#=> 2
freq[99]
#=> 0
The second result follows because freq
was defined to have a default value of 0
. All that means is that if freq
does not have a key k
, freq[k]
returns zero (and that does not alter freq
).
Here are solutions to two possible interpretations of your question. Both use the method Enumerable#sort_by.
Sort the unique values of arr
by decreasing frequency
freq.sort_by { |_,v| -v }.map(&:first)
#=> [4, 3, 1, 2, 5]
Sort the values of arr
by decreasing frequency
arr.sort_by { |n| -freq[n] }
#=> [4, 4, 4, 4, 3, 3, 3, 1, 1, 2, 5]
Replace -v
and -freq[n]
with v
and freq[n]
to sort by increasing frequency.
I've used the local variable _
to represent the keys in the first interpretation to signify that it is not used in the block calculation. This is common practice.
Upvotes: 0