Counting amount of times element appears in array - arrays

I am new to post on Stackoverflow but I am having lots of trouble figuring something out. I am new to the ruby language.
I would like to count the amount of times an element in the array is greater than a specific constant. The array length is between 10 and 25, this is chosen by the user. I then have the array sorted from largest to smallest. I would like to count the amount of times a value in the array is larger or equal to 35. This will be defined as the constant "Quota"
puts "Enter a number between 10 and 25 to represent the number of users: "
num = gets.to_i
if num > 25 or num < 10
puts "I said between 10 and 25. Try again"
num = gets.to_i
end
homeDir = Array.new(num) { rand(20..50)}
homeDir.sort!{|x,y| y<=>x}
puts homeDir
quota = 35

you can use method count
homeDir.count{|el| el >= 35 }

This is my question solved.
print "Enter a number between 10 and 25 to represent the number of users: "
num = gets.chomp.to_i
while num > 25 or num < 10
print "I said between 10 and 25. Try again: "
num = gets.to_i
end
homeDir = Array.new(num) { rand(20..50)}
homeDir.sort!{|x,y| y<=>x}
quota = 35
counter = 0
puts"\n"
puts "Directory Sizes (in MB)"
puts "======================"
homeDir.each{|x| puts x}
homeDir.each do |y|
if y > quota
counter = counter + 1
end
end
puts "\n"
puts "There are #{counter} users whos directories are over 35MB"

Since homeDir is sorted largest to smallest, it would generally be more efficient to use Array#take_while (and then Array#size) than Array#count, as count must traverse the entire array.
def count_biggest(arr, num)
arr.take_while { |n| n >= num }.size
end
arr = [5,4,3,2,1]
count_biggest(arr, 3) #=> 3
count_biggest(arr, 6) #=> 0
count_biggest(arr, 0) #=> 5

Related

What condition should I put in the if() to count all the positive integers in a array?

Hi I am doing a simple ruby array programming exercise for myself. Everything has gone well until the if statement comes in as I need to count the total value of all positive integer in a array. What should put in the if() condition ?
require './input_functions.rb'
def main
arraya = Array.new (10)
num = 5
for x in 0..arraya.length-1
arraya[x] = num
num -=1
end
show(arraya)
puts "Enter a new integer:"
r = gets.chomp.to_i
p = read_integer_in_range("Select an index in the array to store a new integer ", 0, 9)
arraya [p] = r
show(arraya)
sum = 0
for x in 0..arraya.length-1
if(x > -1)
sum +=arraya [x]
end
end
puts "The total of all the positive integers is " + sum.to_s
end
def show (arrayb)
for x in 0..arrayb.length-1
puts arrayb[x]
end
end
main
this is the input_function.rb
def read_integer_in_range(prompt, min, max)
value = read_integer(prompt)
while (value < min or value > max)
puts "Please enter a value between " + min.to_s + " and " + max.to_s + ": "
value = read_integer(prompt);
end
value
end
ok i figured it out
it is arraya [x] > 0

How to split a hash into multiple arrays of keys based the values not exceeding a certain sum in each array?

