Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/64.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 什么样的Ruzzle板包含最独特的单词?_C++_C_Performance_Algorithm_Puzzle - Fatal编程技术网

C++ 什么样的Ruzzle板包含最独特的单词?

C++ 什么样的Ruzzle板包含最独特的单词?,c++,c,performance,algorithm,puzzle,C++,C,Performance,Algorithm,Puzzle,对于智能手机,有一个叫做的游戏。 这是一个找词游戏 快速解释: 游戏板由4x4个字母组成。 您可以从任意单元格开始,通过向上、向下、向左、向右或对角拖动来拼写单词。 电路板没有包装,您不能重复使用已选择的字母 平均来说,我和我的朋友会找到大约40个单词,在游戏结束时,游戏会告诉你可能会得到多少个单词。这个数字通常在250-350之间。 我们想知道什么样的电路板会产生最多可能的字数 我该如何找到最佳线路板? 我用C编写了一个程序,它包含16个字符,并输出所有适当的单词。 测试超过80000个单词

对于智能手机,有一个叫做的游戏。

这是一个找词游戏

快速解释:
游戏板由4x4个字母组成。
您可以从任意单元格开始,通过向上、向下、向左、向右或对角拖动来拼写单词。
电路板没有包装,您不能重复使用已选择的字母

平均来说,我和我的朋友会找到大约40个单词,在游戏结束时,游戏会告诉你可能会得到多少个单词。这个数字通常在250-350之间。
我们想知道什么样的电路板会产生最多可能的字数

我该如何找到最佳线路板?
我用C编写了一个程序,它包含16个字符,并输出所有适当的单词。
测试超过80000个单词,处理大约需要一秒钟

问题:
游戏板排列的数量为26^16。
这是43608742998874059776(43个六位数)

我需要一些启发。
我是否应该跳过所有包含zqx等的电路板,因为它们的字数预计不会太多?我不想在不确定的情况下排除一封信。
每个电路板也有4个副本,因为旋转电路板仍然会得到相同的结果。
但即使有这些限制,我认为我的生命中也没有足够的时间找到答案

也许董事会的产生不是答案。

有没有更快捷的方法从单词列表中找到答案?

