The world has its fair share of serial killers. Some have never been caught and are probably running in the wild freely with their real identities still unknown. Such as the case of a serial killer using the moniker "Zodiac" who murdered at least seven people between December 1968 and October 1969. He taunted local police and newspapers with handwritten letters containing threats, claims of further undiscovered victims, and coded messages. The supposed killer claimed that the solutions would reveal an identity when they were all solved. Some never were, leaving the authorities and many code crackers worldwide puzzled for years, and the killer was never caught.

Z-340
Zodiac's letter sent to the San Francisco Chronicle on November 8, 1969 with the Z-340 cipher, which was decrypted on December 5, 2020.

More than 50 years after the so-called Zodiac Killer first began terrorizing the streets of Northern California, one of the killer's mysterious encoded messages was finally deciphered on December 5, 2020. It is a 340-symbol encrypted message — known as Z-340 — sent to the San Francisco Chronicle in November 1969. The international team of amateur code crackers that succeeded in doing so consisted of David Oranchak (a software developer from Virginia, USA), Sam Blake (a mathematician from Australia) and Jarl Van Eycke (a warehouse operator from Belgium). Unfortunately, the message does not contain enough information to unmask the Zodiac Killer.

Assignment

To encode Z-340, the Zodiac Killer used a classic trick: replace each letter with a symbol. This was easy to break. But the insight that eventually led to cracking the code was that the letters should not be read from left to right and from top to bottom. Still, the Zodiac Killer started writing at the top left corner, but then put each subsequent symbol one row down and two columns to the right. Beyond the rightmost column he continued at the leftmost column, and past the bottom row he continued at the top row.

For example, let's take the message:

I've no plans to call on you, Clarice. The world is more interesting with you in it.

This message consists of 84 characters that are put in a grid with 4 rows and 21 columns in the following way:

order
Order in which the cells of a grid with 4 rows and 21 columns must be filled during Zodiac encoding of a message with 84 characters, shifting one row down and two columns to the right each time. Beyond the right side we continue from the left and past the bottom we continue from the top.

If we replace these positions with their corresponding characters from the message, the cipher looks like:

codering
Grid with 4 rows and 21 columns filled by the Zodiac cipher of the message I've no plans to call on you, Clarice. The world is more interesting with you in it., shifting one row down and two columns to the right each time. Beyond the right side we continue from the left and past the bottom we continue from the top.

We will call this the Zodiac cipher with vertical offset 1 and horizontal offset 2, even though we omit replacing characters with symbols. So, in textual format, the 4-line Zodiac cipher of our example message becomes:

Iatsou   e    ,ephhlm
 o'ri r yin.wcii rle 
 yorvintliono iastCea
snwoneecgodnut Ttl .l

Your task:

Example

In the following interactive session we assume the text files ciphertext.01.txt1 and ciphertext.02.txt2 to be located in the current directory.

Note

To enable using the following interactive session as a doctest, we have escaped all backslashes (in newline representations) as double backslashes.

Testcases that print a result may be corrupted by editors that automatically remove white space characters at the end of lines.

>>> message = "I've no plans to call on you, Clarice. The world is more interesting with you in it."

>>> read_ciphertext('ciphertext.01.txt3')
['Iatsou   e    ,ephhlm', " o'ri r yin.wcii rle ", ' yorvintliono iastCea', 'snwoneecgodnut Ttl .l']
>>> decode('ciphertext.01.txt4')
"I've no plans to call on you, Clarice. The world is more interesting with you in it."
>>> encode(message, 4)
"Iatsou   e    ,ephhlm\\n o'ri r yin.wcii rle \\n yorvintliono iastCea\\nsnwoneecgodnut Ttl .l"
>>> print(encode(message, 4))
Iatsou   e    ,ephhlm
 o'ri r yin.wcii rle 
 yorvintliono iastCea
snwoneecgodnut Ttl .l

>>> read_ciphertext('ciphertext.02.txt5')
['Ioni TC seiwe  r ooihsrreual', ' d  lnv  tseantn teoococp.yi', ",la'ugnihlo  nirmwiy  t tel."]
>>> decode('ciphertext.02.txt6', vertical=2, horizontal=3)
"I've no plans to call on you, Clarice. The world is more interesting with you in it."
>>> encode(message, 3, vertical=2, horizontal=3)
"Ioni TC seiwe  r ooihsrreual\\n d  lnv  tseantn teoococp.yi\\n,la'ugnihlo  nirmwiy  t tel."
>>> print(encode(message, 3, vertical=2, horizontal=3))
Ioni TC seiwe  r ooihsrreual
 d  lnv  tseantn teoococp.yi
,la'ugnihlo  nirmwiy  t tel.

Epilogue