decipherbible.frink

View or download decipherbible.frink in plain text format


// The Troublesome Gospel of St. Clinton
// This program finds reverse translation of Clint Williams' lossy numerical
// encoding of the Bible:
//
// http://www.c-c-w.net/numerical/


// 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

// Now perform dechiffrage
orig = read["http://www.c-c-w.net/numerical/"]
orig =~ %s/<[^>]*>/ /gs            // Strip HTML
orig =~ %s/[^0-9]+/ /gs            // Strip all non-numbers & condense spaces
decipher[orig, dict]


// 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 decipher a string of text, using a dictionary that
// was already built
decipher[string, dict] :=
{
   words = split[%r/\s+/s, string]  // Split on spaces

   for num = words
   {
      rev = dict@num

      if (! rev)
         print["$num "]     // Word not found, print numeric value
      else
         if (length[rev] == 1)
            print[rev@0 + " "]  // Only one word; print without brackets
         else
            print["$rev "]  // More than one mapping, print array
   }
}


View or download decipherbible.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 17596 days, 22 hours, 4 minutes ago.