输入处理创建数独网格

问题描述:

我用许多编程语言编写了很多东西,而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方式
  • 解释,我怎么能解决这个问题。

有几种方法可以完成规范阅读。如果你愿意重用你的代码,我会建议使用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

我会写一个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|...]].