2012-04-27 75 views
1

我用許多編程語言編寫了很多東西,而Prolog不是這些語言之一。當我給出一個拼圖表示作爲輸入時,我應該編寫一個解決數獨謎題的程序。輸入處理創建數獨網格

我的想法:
存放在一個列表的列表所有提供的數字(行列表),和蠻力可能的選項,直到一個合適(我知道,這不是最優雅的,但我沒有很多時間花時間寫出邏輯來解決傳統難題)。但是,對於Prolog而言,我很難理解事情的發展方式。輸入在列的形式的文本文件中給出看起來像

1-2---34- 
-34--1-5- 

等等等等。我的代碼閱讀和打印的文件是:

readPuzzle(File) :- 
    see(File), 
    repeat, 
    get_char(X), 
    (X = end_of_file, ! 
    ; 
    write(X), 
    fail 
), 
    seen. 

這工作都很好。因此,我們假設我試圖通過在see(File)之上添加W = [] 並用W = [W|X]替換write(X)來構建該列表。根據我的經驗,這應該創建一個由文本文件提供的所有字符的長列表。
它沒有。 有人請要麼

  • 提前告訴我我完成任務的更好更prological方式
  • 解釋,我怎麼能解決這個問題。

回答

1

有幾種方法可以完成規範閱讀。如果你願意重用你的代碼,我會建議使用assertz:

:- dynamic onechar/1. 

readPuzzle(File) :- 
    see(File), 
    repeat, 
    get_char(X), 
    (X = end_of_file, ! 
    ; 
    asssertz(onechar(X)), % write(X), 
    fail 
), 
    seen. 

,並使用

..., findall(L, retract(onechar(C)), Cs), ... 

得到字符的列表讀取,那麼你就需要分割的行列表,丟棄行的分隔符。

否則,而不是斷言/收縮,我們可以使用的服務斷言,收集更多的結構化輸入和約束長度,同時閱讀:

readPuzzle(File, Puzzle) :- 
    see(File), 
    length(Puzzle, 9), % this allocates a list of unbound variables 
    maplist(read_a_line, Puzzle), 
    seen. 

read_a_line(Line) :- 
    length(Line, 9), 
    maplist(get_char, Line), 
    get_char(_). % get rid of nl 

對於如何工作的SWI-Prolog的一個例子:

?- length(L,9),see(user),maplist(get,L),seen. 
|: 987654321 

L = [57, 56, 55, 54, 53, 52, 51, 50, 49]. 

更新

這裏是另一種方式,用accumulato RS收集結構化輸入和大小..

readPuzzle(File, Puzzle, Length) :- 
    see(File), 
    readLines([], 0, Puzzle, Length), 
    seen. 

readLines(SoFar, CountSoFar, Lines, CountLines) :- 
    get_char(C), % lookahead 
    C \= end_of_file, 
    readLine(C, [], Line), 
    M is SoFar + 1, 
    readLines([Line|SoFar], M, Lines, CountLines). 
readLines(Lines, TotLines, Lines, TotLines). 

readLine(C, Line, Line) :- 
C == 10. 
readLine(C, SoFar, Line) :- 
get_char(S), 
readLine(S, [C|SoFar], Line). 
+0

這有助於TON謝謝你現在說,我不知道這個數獨題是什麼規模,你會如何保持多少個字符之前被讀取的軌道說「。 \ n'被擊中了嗎?只要做一些像你在這裏給出的東西,並提供一個!當'\ n'被擊中,然後得到長度..? – 2012-04-27 06:04:21

+0

我會補充另一種方式,看到更新的答案 – CapelliC 2012-04-27 06:11:23

+0

啊啊謝謝太多了!你不知道這有多大的幫助。Prolog對我來說是非常陌生的.. – 2012-04-27 06:33:14

2

我會寫一個DCG描述謎語法,然後用庫(PIO)使用DCG從文件中讀取的難題。例如:

:- use_module(library(pio)). 

puzzle([Line|Lines]) --> 
     line(Line), 
     !, 
     puzzle(Lines). 
puzzle([]) --> []. 

line([]) --> "\n". 
line([_|Ls]) --> "-", !, line(Ls). 
line([N|Ls]) --> [D], { name(N, [D]) }, line(Ls). 

當我將示例拼圖保存在文件「sud。TXT」,我得到:。

?- phrase_from_file(puzzle(Ps), 'sud.txt'), maplist(writeln, Ps). 
[1,_G517,2,_G526,_G529,_G532,3,4,_G547] 
[_G553,3,4,_G568,_G571,1,_G580,5,_G589] 
Ps = [[1, _G517, 2, _G526, _G529, _G532, 3, 4|...], [_G553, 3, 4, _G568, _G571, 1, _G580|...]].