Download or view decipherrabbit.frink in plain text format
// The rabbit monologue, returned to its
// This program finds reverse translation of Clint Williams' irreversible
// numerical encoding of the McGregor tale:
//
// http://www.c-c-w.net/mcgregor/
// dict is a dictionary of words, keyed by their numeric values, values
// are an array of words that this number maps to.
dict = new dict
// Effectively, this is a "set" of the words we've seen.
// TODO: need to implement efficient sets.
usedDict = new dict
// Paths to several Moby wordlists (not included)
// The wordlist files are part of the Moby wordlist project, available at:
// http://icon.shef.ac.uk/Moby/
files = ["file:///home/eliasen/prog/mobydict/mwords/singlewords.txt",
"file:///home/eliasen/prog/mobydict/mwords/compoundwords.txt",
"file:///home/eliasen/prog/mobydict/mwords/names.txt",
"file:///home/eliasen/prog/mobydict/mwords/places.txt"]
// Load in the wordfiles and convert words to their numeric values
for file = files
numeric[read[file], usedDict, dict] // Read in wordlists
usedDict = undef
orig = read["file:///c:/prog/frink/rabbitorig.txt"]
// Now perform dechiffrage
orig =~ %s/(\d+)/decipher[$1,dict]/gse
println[orig]
// Function to turn a text into its string representations
// and insert each word mapping into a dictionary.
//
numeric[string, usedDict, dict] :=
{
words = split[%r/\s+/s, string] // Split into words
for word = words
{
if word =~ %r/[^A-Za-z]/ // Discard non-alphabetic words.
next
if word =~ %r/[A-Z]{2,}/ // Two or more uppercase letters? Skip 'em.
next
capWord = uppercase[word] // Make all keys uppercase
if (usedDict@capWord) // Already seen it?
next
usedDict@capWord = true // Mark word as used
// Make numeric value. This could be done more concisely if we
// had a map[] function.
ret = ""
for char = chars[capWord]
{
char = char - char["A"] + 1
ret = ret + "$char"
}
// See if number exists already
if (dict@ret != undef)
{
dict@ret.push[word] // Already exists
// println[dict@ret]
// Comment in to see hash collisions
} else
dict@ret = [word] // Doesn't exist, create a one-element array
}
}
// Function to do enciphering, for reference. Note that it's a *whole*
// lot easier to encipher than decipher.
encipher[str] := uc[str] =~ %s/([A-Za-z])/char[$1]-char["A"] + 1/ges
// Function to decipher a single number to its probable word(s)
decipher[num, dict] :=
{
rev = dict@num
if (! rev)
return num // Word not found, print numeric value
else
if (length[rev] == 1)
return rev@0 // Only one word; print without brackets
else
return rev // More than one mapping, print array
}
Download or view decipherrabbit.frink in plain text format
This is a program written in the programming language Frink.
For more information, view the Frink
Documentation or see More Sample Frink Programs.
Alan Eliasen was born 20217 days, 23 hours, 22 minutes ago.