From 3ecc79d7956eadb9bdf4df281bd65de15f49e764 Mon Sep 17 00:00:00 2001 From: Tomas Norre Mikkelsen Date: Thu, 22 Feb 2024 21:13:56 +0100 Subject: [PATCH 1/2] Add Rotational Cipher Exercise --- config.json | 8 ++ .../rotational-cipher/.docs/instructions.md | 29 +++++ .../rotational-cipher/.meta/config.json | 19 +++ .../rotational-cipher/.meta/example.php | 22 ++++ .../rotational-cipher/.meta/tests.toml | 40 ++++++ .../rotational-cipher/RotationalCipher.php | 33 +++++ .../RotationalCipherTest.php | 118 ++++++++++++++++++ 7 files changed, 269 insertions(+) create mode 100644 exercises/practice/rotational-cipher/.docs/instructions.md create mode 100644 exercises/practice/rotational-cipher/.meta/config.json create mode 100644 exercises/practice/rotational-cipher/.meta/example.php create mode 100644 exercises/practice/rotational-cipher/.meta/tests.toml create mode 100644 exercises/practice/rotational-cipher/RotationalCipher.php create mode 100644 exercises/practice/rotational-cipher/RotationalCipherTest.php diff --git a/config.json b/config.json index d4e98233..9bd0ab9b 100644 --- a/config.json +++ b/config.json @@ -1195,6 +1195,14 @@ "practices": [], "prerequisites": [], "difficulty": 3 + }, + { + "slug": "rotational-cipher", + "name": "Rotational Cipher", + "uuid": "61add6ab-9eaa-4fbc-b060-8ac44f47fad7", + "practices": [], + "prerequisites": [], + "difficulty": 3 } ] }, diff --git a/exercises/practice/rotational-cipher/.docs/instructions.md b/exercises/practice/rotational-cipher/.docs/instructions.md new file mode 100644 index 00000000..4bf64ca1 --- /dev/null +++ b/exercises/practice/rotational-cipher/.docs/instructions.md @@ -0,0 +1,29 @@ +# 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 + `. +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.` diff --git a/exercises/practice/rotational-cipher/.meta/config.json b/exercises/practice/rotational-cipher/.meta/config.json new file mode 100644 index 00000000..21704bfc --- /dev/null +++ b/exercises/practice/rotational-cipher/.meta/config.json @@ -0,0 +1,19 @@ +{ + "authors": [ + "tomasnorre" + ], + "files": { + "solution": [ + "RotationalCipher.php" + ], + "test": [ + "RotationalCipherTest.php" + ], + "example": [ + ".meta/example.php" + ] + }, + "blurb": "Create an implementation of the rotational cipher, also sometimes called the Caesar cipher.", + "source": "Wikipedia", + "source_url": "https://en.wikipedia.org/wiki/Caesar_cipher" +} diff --git a/exercises/practice/rotational-cipher/.meta/example.php b/exercises/practice/rotational-cipher/.meta/example.php new file mode 100644 index 00000000..1b2356ff --- /dev/null +++ b/exercises/practice/rotational-cipher/.meta/example.php @@ -0,0 +1,22 @@ +. + * + * To disable strict typing, comment out the directive below. + */ + +declare(strict_types=1); + +class RotationalCipher +{ + public function rotate(string $text, int $shift): string + { + throw new \BadMethodCallException(sprintf('Implement the %s method', __FUNCTION__)); + } +} diff --git a/exercises/practice/rotational-cipher/RotationalCipherTest.php b/exercises/practice/rotational-cipher/RotationalCipherTest.php new file mode 100644 index 00000000..dfdcc3c2 --- /dev/null +++ b/exercises/practice/rotational-cipher/RotationalCipherTest.php @@ -0,0 +1,118 @@ +rotationalCipher = new RotationalCipher(); + } + + /** + * uuid: 74e58a38-e484-43f1-9466-877a7515e10f + */ + public function testRotateAByZero(): void + { + $expected = 'a'; + $actual = $this->rotationalCipher->rotate('a', 0); + $this->assertEquals($expected, $actual); + } + + /** + * uuid: 7ee352c6-e6b0-4930-b903-d09943ecb8f5 + */ + public function testRotateAByOne(): void + { + $expected = 'b'; + $actual = $this->rotationalCipher->rotate('a', 1); + $this->assertEquals($expected, $actual); + } + + /** + * uuid: edf0a733-4231-4594-a5ee-46a4009ad764 + */ + public function testRotateABy26(): void + { + $expected = 'a'; + $actual = $this->rotationalCipher->rotate('a', 26); + $this->assertEquals($expected, $actual); + } + + /** + * uuid: e3e82cb9-2a5b-403f-9931-e43213879300 + */ + public function testRotateMBy13(): void + { + $expected = 'z'; + $actual = $this->rotationalCipher->rotate('m', 13); + $this->assertEquals($expected, $actual); + } + + /** + * uuid: 19f9eb78-e2ad-4da4-8fe3-9291d47c1709 + */ + public function testRotateNBy13WithWrapAroundAlphabet(): void + { + $expected = 'a'; + $actual = $this->rotationalCipher->rotate('n', 13); + $this->assertEquals($expected, $actual); + } + + /** + * uuid: a116aef4-225b-4da9-884f-e8023ca6408a + */ + public function testRotateCapitalLetters(): void + { + $expected = 'TRL'; + $actual = $this->rotationalCipher->rotate('OMG', 5); + $this->assertEquals($expected, $actual); + } + + /** + * uuid: 71b541bb-819c-4dc6-a9c3-132ef9bb737b + */ + public function testRotateSpaces(): void + { + $expected = 'T R L'; + $actual = $this->rotationalCipher->rotate('O M G', 5); + $this->assertEquals($expected, $actual); + } + + /** + * uuid: ef32601d-e9ef-4b29-b2b5-8971392282e6 + */ + public function testRotateNumbers(): void + { + $expected = 'Xiwxmrk 1 2 3 xiwxmrk'; + $actual = $this->rotationalCipher->rotate('Testing 1 2 3 testing', 4); + $this->assertEquals($expected, $actual); + } + + /** + * uuid: 32dd74f6-db2b-41a6-b02c-82eb4f93e549 + */ + public function testRotatePunctuation(): void + { + $expected = "Gzo'n zvo, Bmviyhv!"; + $actual = $this->rotationalCipher->rotate("Let's eat, Grandma!", 21); + $this->assertEquals($expected, $actual); + } + + /** + * uuid: 9fb93fe6-42b0-46e6-9ec1-0bf0a062d8c9 + */ + public function testRotateAllLetters(): void + { + $expected = 'Gur dhvpx oebja sbk whzcf bire gur ynml qbt.'; + $actual = $this->rotationalCipher->rotate('The quick brown fox jumps over the lazy dog.', 13); + $this->assertEquals($expected, $actual); + } +} From 4a1870cab0261fd2db3e39957d09851a04b6df8e Mon Sep 17 00:00:00 2001 From: Tomas Norre Mikkelsen Date: Fri, 23 Feb 2024 08:49:39 +0100 Subject: [PATCH 2/2] Add instructions.append.md --- .../practice/rotational-cipher/.docs/instructions.append.md | 3 +++ 1 file changed, 3 insertions(+) create mode 100644 exercises/practice/rotational-cipher/.docs/instructions.append.md diff --git a/exercises/practice/rotational-cipher/.docs/instructions.append.md b/exercises/practice/rotational-cipher/.docs/instructions.append.md new file mode 100644 index 00000000..9104d76c --- /dev/null +++ b/exercises/practice/rotational-cipher/.docs/instructions.append.md @@ -0,0 +1,3 @@ +~~~~exercism/note +Do not use PHP functions like `str_rot13()` to solve this exercise! Only use basic string and character manipulation functions. +~~~~