jcb(Answer) :-
% 682; 1 right & in places
mastermind([6,8,2],Answer,1,0),
% 614; 1 right but wrong place
mastermind([6,1,4],Answer,0,1),
% 206; 2 digits right but wrong place
mastermind([2,0,6],Answer,0,2),
% 738; all wrong
% mastermind([7,3,8],Answer,0,0),
% 380; one right but wrong place
mastermind([3,8,0],Answer,0,1).
mastermind(Guess,Answer,Black,White) :-
layout(Guess),
layout(Answer),
all(Guess,digit),
all(Answer,digit),
count_blacks(Guess, Answer, Black),
count_whites(Guess, Answer, N),
White is N - Black.
layout(X) :- X=[_,_,_].
digit(0).
digit(1).
digit(2).
digit(3).
digit(4).
digit(5).
digit(6).
digit(7).
digit(8).
digit(9).
% check if all elements of a list fulfill certain criteria
all([],_).
all([H|T],Function) :- call(Function,H),all(T,Function).
count_blacks([],[],0).
count_blacks([H1|T1], [H2|T2], Cnt2) :- H1=H2,count_blacks(T1,T2,Cnt1),Cnt2 is Cnt1+1.
count_blacks([H1|T1], [H2|T2], Cnt) :- \+ H1=H2,count_blacks(T1,T2,Cnt).
count_whites(G,A,N) :-
color_cooccurrence(G,A,0,C0),
color_cooccurrence(G,A,1,C1),
color_cooccurrence(G,A,2,C2),
color_cooccurrence(G,A,3,C3),
color_cooccurrence(G,A,4,C4),
color_cooccurrence(G,A,5,C5),
color_cooccurrence(G,A,6,C6),
color_cooccurrence(G,A,7,C7),
color_cooccurrence(G,A,8,C8),
color_cooccurrence(G,A,9,C9),
N is C0+C1+C2+C3+C4+C5+C6+C7+C8+C9.
% count color cooccurrences in C and G list
color_cooccurrence(C,G,Color,Cnt) :-
countall(C,Color,CCnt),
countall(G,Color,GCnt),
min(GCnt,CCnt,Cnt).
% count occurrence in list
count([],X,0).
count([X|T],X,Y):- count(T,X,Z), Y is 1+Z.
count([X1|T],X,Z):- X1\=X,count(T,X,Z).
countall(List,X,0) :-
sort(List,List1),
\+ member(X,List1).
countall(List,X,C) :-
sort(List,List1),
member(X,List1),
count(List,X,C).
% min of two objects
min(X,Y,X) :- X<Y.
min(X,Y,Y) :- X>=Y.