Programming Puzzles & Code Golf Stack Exchange is a question and answer site for programming puzzle enthusiasts and code golfers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

What general tips do you have for golfing in Ruby? I'm looking for ideas that can be applied to code golf problems in general that are at least somewhat specific to Ruby (e.g. "remove comments" is not an answer). Please post one tip per answer.

-- borrowed from marcog's idea ;)

share|improve this question
The answers are community wiki, so I edited some. – kernigh May 24 '14 at 16:22
I don't think accepting an answer makes sense for tips. – nyuszika7h Jul 5 '14 at 12:17

29 Answers 29

up vote 30 down vote accepted
  • The numbers 100 to 126 can be written as ?d to ?~ in 1.8.
  • On a similar note if you need a single-character string in 1.9 ?x is shorter than "x".
  • If you need to print a string without appending a newline, $><<"string" is shorter than print"string".
  • If you need to read multiple lines of input $<.map{|l|...} is shorter than while l=gets;...;end. Also you can use $<.read to read it all at once.
  • If you're supposed to read from a file, $< and gets will read from a file instead of stdin if the filename is in ARGV. So the golfiest way to reimplement cat would be: $><<$<.read.
share|improve this answer
?x yields the ascii code in general, so you can realistically get all the printables to digits in two characters. 1.9 is different, 'a'.ord yields the ascii number, but is four bytes longer than the decimal version. – Hiato Feb 3 '11 at 8:03
You can use ?a.ord in 1.9, but that's still longer than the decimal. – Nemo157 Feb 3 '11 at 22:59
An even golfier way to implement cat is to leave the ruby file completely empty (0 bytes) and insist that it should be run from the command line with the -p flag. – daniero Jul 17 '13 at 20:01
or, from @daniero's own answer, puts *$< – Not that Charles Jul 2 '14 at 19:15

Use the splat operator to get the tail and head of an array:

tail, *head = [1,2,3]
tail => 1
head => [2,3]

This also works the other way:

*head, tail = [1,2,3]
head => [1,2]
tail => 3

Use the * method with a string on arrays to join elements:

=> "1,2,3"
share|improve this answer
  • Use abort to terminate the program and print a string to STDERR - shorter than puts followed by exit
  • If you read a line with gets, you can then use ~/$/ to find its length (this doesn't count a trailing newline if it exists)
  • Use [] to check if a string contains another: 'foo'['f'] #=> 'f'
  • Use tr instead of gsub for character-wise substitutions: '01011'.tr('01','AB') #=> 'ABABB'
  • If you need to remove trailing newlines, use chop instead of chomp
share|improve this answer
+1 for abort and ~/$/ – J-_-L Jun 26 '11 at 22:13

Use the short predefined variables wherever possible, e.g. $* instead of ARGV. There's a good list of them here, along with a lot of other useful information.

share|improve this answer

End your end.

Try to remove end from your code.

Don't use def...end to define functions. Make a lambda with the new -> operator in Ruby 1.9. (The -> operator is a "stabby lambda", or "dash rocket".) This saves 5 characters per function.

# 28 characters
def c n

# 23 characters, saves 5

Method calls are c n or c(n). Lambda calls are c[n]. Changing each c n to c[n] costs 1 character, so if you can use c n more than 5 times, then keep the method.

All methods that take do...end blocks can take {...} blocks instead. This saves 3 to 5 characters. If the precedence of {...} is too high, then use parentheses to fix it.

# 48 characters
(?a..?m).zip (1..5).cycle do|a|puts a.join','end

# WRONG: passes block to cycle, not zip
(?a..?m).zip (1..5).cycle{|a|puts a.join','}

# 45 characters, saves 3
(?a..?m).zip((1..5).cycle){|a|puts a.join','}

Replace if...else...end with the ternary operator ?:. If a branch has two or more statements, wrap them in parentheses.

# 67 characters
if a<b
puts'statement 1'
puts'statement 2'else
puts'statement 3'end

# 62 characters, saves 5
a<b ?(puts'statement 1'
puts'statement 2'):(puts'statement 3')

You probably don't have while or until loops, but if you do, then write them in modifier form.

b-=1)while a<b
share|improve this answer

