예제 #1
0
    private static List <string> SampleMatchingWords(WordRegexMatches wordRegexMatches)
    {
        byte[]   wordMatches   = wordRegexMatches.wordMatches;
        int[]    countsByRegex = wordRegexMatches.countsByRegex;
        string[] selectedWords = new string[countsByRegex.Length];

        // Examine regexes in order of increasing number of matching words
        List <int> remainingRegexIndices = Enumerable.Range(0, countsByRegex.Length)
                                           .OrderBy(regexIndex => countsByRegex[regexIndex]).ToList();
        byte satisfiedRegexFlags = 0;

        while (remainingRegexIndices.Count > 0)
        {
            int?       matchedRegexIndex = null;
            List <int> wordIndexChoices  = new List <int>();

            foreach (int ri in remainingRegexIndices)
            {
                for (int wi = 0; wi < ALL_WORDS.Length; wi++)
                {
                    byte wm        = wordMatches[wi];
                    byte regexFlag = (byte)(1 << ri);
                    // If wm matches this regex, and any other matches in wm overlap only
                    // with previously-matched regexes, then we found a new match
                    bool matchesThisRegex = (wm & regexFlag) != 0;
                    bool matchesOtherUnsatisfiedRegexes = (wm & ~regexFlag & ~satisfiedRegexFlags) != 0;
                    if (matchesThisRegex && !matchesOtherUnsatisfiedRegexes)
                    {
                        matchedRegexIndex = ri;
                        wordIndexChoices.Add(wi);
                    }
                }
                // Only accept choices from a single regex
                if (matchedRegexIndex != null)
                {
                    break;
                }
            }

            if (matchedRegexIndex == null)
            {
                // This should never happen!
                throw new System.Exception("No solution found for regexes!");
            }
            else
            {
                satisfiedRegexFlags |= (byte)(1 << matchedRegexIndex.Value);
                remainingRegexIndices.Remove(matchedRegexIndex.Value);
                selectedWords[matchedRegexIndex.Value] = ALL_WORDS[wordIndexChoices.PickRandom()];
            }
        }

        return(selectedWords.ToList());
    }
예제 #2
0
    public static Puzzle SamplePuzzle(int rowNorth, int rowSouth, int colWest, int colEast)
    {
        // NW, NE, SE, SW
        RegexData[] regexData = new RegexData[] {
            RegexDataAtTablePos(rowNorth, colWest),
            RegexDataAtTablePos(rowNorth, colEast),
            RegexDataAtTablePos(rowSouth, colEast),
            RegexDataAtTablePos(rowSouth, colWest),
        };
        WordRegexMatches wordRegexMatches = ComputeWordRegexMatches(regexData);

        List <string> matchingWords = SampleMatchingWords(wordRegexMatches);
        List <string> decoyWords    = SampleDecoyWords(regexData);

        return(new Puzzle(regexData.ToList(), matchingWords, decoyWords));
    }