I want to create a class that makes the number round down to the nearest square number( 1, 4, 9, 16, 25...).
I've tried some other code suggestions but I haven't found anything helpful. I don't know mostly how to get it to the nearest square
class Integer
def down
#round down to nearest square using self
end
end
(27).down #=> 25
Josh, maybe the code below can help you. You can put that in a ruby file and then run in the terminal. It will ask for a value and will return the answer.
class Integer
def down
Integer.sqrt(self) ** 2
end
end
print "Enter a valid number: "
a = gets.to_i
puts a.down
Updated thanks to pjs and Cary Swoveland.
Related
I am trying to get the first half of a string. If the string length is an odd number, then round up. I am bit stuck on getting a half of a string.
def get_first_half_of_string(string)
if string.size % 2 == 0
string[1,4]
else
string[1,5]
end
end
puts get_first_half_of_string("brilliant")
This returns rilli
When calling str[start, length] you need to use 0, not 1, as the start point. For the length you should just be able to divide the length by 2, so your method body only needs string[0, (string.length.to_f / 2).ceil]
https://ruby-doc.org/core-2.2.0/String.html#method-i-5B-5D
I would do something like this:
def first_half_of_string(string)
index = (string.size.to_f / 2).ceil
string[0, index]
end
first_half_of_string("brilliant")
#=> "brill"
Maybe you could divide the string size in half and round up if it is odd:
half = (string.size/2.to_f).ceil
string[0,half]
Following previous answers, you could open String class:
class String
def first_half
self[0,(self.size/2.to_f).ceil]
end
end
So you can do:
"ruby".first_half
=> "ru"
"hello".first_half
=> "hel"
I got the task to create a lottery program which outputs 6 random numbers from 1 to 49 without duplicates. I'm not allowed to use the shuffle-Method of Arrays and as a tip I recieved that I should create an array with 49 entries and "shuffle" the numbers. I thought about this tip but it's not really helping.
This is what I got till now, I hope someone understands my code. I'm still stuck in a more Java way of writing than in ruby.
# Generating the Array
l_num = Array.new(6)
i = 0
while (i == 0)
l_num << [rand(1...49), rand(1...49), rand(1...49), rand(1...49), rand(1...49), rand(1...49)]
if (l_num.uniq.length == l_num.length)
i += 1
end
end
#Output
puts 'Todays lottery numbers are'
l_num.each { |a| print a, " " }
I picked up the uniq-Methode, because I read that it could elimante doubles that way, but I don't think it works in this case. In previous versions of my code I got a Error because I was trying to override the allready created array, I understand why Ruby is giving me an error but I have no clue how to do it in another way.
I hope someone is able to provide me some code-pieces, methods, solutions or tips for this task, thanks in advance.
This is the strategy I would take:
lottery_numbers = []
begin
# add 1 because otherwise it gives you numbers from 0-48
number = rand(49)+1
lottery_numbers.push(number) unless lottery_numbers.include?(number)
end while lottery_numbers.size < 6
puts "lottery numbers:"
puts lottery_numbers.join(" ")
Rubyists tend to initialize arrays with [] as opposed to the verbose Array.new
Charles, I think the easiest would be the following:
Array.new(49) { |x| x + 1 }.sample(6)
However this is what I believe you was prohibited to do? If yes, try a more "manual" solution:
Array.new(49) { |x| x + 1 }.sort { rand() - 0.5 }.take(6)
Otherwise, try implementing one completely "manual" solution. For example:
require 'set'
result = Set.new
loop do
result << 1 + rand(49)
break if result.size == 6
end
puts result.to_a.inspect
Here's one way to do it you can't use sample:
a = *1..49
#=> [1, 2, 3,..., 49]
6.times.map { a.delete_at(rand(a.size))+1 }
# => [44, 41, 15, 19, 46, 17]
min_lottery_number = 1
max_lottery_number = 49
total_size = 6
(min_lottery_number..max_lottery_number).to_a.sample(total_size)
Brand new to Ruby. There are a couple of array methods I can't access.
EDIT:
I originally had:
puts 'give me a number to find phi of: '
K = gets
List = Array.new(K) #{|i| i}
List.drop(2)
List puts
Rec'd the error: in `initialize': no implicit conversion of String into Integer
so I changed line 3 above to:
List = Array.new(K.to_i) #{|i| i}
and am now receiving: undefined method `List' for main:Object
I'm trying to create an array based on user input, then drop or shift the first 2 elements of the array (the 0 and 1)
=================================
original post was unclear:
puts 'give me a number to find phi of: '
K = gets
puts K.shift
I'm sure it's something easy but can't figure it out. Am I missing a basic library or something? Any help would be appreciated!
This is the shortest way to find all primes between 2 and K in Ruby, you don't have to invent your own algo for finding primes when there's one already(http://ruby-doc.org/stdlib-1.9.3/libdoc/prime/rdoc/Prime.html)
require 'prime'
def find_primes_between_2_and(a_number)
Prime.each(a_number).map do |prime|
prime
end
end
puts 'Give me a number up to which to find primes:'
number = gets.to_i
puts find_primes_between_2_and(number)
I'm running thru Chris Pike's Ruby "Learning to Program" & am doing it as an exercise. But hey, thanks for the help.
My problem on the shift was passing it w/o a parameter. It should have been List.shift(2)
Thanks much!
def percent_more
puts "What is the biggest number?"
biggest_number = gets.chomp
puts "What is the smallest number?"
smallest_number = gets.chomp
difference = biggest_number.to_i - smallest_number.to_i
total_percent_more = difference / smallest_number.to_f
puts "Your biggest number is #{total_percent_more}% bigger then your smallest number. Don't forget to round off to the nearest whole percent!"
end
Now that code will tell you what percent more biggest_number is than smallest_number. But the problem is it prints out a long list of decimals, which are a pain to sort through. So if I wanted the code to only show say the first 3 numbers what would I do??
What you want to use is total_percent_more.round like so:
puts "What is the biggest number?"
biggest_number = gets.chomp
puts "What is the smallest number?"
smallest_number = gets.chomp
difference = biggest_number.to_i - smallest_number.to_i
total_percent_more = difference / smallest_number.to_f
puts "Your biggest number is #{total_percent_more.round}% bigger then your smallest number. Don't forget to round off to the nearest whole percent!"
See the docs for more info :
http://www.ruby-doc.org/core-2.1.2/Float.html#method-i-round
in ruby versions earlier than 1.9 you'll need to use sprintf like so:
puts "Your biggest number is #{sprintf('%.2f', total_percent_more)}% bigger then your smallest number. Don't forget to round off to the nearest whole percent!"
You can change the amount of decimal places by changing the number.
See docs for more details:
http://www.ruby-doc.org/core-1.8.7/Kernel.html#method-i-sprintf
result = 10/6.0
puts result
printf("%.3f\n", result)
--output:--
1.66666666666667
1.667
Here is an example how to round to 2 decimal places
amount = 342
puts amount.round(2)
If you wanted to round to the nearest 3 decimal places then something like:
puts amount.round(3)
I want to convert a subtitle time code:
begin="00:00:07.71" dur="00:00:03.67
to pure seconds:
begin=7.1 end=11.38
I wrote a Ruby code:
def to_sec(value)
a = value.split(':')
a[0].to_i*3600+a[1].to_i*60+a[2].to_f
end
which resulted in 11.379999999999999.
Can anybody tell me why this happens?
Is there any Time library that can do this conversion?
It'll probably be easiest for you to represent your underlying datatype as integer hundredths of a second (centiseconds):
def to_csec(value) #if you had CSec < Integer this would be `def self.[](value)`
a = value.split(':')
#tacking on a couple zeros to each
a[0].to_i*360000+a[1].to_i*6000+(a[2].to_f * 100).to_i
end
You could add some helpers for dealing with the durations and pretty printing them as well:
def csec_to_s(csec) #if you had CSec < Integer, this would be `def to_sec`
"%.2f" % (csec.to_f / 100)
end
class SubtitleDuration < Range
def initialize(a,b)
centi_a = to_csec(a)
super(centi_a,to_csec(b) + centi_a)
end
def to_s
"begin=#{csec_to_s(self.begin)} end=#{csec_to_s(self.end) }"
end
end
Then your answer is just:
puts SubtitleDuration.new("00:00:07.71", "00:00:03.67").to_s
#=> begin=7.71 end=11.38
This sort of thing can happen in just about any programming language. It's because of how floating point numbers are represented. They're not stored as decimals under the hood, so sometimes you get odd rounding errors like this.