Addition to w0lf

When working with arrays, .compact can be replaced with -[nil] to save 2 chars.

Combined with above -> you can make it even shorter with -[p] to save another 2 chars.

share|improve this answer

If you need to find if a particular element e is inside a range r, you can use


instead of the longer:

r.cover?(e) # only works if `r.exclude_end?` is false




share|improve this answer
Isn’t r===e even shorter? – akuhn Jun 1 '12 at 21:10
@akuhn Yes, it is. Much Shorter. Thanks for pointing that out, it helped me shorten my code by 10 chars, which is huge: – w0lf Jun 1 '12 at 21:20
You’re welcome. Everything that can be used in a switch statement has === implemented. – akuhn Jun 2 '12 at 12:49

$_ is last read line.

  • print - if no argument given print content of $_
  • ~/regexp/ - short for $_=~/regexp/

In Ruby 1.8, you have four methods in Kernel that operate on $_:

  • chop
  • chomp
  • sub
  • gsub

In Ruby 1.9, these four methods exist only if your script uses -n or -p.

If you want to print some variable often then use trace_var(:var_name){|a|p a}

share|improve this answer
These are only available when you run Ruby with the -p or -n option. Reference. – Darren Stone Dec 27 '13 at 19:12
It seems that trace_var only works with global $variables – daniero Mar 23 at 8:56

Scientific notation can often be used to shave off a char or two:

share|improve this answer
Note: This will return a Float value (1000.0) instead of an Integer, which may cause inaccurate results with large numbers. – Dogbert Feb 25 '11 at 11:02
Ah, nice 1e2 is better than 100.0 when a percentage is needed. – Phrogz Feb 26 '11 at 6:36

Build arrays using a=i,*a to get them in reverse order. You don't even need to initialize a, and if you do it doesn't have to be an array.

share|improve this answer

Use string interpolation!

  1. To replace to_s. If you need parentheses around whatever you want to turn into a string, to_s is two bytes longer than string interpolation:

  2. To replace concatenation. If you concatenate something surrounded by two other strings, interpolation can save you one byte:


    Also works if the middle thing is itself concatenated, if you just move the concatenation inside the interpolation (instead of using multiple interpolations):

share|improve this answer

Don't use the true and false keywords.


  • !p for true (thanks, histocrat!)
  • !0 for false. If all you need is a falsy value, then you can simply use p (which returns nil).

to save some chars.

share|improve this answer
Unless you actually need true (i.e. if a truthy value is enough, like in an if condition), you don't even need !!. – Martin Ender Aug 6 '14 at 6:31
And similarly, p (which evaluates to nil) is a shorter falsey value. Which means the shortest way to get true is !p. – histocrat Aug 6 '14 at 22:17
@histocrat good point! I've edited my answer. – w0lf Aug 7 '14 at 6:26

