11

I am trying to get a random year between 1900 and 1980 with Ruby.

So far I have:

puts 'the year was: ' + 1900.to_s + rand(1980).to_s 

but this is just adding 1900 and a random number from 0 - 1979 together to look like 19001947.

I think I'm missing something silly but can anyone shed any light?

1

5 Answers 5

29

Ruby 1.9.3

1.9.3p0 :001 > rand(1900..1980) => 1946 1.9.3p0 :002 > rand(1900..1980) => 1929 1.9.3p0 :003 > rand(1900..1980) => 1934 
Sign up to request clarification or add additional context in comments.

Comments

13

Give this a try

(1900 + rand(81)).to_s 

To be clear for passersby

First, there was an issue regarding string concatenation. The original code in the question was concatenating two strings (containing numbers) together. Example:

"1900" + "1920" = "19001920"

Second, there was an issue the range of random numbers being generated. In this case, since we only want a range of 80 years, we want to use rand(81), instead of rand(1980). We then take that result and add it to the base number, which will give us a random number between 1900 and 1980.

3 Comments

This will generate 1900 (sometimes), but it will never generate 1980.
you're mistaken about this not being an issue of string catenation: 1900.to_s and rand(80).to_s both evaluate to objects of type string, so the "+" operation is indeed the string overload of "+". This when that's changed to (1900 + rand(80)).to_s, 1900 and the result of rand(80) are numbers, and the resulting sum are then converted to a string.
@Charlie, I think you read my comment regarding the string incorrectly. My answer states "The original question was concatenating two strings". I believe we are no the same page. Quoting my answer: "First, there was an issue regarding string concatenation." with my intent being to communicate that the question did indeed have two problems, the first being a concatenation issue
3
puts "The year was #{1900 + rand 81}" 

Comments

2

Yes: you're getting the "string catenation" overload of +. Try (1900+rand(80)).to_s

Comments

2

Ruby 1.8+

(1900..1980).to_a[rand(80)] # or little more Rubyistic (1900..1980).to_a.shuffle.first 

Ruby 1.9+

[*1900..1980].sample 

7 Comments

The downside to this approach is an intermediate array is created for each element in the range. For a small range it's not a big deal. A large range, say 0..1_000_000_000 could be painful.
@the Tin Man, I think it is overengineering and over optimization. Here is particular issue and I think good solution for this issue :). It is static range (1900..1980) which won't ever grow into something big. And overengineering is evel, I believe. Of course you should understand all downsides of any approach you use, but you never should use "fastest" in perfomance if it is not a goal.
And yes, I prefer @Phrogz solution, but as far as obvious straight solution was here before I answered, I suggested this just for fun :D
@fl00r : because it's inefficient. Instead of calling rand you're creating a possibly huge array, only to call a more complicated random method on it (.sample makes sure no duplicates are returned).
"all this side effects not a problem for our topic" I disagree. It's important to provide answers that include the information the OP needs to make good decisions now, and in the future. While your solution does work for this particular question, the OP could get into trouble later because no caveat was given about that particular use. That is important information to pass on and is teaching how to fish. And, as far as over engineering, I consider it defensive programming by avoiding a potential future problem.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.