3

im doing research project for a the game Text twist,the text will automatically search word from a dictionary and scramble then, and also process the words to be found automatically using the same concept with this site http://grecni.com/texttwist.php , i also need to provide an algorithm that i will use for my project,and im planning to include this word unscrambler in this web site http://grecni.com/texttwist.php but i dont know what algorithm is possibly use to do the actions done on the website i posted. does any one know what type, or what you call the algorithm used,or can be use that will give the same results, an example of the algorithm will be greatly appreciated.

wicked14
  • 77
  • 5
  • 1
    We don't charge for line breaks and capitals, you know. Also, [what have you tried?](http://whathaveyoutried.com/) – DaveRandom Jun 22 '12 at 00:53
  • A naive approach: Generate all possible strings from the characters. Test each string for a definition. – Chris Dargis Jun 22 '12 at 01:00
  • i added vb.net because im planning to do the program with it,if ever the have sample they can post it with that language. and @VanDarg its not a homework,its a research project.still new with application of known algorithm in programs i make,because i program in a logical manner. and program spontaneously. so a sample implementation of a algorithm that someone will post will greatly help, but just the algorithm name is a great help already. – wicked14 Jun 23 '12 at 06:47

3 Answers3

2

The data structure you want is called a Directed Acyclic Word Graph (dawg)

There are questions already answered about this:

Algorithm to get a list of all words that are anagrams of all substrings (scrabble)?

Writing an algorithm for scrabble

You could also perhaps implement the levenshtein algorithm which would accomplish pretty much the same result: MySQL - Which Hash Algo should I use for this?

Update:

After giving myself a challenge to create an example to demonstrate the algorithm ive come up with this, as its from a plugin built for my cms its wrapped in a class but your get the idea there is a demo @ http://cherone.co.uk/scrabble_suggest

First I created a table with id,word,sorted (word = the actual word, sorted = the word alphabetically sorted like for e.g: aardvark sorted would be aaadkrrv) i just found an english wordlist on the internets.

The form posts the string and then the string is sorted alphabetically to match 1:1 the sorted column, then the string is split into each character and then queried sequentially till the last character. The functions of interest are str_sort,permute,swap Perhaps its of some interest..

<?php 
/**
 * Scrabble solver Plugin this file is "inline" included within the frontController class
 */