I have a large hash, where the keys are names, like "Alex", and the values are numeric, like "100".
How can I split this hash into multiple arrays that contain the keys, of which the sum of values doesn't exceed a certain threshold value?
Example
I have the hash
{"Alex"=>50, "Bamby"=>100, "Jordan"=>300, "Ger"=>700, "Aus"=>500, "Can"=>360}
and I want to split it into packs of 1000 from the beginning (doesn't have to be from the beginning but would be nice),
meaning:
array1 = ["Alex", "Bamby", "Jordan"] # not "Ger" bc it would exceed the 1000 in sum
array2 = ["Ger"] # not the Aus because it again would exceed the 1000
array3 = ["Aus", "Can"]
The best solution would actually be to have it optimized in a way that the code makes arrays all close or equal 1000 but that's the next step I guess...
Thank you so much in advance! ~Alex
h = {"Alex"=>50, "Bamby"=>100, "Jordan"=>300, "Ger"=>700, "Aus"=>500, "Can"=>360}
tot = 0
h.keys.slice_before { |k| (tot += h[k]) > 1000 ? tot = h[k] : false }.to_a
#=> [["Alex", "Bamby", "Jordan"], ["Ger"], ["Aus", "Can"]]
Not that if tot > 1000 the block returns a truthy value (h[k]) and the parentheses around tot += h[k] are necessary.
See Enumerable#slice_before.
original = {"Alex"=>50, "Bamby"=>100, "Jordan"=>300, "Ger"=>700, "Aus"=>500, "Can"=>360}
chunked = original.inject([]) do |array, (key, value)|
array << {} unless array.any?
if array.last.values.sum + value <= 1_000
array.last.merge!(key => value)
else
array << { key => value }
end
array
end
# => [{"Alex"=>50, "Bamby"=>100, "Jordan"=>300}, {"Ger"=>700}, {"Aus"=>500, "Can"=>360}]
You can iterate over the elements inside the hash like this, the explain is in the comments:
hash={"Alex"=>50, "Bamby"=>100, "Jordan"=>300, "Ger"=>700, "Aus"=>500, "Can"=>360}
rs = [] # the outside array
rss = [] # the array inside the array
m = 0 # check if the sum of nexts are 1000
hash.each do |key, n|
if m+n <= 1000 # if the counter + the next element < 1000
m += n # then add it to the counter
rss << key # add the key to the actual array
else
rs << rss #else m is equal or bigger than 1000, so, I add all the keys to the main array
m=n # the element that overcomes m to 1000, becomes the first count now
rss=[key] # And that key is the first element of a new array
end
end
rs << rss #Importan! at the end, the final array need to be added outside the loop
print rs
Result _
=> [["Alex", "Bamby", "Jordan"], ["Ger"], ["Aus", "Can"]]

Ruby loop and array

I've been trying to teach myself Ruby. I've found a few code problems to try solving, but I'm stuck. Here is what I have and the problems I'm trying to solve.
My algorithm is as follows:
Prompt the user to enter a number between 1 and 10 (inclusive).
Read that number into an appropriately named variable.
Test that the number lies in the appropriate range.
Input new number if it is out of bounds as per the condition.
Use the number entered by the user to create an array with that
number of elements.
Write a loop which will run through a number of iterations equal to
the size of the array.
Each time through, prompt the user to enter a text string - a name
(names of cars, that sort of thing).
Once the array is entered, display the contents of the array three
items to a line.
You will want a for loop for this, and within the for loop you should include a decision which will insert a line break at the appropriate places.
Also,
Separate the array elements with dashes - but do not put a dash
before the first element on a line, and do not put a dash after the
last element on a line.
Use a Ruby function to sort the array alphabetically, then display it
again, the same way as before.
Reverse the order of the array
Display its contents a third time, again putting three elements on each line of output and placing dashes the way you did with the first display effort.
loop do
print "Enter an integer between 1 and 10: "
s = gets.chomp.to_i
if s >0 && s <= 10
break
else
puts "Interger entered is outside specified range."
end
end
array=[]
array.size
loop do
print "Enter name of a car model: "
car=gets.chomp
array<<car
for i in array
array.slice(1..9) {|car|
puts car.join(", ")
}
end
end
Is that solution you looking for?
loop do
print "Enter an integer between 1 and 10: "
s = gets.chomp.to_i
if (1..10).include?(s)
arr = [""] * s
i = 0
while i < arr.length
print "Enter name of a car model: "
car = gets.chomp
arr[i] = car
i += 1
end
puts arr.join(", ")
break
else
puts "Interger entered is outside specified range."
break
end
end
Result is:
[retgoat#iMac-Roman ~/temp]$ ruby loop.rb
Enter an integer between 1 and 10: 2
Enter name of a car model: car_a
Enter name of a car model: car_b
car_a, car_b
UPDATE
Below solution to print an array by 3 elements per line with natural sorting
loop do
print "Enter an integer between 1 and 10: "
s = gets.chomp.to_i
if (1..10).include?(s)
arr = [""] * s
i = 0
while i < arr.length
print "Enter name of a car model: "
car = gets.chomp
arr[i] = car
i += 1
end
puts arr.sort.each_slice(3){ |e| puts "#{e.join(", ")}\n"}
break
else
puts "Interger entered is outside specified range."
break
end
end
Result is:
[retgoat#iMac-Roman ~/temp]$ ruby loop.rb
Enter an integer between 1 and 10: 4
Enter name of a car model: z
Enter name of a car model: a
Enter name of a car model: x
Enter name of a car model: b
a, b, x
z
And reverse sorting:
loop do
print "Enter an integer between 1 and 10: "
s = gets.chomp.to_i
if (1..10).include?(s)
arr = [""] * s
i = 0
while i < arr.length
print "Enter name of a car model: "
car = gets.chomp
arr[i] = car
i += 1
end
puts arr.sort{ |x, y| y <=> x }.each_slice(3){ |e| puts "#{e.join(", ")}\n"}
break
else
puts "Interger entered is outside specified range."
break
end
end
Result is:
[retgoat#iMac-Roman ~/temp]$ ruby loop.rb
Enter an integer between 1 and 10: 4
Enter name of a car model: z
Enter name of a car model: a
Enter name of a car model: x
Enter name of a car model: b
z, x, b
a
It's better to split you program into small pieces. Also, try not to use loop without necessity.
# Specify Exception class for your context
class ValidationException < RuntimeError
end
def number_of_cars_from_input
# Get user input
print 'Enter an integer between 1 and 10: '
number = gets.chomp.to_i
# Validate input for your requirements
unless (1..10).cover?(number)
raise ValidationException, 'Interger entered is outside specified range.'
end
number
rescue ValidationException => err
# Print exception and retry current method
puts err
retry
end
# Get car name from user input
def car_from_input
print 'Enter name of a car model: '
gets.chomp
end
# Create array with size equal to number from imput and fill it with cars
array_of_cars = Array.new(number_of_cars_from_input) { car_from_input }
# Separate cars in groups by 3 and join groups
puts array_of_cars.each_slice(3).map { |a| a.join(', ') }

How to re-create (each time create new) array in Ruby?

What I missing for create new array for each pair of numbers and then put the sum of each pair? Btw, is it possible to enter pair of numbers through ',' on one line?
arr = []
sum = 0
puts "How much pair of numbers do you want to sum?"
iter = gets.to_i
iter.times do |n|
puts "Enter pair of numbers: "
a = gets.to_i
b = gets.to_i
arr << a
arr << b
end
iter.times do |n|
puts "Here are the sums: "
arr.each { |x| sum += x }
puts sum
end
The input must be like this:
2 # Number of pairs
562 -881 # First pair
310 -385 # Second pair
So the output will be:
-319
-75
For the first part of your question you modify your code like this:
arr = []
sum = 0
puts "How much pair of numbers do you want to sum?"
iter = gets.to_i
iter.times do |n|
puts "Enter pair of numbers: "
a = gets.to_i
b = gets.to_i
arr << [a, b] # store a new 2-element array to arr
end
iter.times do |n|
puts "Here are the sums: "
arr.each { |a, b| puts a + b } # calculate and output for each
end
For the second part of your question, you can do:
a, b = gets.split(',').map(&:to_i)
and rework the calculation/output part like this (with just one loop):
puts "Here are the sums: "
arr.each { |a, b| puts a + b } # calculate and output for each
plus some error handling.

Sum in Ruby array

I'm trying to do a program that asks the user for three numbers one at a time, store them in array, then print the list of the numbers and the total.
Please explain.
Here is what I have so far:
numbers = Array.new
numbers = []
puts "Enter first number: "
first = gets.to_i
puts "Enter second number: "
second = gets.to_i
puts "Enter third number: "
third = gets.to_i
def sum(numbers)
return 0 if numbers.length < 1
result = 0
numbers.each { |num| result += num }
result
end
You can also use Array's reduce method.
http://ruby-doc.org/core-2.1.0/Enumerable.html#method-i-reduce
#!/usr/bin/ruby
numbers = Array.new
# numbers = [] #this is same as above
puts "Enter first number: "
first = gets.to_i
numbers<<first
puts "Enter second number: "
second = gets.to_i
numbers<<second
puts "Enter third number: "
third = gets.to_i
numbers<<third
puts numbers.reduce {|sum, n| sum + n } #here
Here is one more way of doing this:
sum = 3.times.collect{ |i| puts "Enter number #{i + 1}:"; gets.chomp.to_i }.inject(:+)
puts sum
Could also be written like below:
read_num = lambda{|i| puts "Enter number #{i}"; gets.chomp.to_i}
sum = 3.times.map(&read_num).reduce(:+)
puts sum
You haven't pushed any of your inputs into the array, you can either use the push function or the << to add elements to your array
#!/usr/bin/ruby
numbers = Array.new
numbers = []
puts "Enter first number: "
first = gets.to_i
numbers<<first
puts "Enter second number: "
second = gets.to_i
numbers<<second
puts "Enter third number: "
third = gets.to_i
numbers<<first
def sum(someArray)
return 0 if someArray.length < 1
result = 0
someArray.each { |num| result += num }
result
end
hope that helps
There are two problems here:
You aren't pushing the numbers you read into the array
You defined the sum function properly, but aren't calling it anywhere
#!/usr/bin/ruby
numbers = Array.new # note the second, redundant, initialization on numbers was removed
puts "Enter first number: "
(numbers ||= []) << gets.to_i # Pushing read value into the array (issue 1)
puts "Enter second number: "
(numbers ||= []) << gets.to_i # Here too
puts "Enter third number: "
(numbers ||= []) << gets.to_i # And here too
def sum(numbers)
return 0 if numbers.length < 1
result = 0
numbers.each { |num| result += num }
result
end
puts sum(numbers) # Calling sum (issue 2)

Resources