Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations Mike Lewis on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

help with arranging flags program

Status
Not open for further replies.

invalid6363

Programmer
Mar 21, 2008
24
US
i'm trying to learn prolog and one of the problems that i am trying to do is the following:
Write a Prolog program that takes the total number of flags of each color and some initial arrangement
of flags. The initial arrangement may be empty, or it may specify that certain positions in the line have
a flag of a certain color. Your program will determine all valid arrangements of the flags. If no valid
arrangements can be created for given inputs, your program will return false (“No”).
Code:
%arrangeFlags/6 takes 6 arguments:
%InitialLine: The initial arrangement of flags.  This can be a list of variables, but its length must 
%always be equal to the total number of flags.
%
%R,Y,G,B: Number of red, yellow, green, and blue flags respectively.
%Precondition: The total number of flags is equal to the length of the initial line.  
%If this precondition is not met arrangeFlags/6 is not required to do anything: It may 
%produce incorrect results or cause an error.
%All the test problems below meet this precondition.
%
%CompleteLine: A variable to hold the completed line of flags.

								%Force CompleteList to have the initial arrangement
arrangeFlags(InitialLine, R, Y, G, B, CompleteLine) :- =(InitialLine, CompleteLine),
							not(occurs(CompleteLine,r,r)),
							not(occurs2(CompletLine,g,g,g)),
							not(occurs(CompleteLine,y,g)),
							not(occurs2(CompleteLine,y,b,y)),
							occurs(CompleteLine,b,g),
							atLeastNMembers(r,CompleteLine,R),
							atLeastNMembers(y,CompleteLine,Y),
							atLeastNMembers(g,CompleteLine,G),
							atLeastNMembers(b,CompleteLine,B).

  
%atLeastNMembers: true if the item appears in the list at least as many times as
%specified by the integer.

atLeastNMembers(_,[],0).
atLeastNMembers(X,[X|T],N) :- atLeastNMembers(X,T,M), N is M+1.
atLeastNMembers(X,[Y|T],N) :- not(X=Y), atLeastNMembers(X,T,N).

%checks for patterns of two in the complete line of flags

occurs([X,Y|_],X,Y).
occurs([X|Y],X,Y).
occurs([_|L],X,Y) :-  occurs(L,X,Y).

%checks for patterns of three in the complete line of flags

occurs2([X,Y,Z|_],X,Y,Z).
occurs2([X,Y|Z],X,Y,Z).
occurs2([X|Y,Z],X,Y,Z).
occurs2([_|L],X,Y,Z) :- occurs2(L,X,Y,Z).

%Testing Examples:

%Single red flag
go(1, Line) :- arrangeFlags([_], 1,0,0,0, Line).

%2 reds and 3 greens
go(5, Line) :- arrangeFlags([_,_,_,_,_], 2,0,3,0, Line).

%3 yellows and 3 blues
go(9, Line) :- arrangeFlags([_,_,_,_,_,_], 0,3,0,3, Line).

%1 of each
go(10, Line) :- arrangeFlags([_,_,_,_], 1,1,1,1, Line).

%2 of each, some filled in
go(11, Line) :- arrangeFlags([r,b,_,g,r,_,_,_], 2, 2, 2, 2, Line).

%3 greens, 2 of other, some filled in
go(12, Line) :- arrangeFlags([y,y,_,_,_,g,_,_,b], 2, 2, 3, 2, Line).

%testing a specific line
go(13, Line) :- arrangeFlags([y,y,b,y,r], 1, 3, 0, 1, Line).

%testing a specific line
go(14, Line) :- arrangeFlags([g,g,y,b,g], 0, 1, 3, 1, Line).
i added the arguments to the arrangeFlags clause and i added the predicates atLeastNMember,occurs, and occurs2 to help check that the flags are arranged in the correct order.
Arrangement Rules:
-You must not put two red flags next to each other
-You must not put a yellow flag to the immediate left of a green flag
-You must not put a blue flag immediately between two yellow flags
-You must not put three green flags together in a row
-If the second to last flag is blue, the last flag must be green.

when i run the program all i get is fail("No") but the results should like this:
Code:
?- go(1,Line).
Line = [r] ;
No
?- go(5, Line).
Line = [r, g, r, g, g] ;
Line = [r, g, g, r, g] ;
Line = [g, r, g, r, g] ;
Line = [g, r, g, g, r] ;
Line = [g, g, r, g, r] ;
No
?- go(9, Line).
Line = [y, y, b, b, y, b] ;
Line = [y, b, b, y, y, b] ;
Line = [y, b, b, b, y, y] ;
Line = [b, y, b, b, y, y] ;
Line = [b, b, y, y, y, b] ;
Line = [b, b, b, y, y, y] ;
No

Does anyone have any suggestions on how to get the code to work correctly?
side note: i am using SWI-Prolog v5.6.51
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top