中文填字程式
由 darkranger 在 週六, 04/13/2013 - 19:11 發表,更新日期:週三, 07/10/2013 - 11:43
話說幾天前 DR 看到一份填字題目,就是那種有三個中文字,例如「法」、「復」、「語」,然後填入一個相同的字讓各個配對可以組成合宜的字詞,以這個例子來說,可以填入的解答就例如有「古」、「國」等。而當 DR 在嘗試作答時,突然靈機一動想到,其實只要有適當的詞庫,這應該是可以用程式去協助解答的。
那麼去哪裡找詞庫呢?DR 很快的想起開放原始碼的新酷音輸入法,於是在 GitHub 上把新酷音輸入法的純文字詞庫檔(tsi.src)抓下來,接著就開始嘗試用 Python 寫出填字程式,所構思的程式運作流程大概像這樣:
- 讀取詞庫文字檔,篩選出兩個字的字詞。
- 三個題目字各自去搜尋符合的字詞,並存成三組詞庫。
- 清除三組詞庫中各自的題目字。
- 比對三組詞庫中的剩餘文字,三組詞庫皆有的字便是可用的答案。
由於 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。
這支程式確實可用,不過一個顯而易見的缺陷是:它無法處理疊字型態的字詞。