简体   繁体   English

如何为填字游戏获得多个解决方案?

[英]How to get multiple solutions for a crossword?

I have already seen the forums and different questions on this.我已经看过论坛和不同的问题。

But i want to ask something different.但我想问一些不同的问题。 I have two wordlist of different words and one grid specified by 0 and 1. i will have to select word from wordlist 1 for rows and 2 for columns.我有两个不同单词的单词列表和一个由 0 和 1 指定的网格。我将不得不从单词列表 1 中的 select 单词中获取行和 2 中的列。

The main problem is i have to find multiple solution within given time constraint.主要问题是我必须在给定的时间限制内找到多个解决方案。 Can someone suggest me some good algorithm for that.有人可以为此建议我一些好的算法。 I am not getting what kind of algorithmic approach should i take.我没有得到我应该采取什么样的算法方法。

Another thing, I have two language options.另一件事,我有两种语言选择。 Either c++ or java which would be better to implement. c++ 或 java 会更好地实施。

thank you谢谢你

I found a solution that does what you want .找到了一个可以满足您需求的解决方案 Sadly I can't take credit for it:)可悲的是,我不能把它归功于它:)

Here is an example.这是一个例子。 You feed it a pattern file, like pattern1 :你给它一个模式文件,比如pattern1

    ##   ##    
    #     #    
    #     #    
           #   
###   ###    ##
#      #      #
   #     #     
    #     #    
     #     #   
#      #      #
##    ###   ###
   #           
    #     #    
    #     #    
    ##   ##    

You invoke the program on it, like eg so:您在其上调用程序,例如:

./cword pattern1 /etc/dictionaries-common/words

The output is output 是

SODS##HOG##AMPS
APIA#RADON#LAUE
TESS#ALONE#ERNA
ENCHANTRESS#GYM
###ADS###TUTU##
#PAYDAY#ESPIES#
REV#SCALD#SCRIP
ARON#KNOWS#SITE
MCCOY#KNITS#TET
#HARASS#NAPPED#
##TACT###DIE###
MCI#COORDINATES
ELOY#AMARU#ROLL
SINE#TARIM#LIMA
SOSA##REP##SLOT

Or, run another time:或者,再次运行:

PAWN##HOT##BEST
OLEO#SURYA#OMAR
LOAN#AGAPE#ABLE
SELFISHNESS#RTE
###ASH###OKAY##
#KATMAI#EPILOG#
INN#SYNOD#MULES
SETH#SCHWA#MONA
MEIER#AMIDS#GEM
#SPLATS#NOWAYS#
##APSE###RAY###
WIS#PATRONYMICS
ALTA#CHOKE#AREA
SLOP#HEARD#ROBS
PSST##ERA##ANUS

Of course, with larger patterns or smaller wordlists your mileage may vary (wildly).当然,对于较大的模式或较小的单词表,您的里程可能会有所不同(非常大)。 I was able to do 1000 generations in 26.5 seconds on a Q9550 processor, using我能够在 Q9550 处理器上在 26.5 秒内完成 1000 代,使用

time for a in $(seq 1 200)
do 
    for a in 1 2 3 4 5
    do 
        ./cword pattern1 /etc/dictionaries-common/words | md5sum&
    done
    wait
done | sort | uniq -c | sort -n | tee >(wc -l)

The output confirmed that these were in fact 1000 unique solutions. output 证实这些实际上是 1000 个独特的解决方案。 Not bad, if you ask me.不坏,如果你问我。 (The timing included the time to calculate the md5sums per solution) (时间包括计算每个解决方案的 md5sums 的时间)

You may be able to use something called the Dancing Links or DLX algorithm.您也许可以使用称为Dancing Links 或 DLX算法的东西。 This is an extremely efficient algorithm for solving exact cover problems.这是解决精确覆盖问题的一种非常有效的算法。

There are several programs out there that use this to solve Sudoku puzzles.有几个程序可以使用它来解决数独难题。

I honestly don't know enough about exact cover problems to say that this will definitely work for your needs but it's worth taking a look.老实说,我对确切的封面问题知之甚少,无法说这肯定会满足您的需求,但值得一看。

When doing a crossword, one usually finds oneself looking for a word of a certain length, with a certain letter at a certain position in it.在做填字游戏时,通常会发现自己在寻找一个特定长度的单词,其中包含某个 position 处的某个字母。 So, you're probably going to want a function like this:因此,您可能会想要这样的 function:

List<String> findWord(int ofLength, char withLetter, int atIndex) {/*implementation*/}

Which could probably use a set of pre-built HashMaps to produce a set of candidates quickly.这可能会使用一组预先构建的 HashMap 来快速生成一组候选对象。 (You'll probably also want to be able to track whether the word is currently used already in the crossword...assuming duplicates aren't allowed) (您可能还希望能够跟踪该单词当前是否已在填字游戏中使用……假设不允许重复)

The other thing people do is guess using hints.人们做的另一件事是使用提示进行猜测。 I figure you're probably not looking for strong AI, so that leaves brute force algorithms...in which case, try to fill in the crossword starting with the biggest words first, since there are generally fewer possibilities there.我认为您可能不是在寻找强大的 AI,因此留下了蛮力算法……在这种情况下,请尝试首先从最大的单词开始填写填字游戏,因为那里的可能性通常较小。

Skeleton algorithm:骨架算法:

private void checkPuzzleOn(Row row, SolutionSet s) {

    List<Row> crossingRows = row.getCrossingRows();

    if(allAlreadyFilled(crossingRows)) {
        //This part of the crossword works; store info in solution set.
        return;
    }

    crossingRows.sortBiggestToSmallest();

    foreach(Row crossing in crossingRows) {

        int index = row.getIndexOfIntersectionWith(crossing);
        char c = row.charAt(index);

        List<String> candidates = findWords(crossing.length, c, index);
        foreach(String candidate in candidates) {
            verifyAgainstPresentWords(crossing, candidate); //check that using this word won't collide with others; important because of cycles.
        }

        if(candidates.isEmpty()) {
            //This part of the crossword won't match! store info in solution set.
            return;
        }

        foreach(String candidate in candidates) {
            crossing.setWord(candidate);
            checkPuzzleOn(crossing, s);
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM