jackneedshelp
jackneedshelp

Reputation: 137

Counting integers in array from 1 to 100 in increments of 10

a = Array.new(200) { rand(1..100) }.sort!

puts a.count{ |a| (a >  0 && a < 11) }
puts a.count{ |b| (b > 10 && b < 21) }
puts a.count{ |c| (c > 20 && c < 31) }

puts a.inspect

So I can just repeat this all the way to 100 which works but I'm looking for a short cut to hopefully count all the digits pairs with the single line at the top(Add onto the single line). Hopefully each 10 (1-10, 11-20, etc) has a different variable that I can call later on. Or at-least be able to convert it.

make variables like

b = a.count{ |c| (c > 20 && c < 31) }

so later i could use it to make a string like

puts "#" * b

so the end result of it all will look like below

1-10 #########################
11-20 ##############################
21-30 ######################

each # representing how much 1-10 there were.

Upvotes: 1

Views: 913

Answers (3)

Amadan
Amadan

Reputation: 198324

counts = 10.times.map { |i| (i + 1)...(i + 11) }.map { |range|
  a.count { |x| range.include? x }
}

counts[0]
# => 17   (number of numbers in 1...11)
counts[1]
# => 20   (number of numbers in 11...21)
counts[2]
# => 22   (number of numbers in 21...31)
# ...

EDIT: Or even easier, by exploiting a simple mathematical property:

counts = a.group_by { |x| (x - 1) / 10 }.map { |k, v| v.count }

Hopefully each 10 (1-10, 11-20, etc) has a different variable that I can call later on.

Why would you want different variables when you can have an array?

EDIT2: Whole program, in 1-4 lines:

array = 200.times.map { rand(1..100) }.sort
array.group_by { |x| (x - 1) / 10 }.each do |k, v|
  puts "%2d-%2d %s" % [k * 10 + 1, k * 10 + 10, "#" * v.count]
end

Translation: Do two hundred iterations, and construct an array, such that each element is a random number between 1 and 100. Then group the array by the result of division by 10 (adjusting by 1 so we don't get ranges of 0-9, 10-19...); iterating on the hash containing the division result and items, print the bounds (reconstructing the start and the end from the division result) and also a number of hashes corresponding to the number of items in each group.

EDIT3: As Stefan notes, we can use chunk because the array is sorted, for a bit of a speedup. group_by above doesn't care about the array being sorted. You can simply replace group_by with chunk even though they return different types, simply because iterating on hashes works the same way as iterating on array of two-element arrays.

array = 200.times.map { rand(1..100) }.sort
array.chunk { |x| (x - 1) / 10 }.each do |k, v|
  puts "%2d-%2d %s" % [k * 10 + 1, k * 10 + 10, "#" * v.count]
end

Upvotes: 3

Cary Swoveland
Cary Swoveland

Reputation: 110675

I suggest using a counting hash.

(a = (Array.new(20){|x| x=(rand(1..100)) })).sort!
  #=> [3, 12, 17, 17, 20, 31, 32, 43, 47, 50, 62, 65, 70, 83, 87, 89, 92, 94, 97, 98] 

g = a.each_with_object(Hash.new(0)) do |n,h|
  interval_first = 1+10*((n-1)/10)
  h[interval_first..interval_first+9] += 1
end
  #=> {1..10=>1, 11..20=>4, 31..40=>2, 41..50=>3, 61..70=>3, 81..90=>3, 91..100=>4}

Notice that

g[21..30] #=> 0
g[51..60] #=> 0

even though g does not have keys 21..30 and 51..60.

If intervals with values of zero are to be included in g, this is one way that could be done:

g = 10.times.map { |i| [1+10*i..10+10*i, 0] }.to_h
  #=> {1..10=>0, 11..20=>0, 21..30=>0, 31..40=>0, 41..50=>0, 51..60=>0,
  #    61..70=>0, 71..80=>0, 81..90=>0, 91..100=>0}

a.each_with_object(g) do |n,h|
  interval_first = 1+10*((n-1)/10)
  h[interval_first..interval_first+9] += 1
end
  # => {1..10=>1, 11..20=>4, 21..30=>0, 31..40=>2, 41..50=>3, 51..60=>0,
  #     61..70=>3, 71..80=>0, 81..90=>3, 91..100=>4}

See Hash::new.

Note that pre-sorting the array of random numbers is of no benefit with this method. That probably holds true with most approaches one might consider.

Upvotes: 1

ndnenkov
ndnenkov

Reputation: 36101

(0..100).step(10).each_cons(2).map do |min, max|
  ar.count { |number| number.between?(min.next, max) }
end

Upvotes: 0

Related Questions