Prolog Logic/Einstein Puzzle

后端 未结 5 997
我寻月下人不归
我寻月下人不归 2021-01-29 01:26

The problem is

Brown, Clark, Jones and Smith are four substantial citizens who serve the community as architect, banker, doctor and lawyer, though not necessarily respe

5条回答
  •  -上瘾入骨i
    2021-01-29 02:04

    Here's my answer to the problem:

    puzzle(Puzzle) :-
        Names = [brown,clark,jones,smith],
    
        permute(Names,Conservatives),
    
    % Brown is more conservative than Jones.
        ismore(brown,jones,Conservatives),
    
    % Brown is less conservative than Smith.
        isless(brown,smith,Conservatives),
    
        permute(Names,Golfs),
        permute(Names,Ages),
    
    % Brown is a better golfer than those older than him.
        worsethans(brown,Golfs,WorseAtGolfThanBrown),
        betterthans(brown,Ages,OlderThanBrown),
        members(OlderThanBrown,WorseAtGolfThanBrown),
    
        permute(Names,Incomes),
    
    % Brown has a higher income than those younger than Clark.
        worsethans(brown,Incomes,WorseIncomeThanBrown),
        worsethans(clark,Ages,YoungerThanClark),
        members(YoungerThanClark,WorseIncomeThanBrown),
    
        permute([banker,architect,lawyer,doctor],Jobs),
    
    % Banker has a higher income than architect.
        lookup(banker,Jobs,Names,Banker),
        lookup(architect,Jobs,Names,Architect),
        ismore(Banker,Architect,Incomes),
    
    % Banker is neither youngest nor oldest.
        ([_,Banker,_,_]=Ages;[_,_,Banker,_]=Ages),
    
    % Doctor is a worse golfer than lawyer.
        lookup(doctor,Jobs,Names,Doctor),
        lookup(lawyer,Jobs,Names,Lawyer),
        ismore(Lawyer,Doctor,Golfs),
    
    % Doctor is less conservative than architect.
        ismore(Architect,Doctor,Conservatives),
    
    % Oldest is most conservative and has highest income.
        [Oldest,_,_,_]=Ages,
        [Oldest,_,_,_]=Conservatives,
        [Oldest,_,_,_]=Incomes,
    
    % Youngest is the best golfer.
        [_,_,_,Youngest]=Ages,
        [Youngest,_,_,_]=Golfs,
    
        Puzzle = [Names,Jobs,c(Conservatives),g(Golfs),i(Incomes),a(Ages)].
    

    It needs these supporting predicates:

    ismore(X,Y,Zs) :-
        append(Xs,[Y|_],Zs),
        member(X,Xs).
    
    isless(X,Y,Zs) :-
        append(_,[Y|Xs],Zs),
        member(X,Xs).
    
    betterthans(X,Ys,Zs) :-
        append(Zs,[X|_],Ys).
    
    worsethans(X,Ys,Zs) :-
        append(_,[X|Zs],Ys).
    
    %lookup(X,Xs,Ys,Y)
    lookup(X,[X|_],[Y|_],Y).
    lookup(X,[_|Xs],[_|Ys],Y) :-
        lookup(X,Xs,Ys,Y).
    
    members([], _).
    members([X|Xs], Ys) :-
        member(X, Ys),
        members(Xs, Ys).
    
    select([X|Xs], X, Xs).
    select([X|Xs], Y, [X|Ys]) :- select(Xs, Y, Ys).
    
    permute([], []).
    permute(Xs, [X|Zs]) :-
        select(Xs, X, Ys),
        permute(Ys, Zs).
    

    Now, the only issue I had is that this gives me more than one answer. Unless I've got the logic wrong this is what I got:

    [[brown,clark,jones,smith],[banker,architect,doctor,lawyer],c([smith,brown,clark,jones]),g([clark,brown,smith,jones]),i([smith,brown,clark,jones]),a([smith,brown,jones,clark])]
    [[brown,clark,jones,smith],[banker,architect,doctor,lawyer],c([smith,brown,clark,jones]),g([clark,brown,smith,jones]),i([smith,brown,jones,clark]),a([smith,brown,jones,clark])]
    [[brown,clark,jones,smith],[banker,architect,doctor,lawyer],c([smith,brown,clark,jones]),g([clark,brown,smith,jones]),i([smith,jones,brown,clark]),a([smith,brown,jones,clark])]
    [[brown,clark,jones,smith],[banker,architect,doctor,lawyer],c([smith,brown,clark,jones]),g([clark,brown,smith,jones]),i([smith,brown,clark,jones]),a([smith,jones,brown,clark])]
    [[brown,clark,jones,smith],[banker,architect,doctor,lawyer],c([smith,brown,clark,jones]),g([clark,brown,smith,jones]),i([smith,brown,jones,clark]),a([smith,jones,brown,clark])]
    [[brown,clark,jones,smith],[banker,architect,doctor,lawyer],c([smith,brown,clark,jones]),g([clark,brown,smith,jones]),i([smith,jones,brown,clark]),a([smith,jones,brown,clark])]
    [[brown,clark,jones,smith],[banker,doctor,architect,lawyer],c([smith,brown,jones,clark]),g([jones,brown,smith,clark]),i([smith,brown,clark,jones]),a([smith,brown,clark,jones])]
    [[brown,clark,jones,smith],[banker,doctor,architect,lawyer],c([smith,brown,jones,clark]),g([jones,brown,smith,clark]),i([smith,brown,jones,clark]),a([smith,brown,clark,jones])]
    [[brown,clark,jones,smith],[banker,doctor,architect,lawyer],c([smith,brown,jones,clark]),g([jones,brown,smith,clark]),i([smith,clark,brown,jones]),a([smith,brown,clark,jones])]
    [[brown,clark,jones,smith],[banker,architect,doctor,lawyer],c([smith,clark,brown,jones]),g([clark,brown,smith,jones]),i([smith,brown,clark,jones]),a([smith,brown,jones,clark])]
    [[brown,clark,jones,smith],[banker,architect,doctor,lawyer],c([smith,clark,brown,jones]),g([clark,brown,smith,jones]),i([smith,brown,jones,clark]),a([smith,brown,jones,clark])]
    [[brown,clark,jones,smith],[banker,architect,doctor,lawyer],c([smith,clark,brown,jones]),g([clark,brown,smith,jones]),i([smith,jones,brown,clark]),a([smith,brown,jones,clark])]
    [[brown,clark,jones,smith],[banker,architect,doctor,lawyer],c([smith,clark,brown,jones]),g([clark,brown,smith,jones]),i([smith,brown,clark,jones]),a([smith,jones,brown,clark])]
    [[brown,clark,jones,smith],[banker,architect,doctor,lawyer],c([smith,clark,brown,jones]),g([clark,brown,smith,jones]),i([smith,brown,jones,clark]),a([smith,jones,brown,clark])]
    [[brown,clark,jones,smith],[banker,architect,doctor,lawyer],c([smith,clark,brown,jones]),g([clark,brown,smith,jones]),i([smith,jones,brown,clark]),a([smith,jones,brown,clark])]
    

    I can constrain it to a single solution if I also say that Clark's income is greater than Brown's.

    Can anyone confirm if my answer is correct or not and if there should be more constraints?

提交回复
热议问题