A go/rotational-cipher/.exercism/config.json => go/rotational-cipher/.exercism/config.json +27 -0
@@ 0,0 1,27 @@
+{
+ "blurb": "Create an implementation of the rotational cipher, also sometimes called the Caesar cipher.",
+ "authors": [
+ "magic003"
+ ],
+ "contributors": [
+ "bitfield",
+ "ekingery",
+ "ferhatelmas",
+ "hilary",
+ "leenipper",
+ "sebito91"
+ ],
+ "files": {
+ "solution": [
+ "rotational_cipher.go"
+ ],
+ "test": [
+ "rotational_cipher_test.go"
+ ],
+ "example": [
+ ".meta/example.go"
+ ]
+ },
+ "source": "Wikipedia",
+ "source_url": "https://en.wikipedia.org/wiki/Caesar_cipher"
+}
A go/rotational-cipher/.exercism/metadata.json => go/rotational-cipher/.exercism/metadata.json +1 -0
@@ 0,0 1,1 @@
+{"track":"go","exercise":"rotational-cipher","id":"92ea268b879143a598b0732cfdf534ba","url":"https://exercism.org/tracks/go/exercises/rotational-cipher","handle":"telemachus","is_requester":true,"auto_approve":false}<
\ No newline at end of file
A go/rotational-cipher/HELP.md => go/rotational-cipher/HELP.md +40 -0
@@ 0,0 1,40 @@
+# Help
+
+## Running the tests
+
+To run the tests run the command `go test` from within the exercise directory.
+
+If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem`
+flags:
+
+ go test -v --bench . --benchmem
+
+Keep in mind that each reviewer will run benchmarks on a different machine, with
+different specs, so the results from these benchmark tests may vary.
+
+## Submitting your solution
+
+You can submit your solution using the `exercism submit rotational_cipher.go` command.
+This command will upload your solution to the Exercism website and print the solution page's URL.
+
+It's possible to submit an incomplete solution which allows you to:
+
+- See how others have completed the exercise
+- Request help from a mentor
+
+## Need to get help?
+
+If you'd like help solving the exercise, check the following pages:
+
+- The [Go track's documentation](https://exercism.org/docs/tracks/go)
+- [Exercism's support channel on gitter](https://gitter.im/exercism/support)
+- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs)
+
+Should those resources not suffice, you could submit your (incomplete) solution to request mentoring.
+
+To get help if you're having trouble, you can use one of the following resources:
+
+- [How to Write Go Code](https://golang.org/doc/code.html)
+- [Effective Go](https://golang.org/doc/effective_go.html)
+- [Go Resources](http://golang.org/help)
+- [StackOverflow](http://stackoverflow.com/questions/tagged/go)<
\ No newline at end of file
A go/rotational-cipher/README.md => go/rotational-cipher/README.md +55 -0
@@ 0,0 1,55 @@
+# Rotational Cipher
+
+Welcome to Rotational Cipher on Exercism's Go Track.
+If you need help running the tests or submitting your code, check out `HELP.md`.
+
+## Instructions
+
+Create an implementation of the rotational cipher, also sometimes called the Caesar cipher.
+
+The Caesar cipher is a simple shift cipher that relies on
+transposing all the letters in the alphabet using an integer key
+between `0` and `26`. Using a key of `0` or `26` will always yield
+the same output due to modular arithmetic. The letter is shifted
+for as many values as the value of the key.
+
+The general notation for rotational ciphers is `ROT + <key>`.
+The most commonly used rotational cipher is `ROT13`.
+
+A `ROT13` on the Latin alphabet would be as follows:
+
+```text
+Plain: abcdefghijklmnopqrstuvwxyz
+Cipher: nopqrstuvwxyzabcdefghijklm
+```
+
+It is stronger than the Atbash cipher because it has 27 possible keys, and 25 usable keys.
+
+Ciphertext is written out in the same formatting as the input including spaces and punctuation.
+
+## Examples
+
+- ROT5 `omg` gives `trl`
+- ROT0 `c` gives `c`
+- ROT26 `Cool` gives `Cool`
+- ROT13 `The quick brown fox jumps over the lazy dog.` gives `Gur dhvpx oebja sbk whzcf bire gur ynml qbt.`
+- ROT13 `Gur dhvpx oebja sbk whzcf bire gur ynml qbt.` gives `The quick brown fox jumps over the lazy dog.`
+
+## Source
+
+### Created by
+
+- @magic003
+
+### Contributed to by
+
+- @bitfield
+- @ekingery
+- @ferhatelmas
+- @hilary
+- @leenipper
+- @sebito91
+
+### Based on
+
+Wikipedia - https://en.wikipedia.org/wiki/Caesar_cipher<
\ No newline at end of file
A go/rotational-cipher/go.mod => go/rotational-cipher/go.mod +3 -0
@@ 0,0 1,3 @@
+module rotationalcipher
+
+go 1.16
A go/rotational-cipher/rotational_cipher.go => go/rotational-cipher/rotational_cipher.go +20 -0
@@ 0,0 1,20 @@
+package rotationalcipher
+
+import "strings"
+
+func RotationalCipher(plain string, shiftKey int) string {
+ var rot strings.Builder
+ shiftByte := byte(shiftKey)
+ // Assume ASCII input.
+ for _, c := range []byte(plain) {
+ switch {
+ case c >= 'a' && c <= 'z':
+ rot.WriteByte(((c - 'a' + shiftByte) % 26) + 'a')
+ case c >= 'A' && c <= 'Z':
+ rot.WriteByte(((c - 'A' + shiftByte) % 26) + 'A')
+ default:
+ rot.WriteByte(c)
+ }
+ }
+ return rot.String()
+}
A go/rotational-cipher/rotational_cipher_test.go => go/rotational-cipher/rotational_cipher_test.go +89 -0
@@ 0,0 1,89 @@
+package rotationalcipher
+
+import (
+ "testing"
+)
+
+var testCases = []struct {
+ description string
+ inputPlain string
+ inputShiftKey int
+ expected string
+}{
+ {
+ description: "rotate a by 0, same output as input",
+ inputPlain: "a",
+ inputShiftKey: 0,
+ expected: "a",
+ },
+ {
+ description: "rotate a by 1",
+ inputPlain: "a",
+ inputShiftKey: 1,
+ expected: "b",
+ },
+ {
+ description: "rotate a by 26, same output as input",
+ inputPlain: "a",
+ inputShiftKey: 26,
+ expected: "a",
+ },
+ {
+ description: "rotate n by 13 with wrap around alphabet",
+ inputPlain: "n",
+ inputShiftKey: 13,
+ expected: "a",
+ },
+ {
+ description: "rotate capital letters",
+ inputPlain: "OMG",
+ inputShiftKey: 5,
+ expected: "TRL",
+ },
+ {
+ description: "rotate spaces",
+ inputPlain: "O M G",
+ inputShiftKey: 5,
+ expected: "T R L",
+ },
+ {
+ description: "rotate numbers",
+ inputPlain: "Testing 1 2 3 testing",
+ inputShiftKey: 4,
+ expected: "Xiwxmrk 1 2 3 xiwxmrk",
+ },
+ {
+ description: "rotate punctuation",
+ inputPlain: "Let's eat, Grandma!",
+ inputShiftKey: 21,
+ expected: "Gzo'n zvo, Bmviyhv!",
+ },
+ {
+ description: "rotate all letters",
+ inputPlain: "The quick brown fox jumps over the lazy dog.",
+ inputShiftKey: 13,
+ expected: "Gur dhvpx oebja sbk whzcf bire gur ynml qbt.",
+ },
+}
+
+func TestRotationalCipher(t *testing.T) {
+ for _, testCase := range testCases {
+ cipher := RotationalCipher(testCase.inputPlain, testCase.inputShiftKey)
+ if cipher != testCase.expected {
+ t.Fatalf("FAIL: %s\n\tRotationalCipher(%s, %d)\nexpected: %s, \ngot: %s",
+ testCase.description, testCase.inputPlain, testCase.inputShiftKey, testCase.expected, cipher)
+ }
+ t.Logf("PASS: %s", testCase.description)
+ }
+}
+
+func BenchmarkRotationalCipher(b *testing.B) {
+ if testing.Short() {
+ b.Skip("skipping benchmark in short mode.")
+ }
+ for i := 0; i < b.N; i++ {
+ for _, testCase := range testCases {
+ RotationalCipher(testCase.inputPlain, testCase.inputShiftKey)
+ }
+ }
+}