7
\$\begingroup\$

I finished the Ruby chapter in Seven Languages in Seven Weeks. It tries to make you familiar with the core concepts of several languages rather quickly. Dutifully I did all exercises, but most likely they can be improved to be more Ruby-like. I'll post my code samples one by one, so I can apply things learned in previous questions to later questions.

Day 1

Write a program that picks a random number. Let a player guess the number, telling the player whether the guess is too low or too high.

range = (0..10)
to_guess = range.min + rand(range.max - range.min)
guessed = false

while !guessed
    puts "Guess a number, between #{range.min} and #{range.max}"
    guess = gets
    int = guess.to_i
    if int == to_guess
        puts 'Correct!'
        guessed = true
    else
        puts int > to_guess ? 'Lower' : 'Higher'
    end     
end

After sepp2k's comments:

class Range
  def size
    self.end - self.begin
  end
end

range = 0..10
to_guess = range.begin + rand(range.size)
guessed = false

until guessed
  puts "Guess a number, between #{range.begin} and #{range.end}"
  guess = gets
  int = guess.to_i
  if int == to_guess
    puts 'Correct!'
    guessed = true
  else
    puts int > to_guess ? 'Lower' : 'Higher'
  end       
end
\$\endgroup\$
7
\$\begingroup\$

A couple of minor things:

First of all the convention in the ruby world is to use 2 spaces for indentation, not 4. It doesn't really matter much, but it's generally easier to use the style conventions that everyone uses unless you have a reason not to.

range = (0..10)

You don't actually need the parentheses here. Parentheses are not part of range syntax - the reason you usually see ranges wrapped in parentheses is that you can't call methods on ranges without them (because 0..10.foo would be interpreter as 0..(10.foo)).

to_guess = range.min + rand(range.max - range.min)

You should use begin and end or first and last instead of min and max. In ruby 1.8.7 min and max are inherited from Enumerable and will iterate the entire range in order to find the minimum/maximum, making them O(n). Only in 1.9 (in 1.9.2 at least) they're overridden to work in O(1) time. begin and end work in O(1) time in all ruby versions.

I would also consider putting this into its own method as it seems like it might come in handy more than once.

while !guessed

I would write that as until guessed as that reads a bit nicer to me.

\$\endgroup\$
4
\$\begingroup\$

One thing I noticed is that you have a throwaway variable, guess, in between gets and int. You can reduce some of that by simply using guess = gets.to_i and if guess == to_guess.

Also, you could use break instead of the guessed variable and while/until condition:

loop do
  # ...
  if guess == to_guess
    puts 'Correct!'
    break
  end
  puts int > to_guess ? 'Lower' : 'Higher'
end

But that is more a matter of preference, as both methods have their merits.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.