2
\$\begingroup\$

As I'm learning Ruby I wrote this little program to generate a "nice" number randomly (like 4747, 6969, etc.). As I'm currently breaking the "do not repeat yourself" rule, how would you refactor the following?

def nice_numbers
    a = rand(9)
    b = rand(9)
    c = rand(9)
    d = rand(9)
    while a != c || b != d
        a = rand(9)
        b = rand(9)
        c = rand(9)
        d = rand(9)
    end
    nice = [a,b,c,d].join
end

puts nice_numbers
\$\endgroup\$
2
  • 2
    \$\begingroup\$ Can you clarify why you are generating c and d at all - what is the purpose if you always want a == c and b == d? It would save you almost all your code if you just did [a,b,a,b].join at the end rather than force a "random" number to match. In fact it's a one liner ([rand(9),rand(9)]*2).join \$\endgroup\$ Commented May 23, 2016 at 18:57
  • \$\begingroup\$ You are right, Neil, so much simpler! Thanks! \$\endgroup\$ Commented May 23, 2016 at 19:29

1 Answer 1

5
\$\begingroup\$

The code:

def nice_numbers
  ([rand(9),rand(9)]*2).join
end

generates the same output as your function. It is also faster, as it does not test then regenerate anything.

If you want to DRY this up for rand(9):

def nice_numbers
  (Array.new(2) {rand(9)} * 2).join
end

Ruby language features used in this last example:

  • Array constructor takes a size param and a block to fill the Array

  • Multiplying an array by an integer repeats the array

\$\endgroup\$
3
  • \$\begingroup\$ You don't even need an array: '%02d' % rand(99) * 2 \$\endgroup\$ Commented May 24, 2016 at 5:00
  • 1
    \$\begingroup\$ @Stefan: Nice alternative idea. Doesn't output same as OP's code though, because the digits can take value 9 (but you would never see 99). Probably rand(100) would work for OP though, and rand(10) - or even rand(9)+1 - would be suitable in this answer. \$\endgroup\$ Commented May 24, 2016 at 6:57
  • \$\begingroup\$ Good catch, I thought it would be 0 <= rand(n) <= n \$\endgroup\$ Commented May 24, 2016 at 7:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.