输入处理创建数独网格
问题描述:
我用许多编程语言编写了很多东西,而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).
答
我会写一个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|...]].
这有助于TON谢谢你现在说,我不知道这个数独题是什么规模,你会如何保持多少个字符之前被读取的轨道说“。 \ n'被击中了吗?只要做一些像你在这里给出的东西,并提供一个!当'\ n'被击中,然后得到长度..? – 2012-04-27 06:04:21
我会补充另一种方式,看到更新的答案 – CapelliC 2012-04-27 06:11:23
啊啊谢谢太多了!你不知道这有多大的帮助。Prolog对我来说是非常陌生的.. – 2012-04-27 06:33:14