2017-03-21 1 views
2

Bert Bos puzzle에 사용되는 보드를 만드는 중이며 게시판을 목록 목록으로 표시하려고합니다.프롤로그 : 빈 목록 목록을 만듭니다.

빈 목록의 목록을 작성해야합니다 (예 : [ [], [] , [] , [] ]). 문제는 입력에서 제공된 빈 목록의 정확한 수가 필요하다는 것입니다. 그래서 예를 들어 create_board (4, X)를 주면 X= [ [], [], [], [] ]을 반환해야합니다. 여기

내가 구문 오류의 몇에서 지금까지

generate_board(0, [[]]) :- ! 
generate_board(N, [[] | T]) :- 
    N =< 12, N >= 1, 
    N is N-1. 
    generate_board(N, T). 
+2

멋진 퍼즐! 링크 주셔서 감사합니다. – CapelliC

답변

0

외에 무엇을 가지고, 당신의 코드를 사용하여 주요 문제는 라인 N is N-1입니다. 프롤로그에서는 변수를 다시 할당 할 수 없습니다. 변수는 술어 전체에 단일 값을가집니다. 'N은 N-1입니다.'는 그 자체가 -1이되는 값에 대해서만 성공할 수 있습니다. 이는 분명히 결코 사실이 아닙니다. 막 감소 값에 대한 다른 변수 사용 :를 고정

은 간단

generate_board(0, [[]]) :- !. 
generate_board(N, [[] | T]) :- 
    N =< 12, N >= 1, 
    N2 is N-1, 
    generate_board(N2, T). 

?- generate_board(4, X). 
X = [[], [], [], [], []] 

는이 결과를 제공하지만, 의도 된 하나 개 이상의 요소의 더. 이 문제를 스스로 해결하는 방법을 알아낼 수 있습니까? (힌트 : 기본 케이스가 입력 0에 대해 반환하는 것을보십시오)

5

동일한 요소로 구성된 주어진 길이의 목록을 만들거나 따라서 [] 각 요소들을 통합, BoardElement 위해 여기

generate_board(Length, Board) :- 
    length(Board, Length), 
    maplist(=([]), Board). 

, maplist(=([]), Board)=([], Element) ([] = Element의 정규형)를 호출한다 :

| ?- generate_board(4, L). 

L = [[],[],[],[]] 

yes 
| ?- 
012 케이스는 maplist2를 사용하는

이 개념을 확장하여 2 차원 빈 보드를 만들 수 있습니다. (길이 Length와) 행의 목록으로 보드 (길이 Width와) 요소의 목록으로 각 행의 생각 : 여기

generate_board(Length, Width, Board) :- 
    length(Row, Width), 
    maplist(=([]), Row),   % A row of empty lists, forming an empty row 
    length(Board, Length), 
    maplist(=(Row), Board).  % A list of empty rows 

| ?- generate_board(4,3, L). 

L = [[[],[],[]],[[],[],[]],[[],[],[]],[[],[],[]]] 

yes 
| ?- 
4

하면 프로그램이 그렇다 (작동하지 않는 이유는 단지입니다 , 대신에 .). 이 부분은 실패하기 때문에 원본 프로그램도 실패합니다. 어떻게 든 가시적 인 부분을 일반화해야합니다.

 
:- op(950,fy,*). 
*_. 

generate_board(0, [[]]) :- ! 
generate_board(N, _/*[[] | T]*/) :-  % 2nd 
    * N =< 12,        % 2nd 
    * N >= 1,        % 2nd 
    N is N-1, 
    * generate_board(N, T).     % 1st generalization 

?- generate_board(4, B). 

이 방법은 순수하고 단조로운 Prolog 프로그램에서 작동합니다. 그러나 당신은 일반화를 제한하는 상처를 사용했습니다. 이 경우, 커팅 이전에 일반화하지 않도록주의를 기울여야합니다. 첫 번째 일반화는 재귀 적 목표이다. 이 조항의 마지막 목표입니다. 그런 다음에야, 다른 일반화가 절단하지 않고 장소에 당신의 프로그램에서

걸릴 수 있습니다, 우리는 더욱 프로그램을 일반화 할 수 :

 
generate_board(0, _/*[[]]*/). 
... 
2

간단한 해결책 :

generate_board(N, Board) :- 
    findall([], between(1, N, _), Board).