/////////////////////////////////////////////////////////////////////////////////////////////// // // Anagram.f1 // // This is a simple program to find single word anagrams. This program demonstrates // how to create and search a simple indexed relational database. // // The algorithm for anagram search is as follows: // // 1. Create a database of records of all words, each record containing the word itself and // a word containing alphabetically sorted letters. // // Some examples: // // entering the word 'bazaar', we enter this record: // ('bazaar','aaabrz') // // entering the word 'fire', we enter this record: // ('fire','efir') // // entering the word 'rife', we enter this record: // ('rife','efir') // // // 2. Searching for anagrams // Once the database is created (obviously this needs to be done only once), // searching for anagrams is quite straightforward: // Find all the words that have the same sequence of sorted letters as the word for // which we are trying to find the anagram. // // As mentioned above, first we need to create a database of all words. // This is rather quite simple. There are numerous lists of words available on the internet. // We chose the file from UK Advanced Cryptics (ukacdasc.txt), as downloaded from the site: // // http://www.puzzlers.org/secure/wordlists/dictinfo.php // // Then we converted the text file into an indexed database by executing the query: // // CreateAnagramWordDB('ukacdasc.txt','anagram.dbs':WordDB) // // (You can use any other list of words, the code below assumes text files with // one word per line.) // Once we have created the database, (which only takes about 20 seconds), we can find // any existing anagram by issuing a query, such as: // // FindAnagram('staple','anagram.dbs':WordDB) // ////////////////////////////////////////////////////////////////////////////////////////////// local WordRecord = word:S,sorted:S local WordDB = file WordRecord[sorted] proc FindAnagram(word:<S,f:.WordDB) iff RtlSortAscending(word,sorted) & DbSeek(f.sorted,sorted) & // find the first word with the same sorted string if DbAccess(f,y) then // found... Print('\n',y.word) & // print the word FindAllAnagrams(sorted,f) // find the rest of the words with the same end local proc FindAllAnagrams(sorted:<S,f:.WordDB) iff DbSeekNextEq(f.sorted) & if DbAccess(f,y) then Print('\n',y.word) & FindAllAnagrams(sorted,f) end /////////////////////////////////////////////////////////////////////////////// // // Create a database file containing all words. // // Given a text file containing words (each line considered a word), create // a database file containing all words. This will automaticall create the // index file for searching through the sorted words as well. // /////////////////////////////////////////////////////////////////////////////// subr CreateAnagramWordDB(fin:.Ascii,fout:.WordDB) iff DbRewind(fout) & DbTruncate(fout) & ReadInFile(fin,fout) local subr ReadInFile(fin:.Ascii, fout:.WordDB) iff if DbAccess(fin,str) then record :.WordRecord & record := (str,RtlSortAscending(str)) & DbPut(fout,record) & DbSkip(fin,1) & ReadInFile(fin,fout) end
This page was created by F1toHTML