Straddling checkerboard: Difference between revisions
Content added Content deleted
(Added Wren) |
|||
Line 1,645: | Line 1,645: | ||
ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING |
ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING |
||
</pre > |
</pre > |
||
=={{header|Nim}}== |
|||
I used the same example as in the Go solution (and, fortunately, got the same result). |
|||
<lang Nim>import strutils, tables |
|||
const |
|||
FullStop = '.' |
|||
Escape = '/' |
|||
type Checkerboard = object |
|||
encryptTable: Table[char, string] |
|||
decryptTable: Table[string, char] |
|||
proc initCheckerboard(digits: string; row1, row2, row3: string): Checkerboard = |
|||
## Initialize a checkerboard with given digits in row 0 and the following given rows. |
|||
## No sanity check is performed. |
|||
var rowChars: seq[char] # The two characters to use to identify rows 2 and 3. |
|||
# Process row 1. |
|||
for col, ch in row1: |
|||
if ch == ' ': |
|||
rowChars.add digits[col] |
|||
else: |
|||
result.encryptTable[ch] = $digits[col] |
|||
if rowChars.len != 2: |
|||
raise newException(ValueError, "expected two blank spots in first letter row.") |
|||
# Add rows 2 and 3. |
|||
for col, ch in row2: |
|||
result.encryptTable[ch] = rowChars[0] & digits[col] |
|||
for col, ch in row3: |
|||
result.encryptTable[ch] = rowChars[1] & digits[col] |
|||
if Escape notin result.encryptTable: |
|||
raise newException(ValueError, "missing Escape character.") |
|||
# Build decrypt table from encrypt table. |
|||
for c, s in result.encryptTable.pairs: |
|||
result.decryptTable[s] = c |
|||
proc encrypt(board: Checkerboard; message: string): string = |
|||
## Encrypt a string. |
|||
let message = message.toUpperAscii |
|||
for ch in message: |
|||
case ch |
|||
of 'A'..'Z', FullStop, Escape: |
|||
result.add board.encryptTable[ch] |
|||
of '0'..'9': |
|||
result.add board.encryptTable[Escape] |
|||
result.add ch |
|||
else: |
|||
discard # Ignore other characters. |
|||
proc raiseError() = |
|||
## Raise a ValueError to signal a corrupt message. |
|||
raise newException(ValueError, "corrupt message") |
|||
proc decrypt(board: Checkerboard; message: string): string = |
|||
## Decrypt a message. |
|||
var escaped = false # Escape char previously encountered. |
|||
var str = "" # Current sequence of characters (contains 0, 1 or 2 chars). |
|||
for ch in message: |
|||
if ch notin '0'..'9': raiseError() |
|||
if escaped: |
|||
# Digit is kept as is. |
|||
result.add ch |
|||
escaped = false |
|||
else: |
|||
# Try to decrypt this new digit. |
|||
str.add ch |
|||
if str in board.decryptTable: |
|||
let c = board.decryptTable[str] |
|||
if c == Escape: escaped = true |
|||
else: result.add c |
|||
str.setLen(0) |
|||
elif str.len == 2: |
|||
# Illegal combination of two digits. |
|||
raiseError() |
|||
when isMainModule: |
|||
let board = initCheckerboard("8752390146", "ET AON RIS", "BC/FGHJKLM", "PQD.VWXYZU") |
|||
let message = "you have put on 7.5 pounds since I saw you." |
|||
echo "Message: ", message |
|||
let crypted = board.encrypt(message) |
|||
echo "Crypted: ", crypted |
|||
echo "Decrypted: ", board.decrypt(crypted)</lang> |
|||
{{out}} |
|||
<pre>Message: you have put on 7.5 pounds since I saw you. |
|||
Crypted: 01306592038080673955702555083069056649578462090130602 |
|||
Decrypted: YOUHAVEPUTON7.5POUNDSSINCEISAWYOU.</pre> |
|||
=={{header|Perl}}== |
=={{header|Perl}}== |