Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"pythagorean-triplet",
"robot-name",
"matrix",
"rail-fence-cipher",
"nth-prime",
"saddle-points",
"beer-song",
Expand Down
17 changes: 17 additions & 0 deletions rail-fence-cipher/example.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
from itertools import cycle, chain


def fence_pattern(rails, size):
zig_zag = cycle(chain(range(rails), range(rails - 2, 0, -1)))
return zip(zig_zag, range(size))


def encode(msg, rails):
fence = fence_pattern(rails, len(msg))
return ''.join(msg[i] for _, i in sorted(fence))


def decode(msg, rails):
fence = fence_pattern(rails, len(msg))
fence_msg = zip(msg, sorted(fence))
return ''.join(char for char, _ in sorted(fence_msg, key=lambda item: item[1][1]))
34 changes: 34 additions & 0 deletions rail-fence-cipher/rail_fence_cipher_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import unittest

from rail_fence_cipher import encode, decode


class RailFenceTests(unittest.TestCase):

def test_encode_with_two_rails(self):
self.assertMultiLineEqual('XXXXXXXXXOOOOOOOOO',
encode('XOXOXOXOXOXOXOXOXO', 2))

def test_encode_with_three_rails(self):
self.assertMultiLineEqual('WECRLTEERDSOEEFEAOCAIVDEN',
encode('WEAREDISCOVEREDFLEEATONCE', 3))

def test_encode_with_middle_stop(self):
self.assertMultiLineEqual('ESXIEECSR', encode('EXERCISES', 4))

def test_decode_with_three_rails(self):
self.assertMultiLineEqual('THEDEVILISINTHEDETAILS',
decode('TEITELHDVLSNHDTISEIIEA', 3))

def test_decode_with_five_rails(self):
self.assertMultiLineEqual('EXERCISMISAWESOME',
decode('EIEXMSMESAORIWSCE', 5))

def test_decode_with_six_rails(self):
self.assertMultiLineEqual(
'112358132134558914423337761098715972584418167651094617711286',
decode('133714114238148966225439541018335470986172518171757571896261', 6)
)

if __name__ == '__main__':
unittest.main()