Anonymous user
Straddling checkerboard: Difference between revisions
→{{header|Nim}}
(Added Wren) |
|||
Line 1,645:
ONENIGHTITWASONTHETWENTIETHOFMARCH1888IWASRETURNING
</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}}==
|