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 17682 days, 11 hours, 34 minutes ago.