1

私は多くのプログラミング言語で多くのことをプログラミングしてきましたが、Prologはそれらの言語の1つではありません。入力としてパズル表現を与えられたときに数独パズルを解くプログラムを書くことになっています。

私のアイデア:
提供されたすべての数値をリストのリスト(行のリスト)に保存し、可能なオプションを1つに収まるまでブルートフォースします(これは最もエレガントではありませんが、書くのに多くの時間を費やす時間はありません)従来の方法でパズルを解くためのロジックを作成します)。しかし、Prologに慣れていないので、物事の進め方を理解するのに少し苦労しています。入力は、次のような行の形式でテキストファイルに入力されます。

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

などなど。ファイルを読み取って印刷するための私のコードは次のとおりです。

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

これはすべてうまく機能します。W = [] したがって、すぐ上に追加してこのリストを作成しsee(File)、を置き換えようwrite(X)としているとしましょうW = [W|X]。私の経験から、これはテキストファイルから提供されたすべての文字の長いリストを作成するはずです。
そうではありません。誰かお願いします

  • 私の前のタスクを達成するためのより良いよりプロロジカルな方法を教えてください
  • これを回避する方法を説明してください。
4

2 に答える 2

2

パズルの構文を説明するDCGを作成し、library(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|...]].
于 2012-04-27T21:10:39.063 に答える
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].

アップデート

これは、アキュムレータを使用して構造化された入力とサイズを収集する別の方法です。

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).
于 2012-04-27T05:49:13.090 に答える