Skip to content

Commit ee96091

Browse files
authored
Merge pull request exercism#273 from behrtam/implement-rail-fence-cipher
rail-fence-cipher: Implement new exercise
2 parents 66fe931 + d199930 commit ee96091

3 files changed

Lines changed: 52 additions & 0 deletions

File tree

config.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
"circular-buffer",
4444
"robot-name",
4545
"matrix",
46+
"rail-fence-cipher",
4647
"nth-prime",
4748
"saddle-points",
4849
"beer-song",

rail-fence-cipher/example.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
from itertools import cycle, chain
2+
3+
4+
def fence_pattern(rails, size):
5+
zig_zag = cycle(chain(range(rails), range(rails - 2, 0, -1)))
6+
return zip(zig_zag, range(size))
7+
8+
9+
def encode(msg, rails):
10+
fence = fence_pattern(rails, len(msg))
11+
return ''.join(msg[i] for _, i in sorted(fence))
12+
13+
14+
def decode(msg, rails):
15+
fence = fence_pattern(rails, len(msg))
16+
fence_msg = zip(msg, sorted(fence))
17+
return ''.join(char for char, _ in sorted(fence_msg, key=lambda item: item[1][1]))
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
import unittest
2+
3+
from rail_fence_cipher import encode, decode
4+
5+
6+
class RailFenceTests(unittest.TestCase):
7+
8+
def test_encode_with_two_rails(self):
9+
self.assertMultiLineEqual('XXXXXXXXXOOOOOOOOO',
10+
encode('XOXOXOXOXOXOXOXOXO', 2))
11+
12+
def test_encode_with_three_rails(self):
13+
self.assertMultiLineEqual('WECRLTEERDSOEEFEAOCAIVDEN',
14+
encode('WEAREDISCOVEREDFLEEATONCE', 3))
15+
16+
def test_encode_with_middle_stop(self):
17+
self.assertMultiLineEqual('ESXIEECSR', encode('EXERCISES', 4))
18+
19+
def test_decode_with_three_rails(self):
20+
self.assertMultiLineEqual('THEDEVILISINTHEDETAILS',
21+
decode('TEITELHDVLSNHDTISEIIEA', 3))
22+
23+
def test_decode_with_five_rails(self):
24+
self.assertMultiLineEqual('EXERCISMISAWESOME',
25+
decode('EIEXMSMESAORIWSCE', 5))
26+
27+
def test_decode_with_six_rails(self):
28+
self.assertMultiLineEqual(
29+
'112358132134558914423337761098715972584418167651094617711286',
30+
decode('133714114238148966225439541018335470986172518171757571896261', 6)
31+
)
32+
33+
if __name__ == '__main__':
34+
unittest.main()

0 commit comments

Comments
 (0)