When you are using string interpolation, (as you should pr Martin Büttner's post), you don't need the curly brackets if your object has a sigil ($, @) in front of it. Useful for magical variables like $_, $&, $1 etc:

puts "this program has read #$. lines of input"

So also if you need to print a variable more than you use it otherwise, you may save some bytes.

a=42; puts "here is a: #{a}"; puts "here is a again: #{a}"
$b=43; puts "here is b: #$b"; puts "here is b again: #$b"
share|improve this answer

If you ever need to get a number from ARGV, get, or something similar to do something that many times, instead of calling to_i on it, you can just use ?1.upto x{do something x times} where x is a string.

So using ?1.upto(a){} instead of x.to_i.times{} will save you 2 characters.

You can also re-write things like p 1 while 1 or p 1 if 1 as p 1while 1 or p 1if 1

That example isn't very useful, but it could be used for other things.

Also, if you need to assign the first element of an array to a variable, a,=c will save two characters as opposed to a=c[0]

share|improve this answer

Avoid length in if a.length<n

length is 6 bytes, a bit costly in code golf. in many situations, you can instead check if the array has anything at a given point. if you grab past the last index you will get nil, a falsey value.

So you can Change:

if a.length<5 to if !a[4] for -5 bytes


if a.length>5 to if a[5] for -6 bytes


if a.length<n to if !a[n-1] for -3 bytes


if a.length>n to if a[n] for -6 bytes

Note: will only work with an array of all truthy values. having nil or false within the array may cause problems.

share|improve this answer
I always use size… But this is definitely better. BTW, works for String too. – manatwork Dec 7 '15 at 17:06

Use || instead or and && instead and.

Beside the one character from and you can save the spaces (and perhaps the bracket) around the operator.

p true and false ? 'yes' :'no'   #-> true (wrong result)
p (true and false) ? 'yes' :'no' #-> 'no'
p true&&false ? 'yes' :'no'      #-> 'no', saved 5 characters

p true or false ? 'yes' :'no'   #-> true (wrong result)
p (true or false) ? 'yes' :'no' #-> 'yes'
p true||false ? 'yes' :'no'      #-> 'yes', saved 4 characters

If you loop on an array you normally use each. But map loops also over an array and it is one character shorter.

share|improve this answer

Kernel#p is a fun method.

Use p var instead of puts var. This works perfectly with integers and floats, but not with all types. It prints quotation marks around strings, which is probably not what you want.

Used with a single argument, p returns the argument after printing it.

Used with multiple arguments, p returns the arguments in an array.

Use p (with no arguments) instead of nil.

share|improve this answer
Unfortunately p 'some string' prints "some string" and not just some string which is often criticised by others. – Patrick Oscity Jun 1 '13 at 21:11

Don't use #each. You can loop over all elements just fine with #map. So instead of

ARGV.each{|x|puts x}

you can do the same in less bytes.{|x|puts x}

Of course, in this case puts $* would be even shorter.

There are literals for rational and complex numbers:

puts 3/11r == Rational(3,11)
puts 3.3r == Rational(66,20)
puts 1-1.i == Complex(1,-1)

=> true

You can use most bytes within strings. "\x01" (6 bytes) can be shortened to "" (3 bytes). If you only need this one byte, this can be shortened even further to ? (2 bytes).

By the same token, you can get newlines shorter like this:


 => "0\n1\n2\n3\n4\n5\n6\n7\n8\n9\n10"

You can use ?\n and ?\t as well, which is one byte shorter than "\n" and "\t". For obfuscation, there also ?\s, a space.

Use constants instead of passing arguments around, even if you need to change them. The interpreter will give warnings to stderr, but who cares. If you need to define more variables related to each other, you can chain them like this:


=> A=17, B=16, C=9

This is shorter than C=9;B=16;A=17 or C=0;B=C+7;A=C+B.

If you need an infinite loop, use loop{...}. Loops of unknown length may be shorter with other loops:

loop{break if'


Some more gsub/regexp tricks. Use the special '\1' escape characters instead of a block:

"golf=great short=awesome".gsub(/(\w+)=(\w+)/,'(\1~>\2)')

"golf=great short=awesome".gsub(/(\w+)=(\w+)/){"(#{$1}~>#{$2})")

And the special variables $1 etc. if you need to perform operations. Keep in mind they are defined not only inside the block:

"A code-golf challenge." =~ /(\w+)-(\w+)/
p [$1,$2,$`,$']

=> ["code", "golf", "A ", " challenge."] 

Get rid of spaces, newlines, and parentheses. You can omit quite a bit in ruby. If in doubt, always try if it works without, and keep in mind this might break some editor syntax highlighting...

share|improve this answer
"Please post one tip per answer." Also ?\n is nice, but not really shorter than actually putting a newline character inside quotes. (same for tab) – Martin Ender May 7 '15 at 23:29

If the first line starts with #! and contains ruby, then Ruby will take command-line switches from it.

For example, if you require two libraries, you can golf



#!ruby -rbenchmark -rprime

which saves 7 bytes.

share|improve this answer
Or you can just add -rbenchmark -rprime to the character/byte count. That's usual in choice golf. – nyuszika7h Jul 5 '14 at 12:21

When a challenge requires that you output multiple lines, you don't have to loop through your results in order to print each line of e.g. an array. The puts method will flatten an array and print each element on a separate line.

> a = %w(testing one two three)
> puts a

Combining the splat operator with #p you can make it even shorter:

p *a

The splat operator (technically the *@ method, I think) also casts your non-array enumerables to arrays:

> p{|x|x*2}
#<Enumerator::Lazy: #<Enumerator::Lazy: [1, 2, 3]>:map>


> p *{|x|x*2}
share|improve this answer

I just attempted a TDD code-golf challenge i.e. Write shortest code to make specs pass. The specs were something like

describe PigLatin do
  describe '.translate' do
    it 'translates "cat" to "atcay"' do
      expect(PigLatin.translate('cat')).to eq('atcay')
    # And similar examples for .translate

For the sake of code-golf, one need not create a module or class.

Instead of

module PigLatin def self.translate s;'some code'end;end

one can do

def(PigLatin=p).translate s;'some code'end

Saves 13 characters!

share|improve this answer
Ha, very thorough. Not only did you add the necessary behavior to PigLatin, but also to @pig_latin, $pig_latin, and 'pig'['latin']. – histocrat Feb 27 '14 at 15:23

When working with arrays, .compact can be replaced with -[nil] to save 2 chars.

share|improve this answer

Yet another way to use the splat operator: if you want to assign a single array literal, a * on the left-hand side is shorter than brackets on the right-hand side:


With multiple values you don't even need the splat operator (thanks to histocrat for correcting me on that):

share|improve this answer
The latter case doesn't actually need the splat. – histocrat Aug 15 '15 at 22:53
@histocrat Oh wow, I thought the second value would just be discarded in that case. – Martin Ender Aug 15 '15 at 22:53
I can't believe I haven't known these in all the time I've spent golfing in Ruby. – Doorknob Jan 2 at 3:07

Subscripting Numbers!

I just discovered this yesterday. n[i] returns n's bit at the i-th position. Example:

irb(main):001:0> n = 0b11010010
=> 210
irb(main):002:0> n [0]
=> 0
irb(main):003:0> n [1]
=> 1
irb(main):004:0> n [2]
=> 0
irb(main):005:0> n [3]
=> 0
irb(main):006:0> n [4]
=> 1
irb(main):007:0> n [5]
=> 0
share|improve this answer

Use Goruby instead of Ruby, which is something like an abbreviated version of Ruby. You can install it with rvm via

rvm install goruby

Goruby allows you to write most of your code as you would be writing Ruby, but has additional abbreviations built in. To find out the shortest available abbreviation for something, you can use the helper method shortest_abbreviation, for example:

shortest_abbreviation :puts
#=> "pts" :map
#=> "m" :capitalize
#=> "cp" :join
#=> "j"

Also very handy is the alias say for puts which itself can be abbreviated with s. So instead of

puts [*?a..?z].map(&:capitalize).join

you can now write

s [*?a..?z].m(&:cp).j

to print the alphabet in capitals (which is not avery good example). This blog post explains more stuff and some of the inner workings if you are interested in further reading.

PS: don't miss out on the h method ;-)

share|improve this answer
More than 2 years later and I finally figured out what this answer reminds me of... – undergroundmonorail May 22 '15 at 13:53

You may be able to save 2 chars and use


instead of


For example, suppose we have a range that we want as an array:


Just do it like this:

[*1..2000]  #  Parentheses around the ( is not needed!

And now you have your range as an array.

share|improve this answer
I think [*1..2000] works, too? – Lynn Aug 24 '15 at 18:38

When getting input of fixed length the optional integer parameter to gets may come in handy.

  • Getting a substring:

    gets 10 vs gets[0,10] -- saves 3 bytes

  • Cutting trailing newline:

    gets 10 vs gets.chop -- saves 3 - log10(required_length) bytes (= 2 in this case)

share|improve this answer

To check if a is an Array, instead of doing:


you can do


Won't work if a can be a string that contains [.

share|improve this answer
Or use the triple equals thing: Array===a ;) – daniero Jun 26 '15 at 23:33

<< trick

a.push x

can be shortened to:


for -4 bytes.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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