有趣的问题。我看到(至少但主要是)两种方法

  • 一种是根据字典,努力粘贴尽可能多的可写字母(各个方向)。正如你所说的,有许多可能的组合,这条路线需要精心设计和复杂的算法才能达到有形的效果

  • 还有另一个基于概率的“松散”解决方案,我更喜欢它。您建议删除一些低外观字母,以最大限度地提高电路板的成品率。这方面的一个扩展可能是使用字典中更多的高外观字母

  • 进一步的步骤可以是:

    • 根据80k字典
      D
      ,您可以发现,对于26个字母的L集合中的每个l1字母,字母l2在l1之前或之后的概率。这是一个
      lxl
      概率数组,它非常小,因此您甚至可以扩展到
      lxlxl
      ,即考虑l1和l2,l3要适应的概率是多少。如果算法想要估计准确的概率,这就有点复杂了,因为概率和取决于3个字母的相对位置,例如在“三角形”配置中(例如位置(3,3)、(3,4)和(3,5)),结果可能比字母对齐时要少[只是一个假设]。为什么不升级到
      lxlxlxl
      ,这将需要一些优化

    • 然后,您在电路板上随机分配几个高外观字母(比如4~6个)(在8个可能的方向中的至少5个方向上,每个字母周围至少有1个空白单元格),然后使用
      L x L[xL]
      probas数组来完成-基于现有字母的含义,下一个单元格填充一个字母,该字母的概率在给定的配置下是高的[同样,字母按概率降序排序,如果两个字母紧密相连,则使用随机性]

    例如,仅采用水平配置,将以下字母放置到位,我们希望在
    ER
    to
    之间找到最佳的2个字母

      ...ER??TO...
    
    使用
    lxl
    ,类似循环(l1和l2是我们缺少的两个字母)。找到绝对更好的字母-但是bestchoice和bestproba可以改为数组,并保留10个最佳选择。 注:没有必要将概率保持在[0,1]的范围内。在这种情况下,我们可以将概率相加(虽然没有给出概率,但数字很重要。数学概率可以是p=(p(l0,l1)+p(l2,l3))/2,l0和l3是我们
    lxl
    示例中的R和t)

    该算法可以考虑更多的因素,并需要考虑垂直和对角线。使用
    lxlxl
    ,需要考虑更多方向上的字母,如
    ER?
    R???

    请注意,其中很多可能是预先计算的,而
    lxl
    数组当然是其中之一。

    tldr

    S   E   R   O
    P   I   T   S
    L   A   N   E
    S   E   R   G
    
    或者它的任何反映

    这个电路板包含1212个单词(事实证明,可以排除“z”、“q”和“x”)

    首先,你用错了字典。在没有得到与Ruzzle的词数精确匹配的结果后,我调查了一下,Ruzzle似乎使用了一个名为TWL06的字典,它有大约180000个单词。不要问我它代表什么,但它在txt中是免费提供的

    我还编写了代码,在16个字符的黑板上查找所有可能的单词,如下所示。它将字典构建成一个树状结构,然后在有单词需要查找时,几乎只是递归地循环。它按长度顺序打印它们。唯一性由STL集合结构维护

    #include <cstdlib>
    #include <ctime>
    #include <map>
    #include <string>
    #include <set>
    #include <algorithm>
    #include <fstream>
    #include <iostream>
    
    using namespace std;
    
    struct TreeDict {
    
        bool existing;
        map<char, TreeDict> sub;
    
        TreeDict() {
            existing = false;
        }
    
        TreeDict& operator=(TreeDict &a) {
    
            existing = a.existing;
            sub = a.sub;
            return *this;
        }
    
        void insert(string s) {
    
            if(s.size() == 0) {
    
                existing = true;
                return;
            }
    
            sub[s[0]].insert(s.substr(1));
        }
    
        bool exists(string s = "") {
    
            if(s.size() == 0)
                return existing;
    
            if(sub.find(s[0]) == sub.end())
                return false;
    
            return sub[s[0]].exists(s.substr(1));
        }
    
        TreeDict* operator[](char alpha) {
    
            if(sub.find(alpha) == sub.end())
                return NULL;
    
            return &sub[alpha];
        }
    };
    
    TreeDict DICTIONARY;
    
    set<string> boggle_h(const string board, string word, int index, int mask, TreeDict *dict) {
    
        if(index < 0 || index >= 16 || (mask & (1 << index)))
            return set<string>();
    
        word += board[index];
        mask |= 1 << index;
        dict = (*dict)[board[index]];
    
        if(dict == NULL)
            return set<string>();
    
        set<string> rt;
    
        if((*dict).exists())
            rt.insert(word);
    
        if((*dict).sub.empty())
            return rt;
    
        if(index % 4 != 0) {
    
            set<string> a = boggle_h(board, word, index - 4 - 1, mask, dict);
            set<string> b = boggle_h(board, word, index - 1, mask, dict);
            set<string> c = boggle_h(board, word, index + 4 - 1, mask, dict);
    
            rt.insert(a.begin(), a.end());
            rt.insert(b.begin(), b.end());
            rt.insert(c.begin(), c.end());
        }
    
        if(index % 4 != 3) {
    
            set<string> a = boggle_h(board, word, index - 4 + 1, mask, dict);
            set<string> b = boggle_h(board, word, index + 1, mask, dict);
            set<string> c = boggle_h(board, word, index + 4 + 1, mask, dict);
    
            rt.insert(a.begin(), a.end());
            rt.insert(b.begin(), b.end());
            rt.insert(c.begin(), c.end());
        }
    
        set<string> a = boggle_h(board, word, index + 4, mask, dict);
        set<string> b = boggle_h(board, word, index - 4, mask, dict);
    
        rt.insert(a.begin(), a.end());
        rt.insert(b.begin(), b.end());
    
        return rt;
    }
    
    set<string> boggle(string board) {
    
        set<string> words;
        for(int i = 0; i < 16; i++) {
    
            set<string> a = boggle_h(board, "", i, 0, &DICTIONARY);
            words.insert(a.begin(), a.end());
        }
        return words;
    }
    
    void buildDict(string file, TreeDict &dict = DICTIONARY) {
    
        ifstream fstr(file.c_str());
        string s;
    
        if(fstr.is_open()) {
            while(fstr.good()) {
    
                fstr >> s;
                dict.insert(s);
            }
            fstr.close();
        }
    }
    
    struct lencmp {
        bool operator()(const string &a, const string &b) {
    
            if(a.size() != b.size())
                return a.size() > b.size();
            return a < b;
        }
    };
    
    int main() {
    
        srand(time(NULL));
    
        buildDict("/Users/XXX/Desktop/TWL06.txt");
    
        set<string> a = boggle("SEROPITSLANESERG");
        set<string, lencmp> words;
        words.insert(a.begin(), a.end());
        set<string>::iterator it;
        for(it = words.begin(); it != words.end(); it++)
            cout << *it << endl;
        cout << words.size() << " words." << endl;
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    使用名称空间std;
    结构树指令{
    布尔现有;
    地图分册;
    TreeDict(){
    存在=错误;
    }
    TreeDict&operator=(TreeDict&a){
    现有=a.现有;
    sub=a.sub;
    归还*这个;
    }
    空白插入(字符串s){
    如果(s.size()==0){
    存在=真实;
    
    #include <cstdlib>
    #include <ctime>
    #include <map>
    #include <string>
    #include <set>
    #include <algorithm>
    #include <fstream>
    #include <iostream>
    
    using namespace std;
    
    struct TreeDict {
    
        bool existing;
        map<char, TreeDict> sub;
    
        TreeDict() {
            existing = false;
        }
    
        TreeDict& operator=(TreeDict &a) {
    
            existing = a.existing;
            sub = a.sub;
            return *this;
        }
    
        void insert(string s) {
    
            if(s.size() == 0) {
    
                existing = true;
                return;
            }
    
            sub[s[0]].insert(s.substr(1));
        }
    
        bool exists(string s = "") {
    
            if(s.size() == 0)
                return existing;
    
            if(sub.find(s[0]) == sub.end())
                return false;
    
            return sub[s[0]].exists(s.substr(1));
        }
    
        TreeDict* operator[](char alpha) {
    
            if(sub.find(alpha) == sub.end())
                return NULL;
    
            return &sub[alpha];
        }
    };
    
    TreeDict DICTIONARY;
    
    set<string> boggle_h(const string board, string word, int index, int mask, TreeDict *dict) {
    
        if(index < 0 || index >= 16 || (mask & (1 << index)))
            return set<string>();
    
        word += board[index];
        mask |= 1 << index;
        dict = (*dict)[board[index]];
    
        if(dict == NULL)
            return set<string>();
    
        set<string> rt;
    
        if((*dict).exists())
            rt.insert(word);
    
        if((*dict).sub.empty())
            return rt;
    
        if(index % 4 != 0) {
    
            set<string> a = boggle_h(board, word, index - 4 - 1, mask, dict);
            set<string> b = boggle_h(board, word, index - 1, mask, dict);
            set<string> c = boggle_h(board, word, index + 4 - 1, mask, dict);
    
            rt.insert(a.begin(), a.end());
            rt.insert(b.begin(), b.end());
            rt.insert(c.begin(), c.end());
        }
    
        if(index % 4 != 3) {
    
            set<string> a = boggle_h(board, word, index - 4 + 1, mask, dict);
            set<string> b = boggle_h(board, word, index + 1, mask, dict);
            set<string> c = boggle_h(board, word, index + 4 + 1, mask, dict);
    
            rt.insert(a.begin(), a.end());
            rt.insert(b.begin(), b.end());
            rt.insert(c.begin(), c.end());
        }
    
        set<string> a = boggle_h(board, word, index + 4, mask, dict);
        set<string> b = boggle_h(board, word, index - 4, mask, dict);
    
        rt.insert(a.begin(), a.end());
        rt.insert(b.begin(), b.end());
    
        return rt;
    }
    
    set<string> boggle(string board) {
    
        set<string> words;
        for(int i = 0; i < 16; i++) {
    
            set<string> a = boggle_h(board, "", i, 0, &DICTIONARY);
            words.insert(a.begin(), a.end());
        }
        return words;
    }
    
    void buildDict(string file, TreeDict &dict = DICTIONARY) {
    
        ifstream fstr(file.c_str());
        string s;
    
        if(fstr.is_open()) {
            while(fstr.good()) {
    
                fstr >> s;
                dict.insert(s);
            }
            fstr.close();
        }
    }
    
    struct lencmp {
        bool operator()(const string &a, const string &b) {
    
            if(a.size() != b.size())
                return a.size() > b.size();
            return a < b;
        }
    };
    
    int main() {
    
        srand(time(NULL));
    
        buildDict("/Users/XXX/Desktop/TWL06.txt");
    
        set<string> a = boggle("SEROPITSLANESERG");
        set<string, lencmp> words;
        words.insert(a.begin(), a.end());
        set<string>::iterator it;
        for(it = words.begin(); it != words.end(); it++)
            cout << *it << endl;
        cout << words.size() << " words." << endl;
    }
    
    string randomBoard() {
    
        string board = "";
        for(int i = 0; i < 16; i++)
            board += (char)('A' + rand() % 26);
        return board;
    }
    
    char distLetter() {
    
        int x = rand() % 15833;
        if(x < 1209) return 'A';
        if(x < 1510) return 'B';
        if(x < 2151) return 'C';
        if(x < 2699) return 'D';
        if(x < 4526) return 'E';
        if(x < 4726) return 'F';
        if(x < 5161) return 'G';
        if(x < 5528) return 'H';
        if(x < 6931) return 'I';
        if(x < 6957) return 'J';
        if(x < 7101) return 'K';
        if(x < 7947) return 'L';
        if(x < 8395) return 'M';
        if(x < 9462) return 'N';
        if(x < 10496) return 'O';
        if(x < 10962) return 'P';
        if(x < 10987) return 'Q';
        if(x < 12111) return 'R';
        if(x < 13613) return 'S';
        if(x < 14653) return 'T';
        if(x < 15174) return 'U';
        if(x < 15328) return 'V';
        if(x < 15452) return 'W';
        if(x < 15499) return 'X';
        if(x < 15757) return 'Y';
        if(x < 15833) return 'Z';
    }
    
    string distBoard() {
    
        string board = "";
        for(int i = 0; i < 16; i++)
            board += distLetter();
        return board;
    }
    
    string changeLetter(string x) {
    
        int y = rand() % 16;
        x[y] = distLetter();
        return x;
    }
    
    string swapLetter(string x) {
    
        int y = rand() % 16;
        int z = rand() % 16;
        char w = x[y];
        x[y] = x[z];
        x[z] = w;
        return x;
    }
    
    string change(string x) {
    
        if(rand() % 2)
            return changeLetter(x);
        return swapLetter(x);
    }
    
    int main() {
    
        srand(time(NULL));
    
        buildDict("/Users/XXX/Desktop/TWL06.txt");
    
        string board = "SEROPITSLANESERG";
        int locmax = boggle(board).size();
        for(int j = 0; j < 5000; j++) {
    
            int changes = 1;
    
            string board2 = board;
            for(int k = 0; k < changes; k++)
                board2 = change(board);
    
            int loc = boggle(board2).size();
            if(loc >= locmax && board != board2) {
                j = 0;
                board = board2;
                locmax = loc;
            }
        }
    }
    
    int main() {
    
        srand(time(NULL));
    
        buildDict("/Users/XXX/Desktop/TWL06.txt");
    
        int glomax = 0;
        int i = 0;
        while(true) {
    
            string board = distBoard();
            int locmax = boggle(board).size();
            for(int j = 0; j < 500; j++) {
    
                string board2 = board;
                for(int k = 0; k < 2; k++)
                    board2 = change(board);
    
                int loc = boggle(board2).size();
                if(loc >= locmax && board != board2) {
                    j = 0;
                    board = board2;
                    locmax = loc;
                }
            }
    
            if(glomax <= locmax) {
                glomax = locmax;
                cout << board << " " << glomax << " words." << endl;
            }
    
            if(++i % 10 == 0)
                cout << i << endl;
        }
    }