Class plugin{

    function __construct($core) {
        $this->core = $core;
        $this->plugin_path = SITE_ROOT.'/core/plugins/'.$this->core->router->action.'/';
        $this->request = explode('/',$this->core->router->request);
        //Assign Page meta tags ect
        $this->core->template->meta_keywords    = 'Text,Twist,Text Twist,word,letter,scrabble,unscrambler,unscramble,word finder,puzzle,anagram,scrabble,cheat,cheater,help,helper,solve,solver,free,php';
        $this->core->template->meta_description = 'Scrabble and Anagram like word solver tool to help unscramble letters and words and cheat at your favorite word puzzle';
        $this->core->template->page_title       = $this->core->template->site_name." - Scrabble and Anagram like word solver";
        $route = (isset($this->request[2])?$this->request[2]:null);
    }

    function load(){
        set_time_limit(0);
        $data=array('var'=>$this,'result'=>'','word'=>'','word_sort'=>'');

        switch($this->core->router->subaction){
            case "index":
                $string='';
                if($_SERVER['REQUEST_METHOD']=='POST'){
                    $string = substr(preg_replace('/[^a-zA-Z]/s', '', trim(strtolower($_POST['letters']))),0,8);
                    $data['word'] = $string;
                    $string = $this->str_sort($string);
                    $data['word_sort'] = $string;
                }
                $stringLen = strlen($string);

                $result = array();
                for($i=2;$i<=$stringLen;$i++){
                    $seq = substr($data['word_sort'],0,$i);

                    $rounds = explode('|',$this->permute($seq,0,strlen($seq)));
                    $r=$i;
                    foreach($rounds as $round){
                        $result[$r] = $this->get_words($round,strlen($seq));
                        $r++;
                    }
                }

                $data['result'] = $result;

                $this->core->template->content_center = $this->core->template->loadContentView(get_class(),$this->core->router->subaction,$data);
                $this->core->template->content_left   = '';
                $this->core->template->content_right  = '';
                break;

            case "update":
                $this->insert_word_lists();
                header('Location: '.SITE_URL.'/'.$this->core->router->action);
                die;
                break;

            case "api":
                header('Content-Type: application/json');
                echo 'No api for this plugin, perhaps one comming soon. ;p';
                break;

            default:
                header('Location: '.SITE_URL.'/'.$this->core->router->action);
                die;
                break;
        }
    }

    //Query Method to search for sequenced alphabetically sorted words.
    private function get_words($word,$stringLen){
        $chars = str_split($word,1);
        $sql = "SELECT DISTINCT `word` FROM `plugin_scrabble_words` WHERE ";
        foreach($chars as $char){
            $sql .=' `sorted` LIKE "%'.$char.'%" AND';
        }
        $sql = trim($sql,'AND');
        $sql .= ' AND LENGTH(sorted) = '.$stringLen;

        $statement = $this->core->db->prepare($sql);
        $statement->execute();

        $result = $statement->fetchAll(PDO::FETCH_ASSOC);

        return $result;
    }

    //A Model method for updating the database word list.
    private function insert_word_lists(){
        set_time_limit(0);
        $lists = glob($this->plugin_path."wordlists/*.txt");
        foreach ($lists as $list){
            $words = file($list);
            foreach($words as $word){
                $word = strtolower(preg_replace('/[^a-zA-Z]/s', '', $word));
                if($this->sql_check_word($word)===false){
                    $this->sql_put_word($word);
                }
            }
        }
    }

    //A Model method for checking the database specific word.
    private function sql_check_word($word){
        $sql = "SELECT `word` FROM `plugin_scrabble_words` WHERE `word` = :word";
        $statement = $this->core->db->prepare($sql);
        $statement->bindParam(':word', $word, PDO::PARAM_STR);
        $statement->execute();
        $result = $statement->fetchAll(PDO::FETCH_ASSOC);

        if(!empty($result)){
            return true;
        }else{
            return false;
        }
    }

    //A Model method for adding the word to the database.
    private function sql_put_word($word){
        $sql = "INSERT into `plugin_scrabble_words` (word,sorted) VALUES (:word,:sorted)";
        $statement = $this->core->db->prepare($sql);
        $sorted = $this->str_sort($word);
        $statement->bindParam(':word', $word, PDO::PARAM_STR);
        $statement->bindParam(':sorted', $sorted, PDO::PARAM_STR);
        $statement->execute();
    }


    //Sort Method that will sort a sring in alphabetical order
    private function str_sort($string) {
        $tmp = str_split($string);
        sort($tmp);
        return implode('',$tmp);
    }

    //Method to generate and return all permutations of the string with | delimiter.
    private function permute($str,$i,$n) {
        if ($i == $n){
            return $str.'|';
        } else {
            for ($j = $i; $j < $n; $j++) {
                $this->swap($str,$i,$j);
                $this->permute($str, $i+1, $n);
                $this->swap($str,$i,$j);
            }
        }
    }

    //Method to swap the char at pos $i and $j of $str.
    private function swap(&$str,$i,$j) {
        $temp = $str[$i];
        $str[$i] = $str[$j];
        $str[$j] = $temp;
    }
}
?> 
Community
  • 1
  • 1
Lawrence Cherone
  • 46,049
  • 7
  • 62
  • 106
  • Thanks men the links provided will be great help!at least now i know where to start my research need to start reading about this. :) – wicked14 Jun 23 '12 at 06:56
  • @wicked14 Ive updated my answer with some example code and a demo, perhaps its of some interest if your stuck. – Lawrence Cherone Jun 23 '12 at 14:01
  • thanks @lawrence, is this an example for levenshtein algorithm? i'll try to implement this with vb.net – wicked14 Jun 23 '12 at 22:37
1

One approach would be to generate all possible permutations of the letters and match them against a dictionary. For an N lettered character sequence, this would take O(N!) time if you keep the dictionary in a set data structure.

For shorter sequences (10 characters or so), this is a perfectly good strategy.

For longer sequences, you should do the reverse. You can loop through the dictionary and determine if your character sequence has the characters to make the word. For M dictionary elements, this would take more or less O(M) time. There are various ways you can speed up this technique like pre-computing the number of each letter in each dictionary entry.

tskuzzy
  • 35,812
  • 14
  • 73
  • 140
  • generating all possible permutations is one of my options. and i think this is the same process that the word unscrambler on the site is doing.thanks for the advice! – wicked14 Jun 23 '12 at 06:51
1

edit: The gentleman below me gives a more algorithmically rigorous and thorough treatment of the subject, and so I would direct you to his explanation (which employs big O notation which mine... embarrassingly does not).

Actually, although VanDang called it a "naive approach", there's nothing wrong with testing all possible combinations of the finite set of characters given. As long as a person is prevented from providing an arbitrary number of characters, there is a maximum of !n combinations of letters (with n = the number of letters, assuming there are no repeats), and, since words in English don't get THAT long, testing each combination wouldn't be that bad.

After all, the method of exhaustion is actually an accepted method for optimizing large boolean expressions when generating hardware descriptions.

root
  • 471
  • 5
  • 18