Skip to content

Instantly share code, notes, and snippets.

@hashlash
Last active May 29, 2020 08:19
Show Gist options
  • Save hashlash/63edd5ab69cafe6ef762023e1cacc7ef to your computer and use it in GitHub Desktop.
Save hashlash/63edd5ab69cafe6ef762023e1cacc7ef to your computer and use it in GitHub Desktop.
A Tour of Go Exercise: rot13Reader https://tour.golang.org/methods/23

Some simple points that I think this code looks great:

  • Doesn't need any additional function(s)

  • Concise if case error handling, instead of:

    ...
    if err != nil {
        return nil, err
    }
    // do the 13-rotation
    return l, nil
  • Only 2 switch cases: lower and upper cases

    • Utilize mod (%) instead of dividing to 'A'-'M' and 'N'-'Z' additional cases
  • Use the character representation ('A', 'Z', 'a', 'z') instead of others, such as 65 (decimal ascii of 'A'), 0x41 (hex ascii of 'A'), etc

  • Arrange the range cases to looks like comparison chaining 'A' <= b[i] <= 'Z'

package main
import (
"io"
"os"
"strings"
)
type rot13Reader struct {
r io.Reader
}
func (r13 rot13Reader) Read(b []byte) (int, error) {
l, err := r13.r.Read(b)
if err == nil {
for i := range b {
switch {
case 'A' <= b[i] && b[i] <= 'Z':
b[i] = (b[i] - 'A' + 13) % 26 + 'A'
case 'a' <= b[i] && b[i] <= 'z':
b[i] = (b[i] - 'a' + 13) % 26 + 'a'
}
}
}
return l, err
}
func main() {
s := strings.NewReader("Lbh penpxrq gur pbqr!")
r := rot13Reader{s}
io.Copy(os.Stdout, &r)
}
@hashlash
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment