|
| 1 | +--- |
| 2 | +title: Golfing Basics |
| 3 | +date: 2015-05-27 |
| 4 | +tags: syntax, golf, strings |
| 5 | +--- |
| 6 | + |
| 7 | +**Code Golf** is the art of writing the shortest program possible. The less bytes the better. And the competition is just ridiculously strong! Head over to [Anarchy Golf](http://golf.shinh.org/) if you want to see more! |
| 8 | + |
| 9 | +ARTICLE |
| 10 | + |
| 11 | +A good beginner's problem is printing out [Pascal's Triangle](http://golf.shinh.org/p.rb?pascal+triangle): Spend a few days to get to **45** bytes. Spend a few *months* to get to **43** bytes! |
| 12 | + |
| 13 | +## 10 Ruby Tricks You'll Learn by Playing Code Golf |
| 14 | + |
| 15 | +While code golfing does not necessarily make you a better programmer, you can learn a lot about the programming language you are using. Here are some things that were new to me: |
| 16 | + |
| 17 | +## Dirty Interpolation |
| 18 | + |
| 19 | +String interpolation (`#{}`) is sometimes possible without using curlies: |
| 20 | + |
| 21 | + "You can directly interpolate #@instance variables, " \ |
| 22 | + "#@@class variables, and #$global variables!" |
| 23 | + |
| 24 | +I must admit, this can confuse newcomers, but it looks fantastic! |
| 25 | + |
| 26 | +## Constant Assignment in Modifiers |
| 27 | + |
| 28 | +It is perfectly legit to use assignments in conditions: |
| 29 | + |
| 30 | + if a = 42 |
| 31 | + p a |
| 32 | + end |
| 33 | + # => 42 |
| 34 | + |
| 35 | + However, this won't work with the shorter *modifier* syntax: |
| 36 | + |
| 37 | + p b if b = 42 |
| 38 | + # NameError: undefined local variable or method `b'... |
| 39 | + |
| 40 | +Unless… you use constants: |
| 41 | + |
| 42 | + p C if C = 42 |
| 43 | + # => 42 |
| 44 | + |
| 45 | +## Shebang `require` |
| 46 | + |
| 47 | +What could possibly be shorter than: |
| 48 | + |
| 49 | + require'json'; require 'yaml' |
| 50 | + p JSON,YAML |
| 51 | + |
| 52 | +It's inlined command-line options: |
| 53 | + |
| 54 | + #!ruby -rjson -ryaml |
| 55 | + p JSON,YAML |
| 56 | + |
| 57 | +## Iterating Input Lines |
| 58 | + |
| 59 | +Finding the shortest way to read user input is a common problem for golfers and solutions vary, depending on how to process the input. My favorite one is to iterate over the input's lines: |
| 60 | + |
| 61 | + $<.each{|e|p e} |
| 62 | + |
| 63 | +## Appending Output |
| 64 | + |
| 65 | +`puts` and `p` are already good candidates to output content. However, sometimes, using `<<` on `STDOUT` is a tiny bit (or byte) more efficent: |
| 66 | + |
| 67 | + ?a.upto(?z){|o|$><<o} |
| 68 | + |
| 69 | +## Regex Always Wins |
| 70 | + |
| 71 | +This is one of the golden rules of golfing. Especially, combining the [block syntax of `gsub`](http://ruby-doc.org/core-2.2.2/String.html#method-i-gsub) with the [perlish regex variables](http://idiosyncratic-ruby.com/9-globalization.html) can be very expressive! |
| 72 | + |
| 73 | + "some_string".gsub(/(^|_)(\w)/){$2.upcase} |
| 74 | + |
| 75 | +## `String#tr` |
| 76 | + |
| 77 | +However, it's not true - regexes do not always win. If you need to perform some simple character substitutions, [tr](https://en.wikipedia.org/wiki/Tr_%28Unix%29) is an extremly short (and also clean) way to do so: |
| 78 | + |
| 79 | + # ROT13 Cipher |
| 80 | + "Vqvbflapengvp Ehol".tr'a-zA-Z','n-za-mN-ZA-M' |
| 81 | + # => "Idiosyncratic Ruby" |
| 82 | + |
| 83 | +## One More or Less |
| 84 | + |
| 85 | +In some instances, you cannot use `i+1` or `i-1` without wrapping them in parenthesis. No problem, [unary complement](http://ruby-doc.org/core-2.2.2/Fixnum.html#method-i-7E) to the rescue: |
| 86 | + |
| 87 | + -~42 # => 43 |
| 88 | + ~-42 # => 41 |
| 89 | + |
| 90 | +## Flexible Precedence |
| 91 | + |
| 92 | +This is one of my favorites: Explicitely call (`.`) operators for alternative precedence semantics: |
| 93 | + |
| 94 | + 3*(2+1) #=> 9 |
| 95 | + 3.*2+1 #=> 9 |
| 96 | + |
| 97 | +## Quick Quit |
| 98 | + |
| 99 | +What's a shorter way to quit a Ruby script than the 4 bytes long `exit` method? |
| 100 | + |
| 101 | + 1/0 |
0 commit comments