中文填字程式

話說幾天前 DR 看到一份填字題目,就是那種有三個中文字,例如「法」、「復」、「語」,然後填入一個相同的字讓各個配對可以組成合宜的字詞,以這個例子來說,可以填入的解答就例如有「古」、「國」等。而當 DR 在嘗試作答時,突然靈機一動想到,其實只要有適當的詞庫,這應該是可以用程式去協助解答的。

 

那麼去哪裡找詞庫呢?DR 很快的想起開放原始碼的新酷音輸入法,於是在 GitHub 上把新酷音輸入法的純文字詞庫檔(tsi.src)抓下來,接著就開始嘗試用 Python 寫出填字程式,所構思的程式運作流程大概像這樣:

  1. 讀取詞庫文字檔,篩選出兩個字的字詞。
  2. 三個題目字各自去搜尋符合的字詞,並存成三組詞庫。
  3. 清除三組詞庫中各自的題目字。
  4. 比對三組詞庫中的剩餘文字,三組詞庫皆有的字便是可用的答案。

 

由於 DR 主要是想測試觀念的實作,所以沒有設計任何的操作介面,執行的流程是先將題目字以逗點分隔的方式寫入 input.txt,然後執行 xword.py 便會將解答(如果有的話)輸出到 output.txt。完成的程式碼內容如下:

#!/usr/bin/python
# -*- coding: utf-8 -*-
import os, sys
import codecs

ENCODING = "utf-8"
LIBRARY = "tsi.src"
INPUT = "input.txt"
OUTPUT = "output.txt"
CHARS = 3

def readLibrary():
    libs = []
    libFile = codecs.open(LIBRARY, "r", ENCODING) 
    for line in libFile.readlines():
        word = line.split(" ")[0]
        if len(word) == 2:
            libs.append(word)
    libFile.close()
    return libs

def readQuery():
    inputFile = codecs.open(INPUT, "r", ENCODING)
    queries = inputFile.read().replace(u"\uFEFF", "").split(u",")
    for x in range(0, CHARS):
        queries[x] = queries[x].strip()
    inputFile.close()    
    return queries

def findWords(libs, queries):
    wordSet = []
    for x in range(0, CHARS):
        words = []
        for y in range(0, len(libs)):  
            if queries[x] in libs[y]:
                words.append(libs[y])
        wordSet.append(words)
    return wordSet
    
def findDiff(diffSet, queries):
    for x in range(0, CHARS):
        char = []
        for y in range(0, len(diffSet[x])):
            diffSet[x][y] = diffSet[x][y].replace(queries[x], u"")
    return diffSet
    
def findAnswers(diffSet):
    outputFile = codecs.open(OUTPUT, "w", ENCODING) 
    outputFile.write(u"\uFEFF")
    for x in range(0, len(diffSet[0])):
        matches = 0
        for y in range(1, len(diffSet)):
            for z in range(0, len(diffSet[y])):
                if diffSet[0][x] == diffSet[y][z]:
                    matches = matches + 1
                    break
        if matches == (CHARS -1):
            outputFile.write(u"%s\n" % diffSet[0][x])
    outputFile.close()            

def xword():
    appdir = os.path.abspath(os.path.dirname(sys.argv[0]))
    os.chdir(appdir) 
    if os.path.exists(LIBRARY):
        if os.path.exists(INPUT):
            libs = readLibrary()
            queries = readQuery()
            wordSet = findWords(libs, queries)
            diffSet = findDiff(wordSet, queries)
            findAnswers(diffSet)
            print "Done."
        else:
            print "Input not found, abort."
    else:
        print "Library not found, abort."
    
if __name__ == "__main__":
    xword()
    


 

原始碼加上詞庫的檔案包則在此:xword.zip

 

這支程式確實可用,不過一個顯而易見的缺陷是:它無法處理疊字型態的字詞。

 

分類: