notes.dt.in.th

These are some Ruby code-golfing tricks I learned from playing Clash of Code. These tricks can help when playing the "shortest" mode but excessively using these tricks can lead to less readable code.

#sum accepts a block:

"1 2 3".split.map(&:to_i).sum
"1 2 3".split.sum(&:to_i)

$> is STDOUT:

print 1
$><<1

$< is STDIN:

STDIN.to_a
$<.to_a

[*x] is x.to_a:

$<.to_a
[*$<]

Range does not need an ending:

"hello"[3..-1]
"hello"[3..]

Range has #% to iterate with desired step:

[*(1..10).step(3)]
[*(1..10) % 3]

[*(10..1).step(-1)]
[*(10..1) % -1]

Integer has #digits:

1234.to_s.chars.map(&:to_i)
1234.digits.reverse

One-character can be presented using ?:

"a"
?a

'"'
?"

Generate a fixed-size array using a block with n.times.map:

Array.new(10){|x|x*x}
10.times.map{|x|x*x}

To check if any of the numbers are 0, multiply them together and check once:

a==0||b==0
a*b==0

You can assign things to variable without a parens if it’s the rightmost term:

a=2;b=3*a
b=3*a=2    # equivalent to b=3*(a=2)

Ruby doesn’t usually coerce strings to numbers (and this can be annoying when codegolfing) but it does coerce string to number when formatting:

"1234".to_i.to_s(2)
"%b" % "1234"

Hashes have to_proc:

names.map { |name| things[name] }
names.map(&things)

Hashes have transform_values:

hash.map { |k, v| [k, f(v)] }.to_h
hash.transform_values { |v| f v }

Enumerables have grep and grep_v (for inverse):

(1..100).select { |x| (38..44).include? x }
(1..100).select { |x| (38..44) === x }
(1..100).grep 38..44

Numbers (actually, any Comparable) can be clamped:

[[progress, 0].max, 100].min
progress.clamp(0, 100)

Integer#pow can take a modulus:

2.pow(12345678) % 10000   # works, but slow
2.pow(12345678, 10000)    # very fast

2.pow(123456789) % 10000  # => NaN + warning: in a**b, b may be too big
2.pow(123456789, 10000)   # => 6112