1

I want to generate a random string with the pattern:

number-number-letter-SPACE-letter-number-number

for example "81b t15", "12a x13". How can I generate something like this? I tried generating each char and joining them into one string, but it does not look efficient.

2
  • 2
    Could you show code that you tried, and explain what you mean by "does not look efficient" - do you want faster code, better use of Ruby idioms? Also, do the codes need to be secure/unguessable (in which case better to use SecureRandom than built-in rand) Commented Jun 4, 2014 at 11:46
  • You already have a solution? Can you show it? Commented Jun 4, 2014 at 11:50

4 Answers 4

4
Nums = (0..9).to_a
Ltrs = ("A".."Z").to_a + ("a".."z").to_a
def rand_num; Nums.sample end
def rand_ltr; Ltrs.sample end

"#{rand_num}#{rand_num}#{rand_ltr} #{rand_ltr}#{rand_num}#{rand_num}"
# => "71P v33"
Sign up to request clarification or add additional context in comments.

3 Comments

@sawa: I thought posting a similar solution, just for laughs. Indeed, using methods and converting ranges to arrays seem to be very inefficient
@kimmmo, Sergio I was aware of that but did not take it seriously. I changed the code.
You can also write as [*"A".."Z", *"a".."z"],, Give Ruby the headache :-) +1
3

Have you looked at randexp gem

It works like this:

> /\d\d\w \w\d\d/.gen
=> "64M c82"

4 Comments

Note to readers: Brian didn't actually give the answer. Sergio Tulentsev did.
@sawa how did I not give the answer?
@Brian: you copied the example from the wiki which did not do what was asked.
@sawa I see what you mean. Thanks.
1

Ok here's another entry for the competition :D

module RandomString
  LETTERS      = (("A".."Z").to_a + ("a".."z").to_a)
  LETTERS_SIZE = LETTERS.size
  SPACE        = " "
  FORMAT       = [:number, :letter, :number, :space, :letter, :number, :number]

  class << self
    def generate
      chars.join
    end

    def generate2
      "#{number}#{letter}#{number} #{letter}#{number}#{number}"
    end

    private

    def chars
      FORMAT.collect{|char_class| send char_class}
    end

    def letter
      LETTERS[rand(LETTERS_SIZE)]
    end

    def number
      rand 10
    end

    def space
      SPACE
    end
  end
end

And you use it like:

50.times { puts RandomString.generate }

Out of curiosity, I made a benchmark of all the solutions presented here. Here are the results:

JRuby:

       user     system      total        real
kimmmo   1.490000   0.000000   1.490000 (  0.990000)
kimmmo2  0.600000   0.010000   0.610000 (  0.479000)
sawa     0.960000   0.040000   1.000000 (  0.533000)
hp4k     2.050000   0.230000   2.280000 (  1.234000)
brian   17.700000   0.170000  17.870000 ( 14.867000)

MRI 2.0

       user     system      total        real
kimmmo   0.900000   0.000000   0.900000 (  0.908601)
kimmmo2  0.410000   0.000000   0.410000 (  0.406443)
sawa     0.570000   0.000000   0.570000 (  0.568935)
hp4k     4.940000   0.000000   4.940000 (  4.945404)
brian   25.860000   0.010000  25.870000 ( 25.870011)

1 Comment

Nothing can beat Brian's solution in terms of conciseness :)
0

You can do it this way

(0..9).to_a.sample(2).join + ('a'..'z').to_a.sample + " " + ('a'..'z').to_a.sample + (0..9).to_a.sample(2).join

Comments

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.