--- /dev/null
+---
+jupyter:
+ jupytext:
+ formats: ipynb,md
+ text_representation:
+ extension: .md
+ format_name: markdown
+ format_version: '1.2'
+ jupytext_version: 1.3.4
+ kernelspec:
+ display_name: Python 3
+ language: python
+ name: python3
+---
+
+```python
+import os,sys,inspect
+currentdir = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe())))
+parentdir = os.path.dirname(currentdir)
+sys.path.insert(0,parentdir)
+```
+
+```python
+from cipher.caesar import *
+from cipher.affine import *
+from cipher.keyword_cipher import *
+from cipher.column_transposition import *
+from cipher.vigenere import *
+from cipher.autokey import *
+
+from support.text_prettify import *
+from support.utilities import *
+from support.plot_frequency_histogram import *
+%matplotlib inline
+```
+
+```python
+challenge_number = 9
+plaintext_a_filename = f'{challenge_number}a.plaintext'
+plaintext_b_filename = f'{challenge_number}b.plaintext'
+ciphertext_a_filename = f'{challenge_number}a.ciphertext'
+ciphertext_b_filename = f'{challenge_number}b.ciphertext'
+```
+
+```python
+ca = open(ciphertext_a_filename).read()
+cb = open(ciphertext_b_filename).read()
+
+sca = sanitise(ca)
+pca = letters(ca)
+pta = depunctuate(ca)
+
+scb = sanitise(cb)
+pcb = letters(cb)
+ptb = depunctuate(cb)
+```
+
+```python
+fc = collections.Counter(sca)
+plot_frequency_histogram(fc, sort_key=fc.get)
+```
+
+```python
+kworda, score = vigenere_frequency_break(sca, fitness=Ptrigrams)
+kworda
+```
+
+```python
+pa = vigenere_decipher(sca, kworda)
+pa
+```
+
+```python
+fpa = lcat(tpack(segment(pa)))
+print(fpa)
+```
+
+```python
+open(plaintext_a_filename, 'w').write(fpa)
+```
+
+```python
+morse_letters = {}
+morse_codes = {}
+with open('morse.txt') as f:
+ for line in f.readlines():
+ l, c = line.split()
+ morse_letters[c] = l
+ morse_codes[l] = c
+morse_letters
+```
+
+```python
+mcb = wcat(cat(morse_letters[l] for l in w.split()) for w in cb.split(' / '))
+smcb = sanitise(mcb)
+mcb
+```
+
+```python
+fc = collections.Counter(sanitise(mcb))
+plot_frequency_histogram(fc, sort_key=fc.get)
+```
+
+```python
+index_of_coincidence_scan(smcb, max_key_length=30)
+```
+
+```python
+kwordb, score = vigenere_frequency_break(smcb, fitness=Ptrigrams, max_key_length=30)
+kwordb
+```
+
+```python
+kwordb, score = autokey_sa_break(smcb, fitness=Ptrigrams, max_keylength=10, max_iterations=5000)
+kwordb
+```
+
+```python
+autokey_decipher(smcb, kwordb)
+```
+
+```python
+tgs = [smcb[i:i+3] for i in range(len(smcb)-2)]
+collections.Counter(tgs).most_common(10)
+```
+
+```python
+wcat(w for w in mcb.split() if len(w) == 3)
+```
+
+```python
+wcat(w if len(w) >= 3 and w.lower() in keywords else w.lower()
+ for w in mcb.split())
+```
+
+```python
+[(i, w) for i, w in enumerate(mcb.split())
+ if len(w) >= 3
+ if w.lower() in keywords ]
+```
+
+```python
+[(i, w) for i, w in enumerate(mcb.split())
+ if i % 26 == 25 ]
+```
+
+```python
+pb = wcat(caesar_decipher(w, i + 1) for i, w in enumerate(mcb.split()))
+pb
+```
+
+```python
+open(plaintext_b_filename, 'w').write(pb)
+```
+
+```python
+transpositions[kwordb]
+```
+
+```python
+
+```