【问题标题】:Beginner Prolog Logic Puzzle初学者序言逻辑拼图
【发布时间】:2018-02-27 01:01:31
【问题描述】:

请耐心等待,我知道这显然非常简单。我似乎无法围绕序言。我有这个逻辑问题:

在最近的节日中,100 米热火受到了严密监控。

每位参赛者必须参加两场比赛,以便确定平均名次。

只有一名跑者在两场比赛中都在同一个地方完赛。

艾伦从来都不是最后的。查尔斯总是打败达伦。布赖恩至少有一个 第一名。艾伦至少在其中一场比赛中获得第三名。两个达伦 查尔斯获得第二名。这两个结果是什么?

答案:第 1 场比赛:Brian、Charles、Alan、Darren。第二场比赛:查尔斯、达伦、艾伦、 布赖恩。

这是我到目前为止想出的,但我无法弄清楚“至少”和其他更复杂的条件。

place(one).
place(two).
place(three).
place(four).

/* Place (constants): one, two, three, four.

Names (variables): Alan_1, Brian_1, Charles_1, Darren_1
Names (variables): Alan_2, Brian_2, Charles_2, Darren_2
*/

higher(one,two).
higher(one,three).
higher(one,four).
higher(two,three).
higher(two,four).
higher(three,four).

is_higher(X,Y):- higher(X,Y).
is_higher(X,Y):- higher(X,Z), is_higher(Z,Y).


is_different(S,T,U,V,W,X,Y,Z):- W\=X,W\=Y,W\=Z,X\=Y,X\=Z,Y\=Z,W\=S,W\=T,
            W\=U,W\=V,S\=T,T\=U,U\=V,S\=U,S\=V,T\=V,
            T\=W,T\=X,T\=Y,T\=Z,U\=W,U\=X,U\=Y,U\=Z,
            V\=X,V\=Y,V\=Z.


solution(Alan_1, Brian_1, Charles_1, Darren_1, Alan_2, Brian_2, Charles_2, 
Darren_2):-
place(Alan_1), place(Brian_1), place(Charles_1), place(Darren_1), 
place(Alan_2), place(Brian_2), place(Charles_2), place(Darren_2),
Alan_1\=four, Alan_2\=four, higher(Charles_1, Darren_1), higher(Charles_2, 
Darren_2),

is_different(Alan_1, Brian_1, Charles_1, Darren_1, Alan_2, Brian_2, 
Charles_2, Darren_2).

/*  Query */

% solution(Alan_1, Brian_1, Charles_1, Darren_1, Alan_2, Brian_2, Charles_2, 
Darren_2).

任何帮助或智慧之言将不胜感激。

【问题讨论】:

    标签: prolog


    【解决方案1】:

    我用 SWI + CLPFD 解决了。 为了代表“至少”, 我用了#\/

    
    
    :-use_module(library(clpfd)).
    
    solve(RaceResult):-
        RaceResult = [Alan1,Alan2,Chales1,Chales2,Brian1,Brian2,Darren1,Darren2],
        RaceResult ins 1..4,
    
        all_different([Alan1,Chales1,Brian1,Darren1]),
        all_different([Alan2,Chales2,Brian2,Darren2]),
    
        % Only one runner finished in the same place in both races.
        (Alan1 #= Alan2) #<==> AlanSame,
        (Chales1 #= Chales2) #<==> ChalesSame,
        (Brian1 #= Brian2) #<==> BrianSame,
        (Darren1 #= Darren2) #<==> DarrenSame,
        sum([AlanSame,ChalesSame,BrianSame,DarrenSame], #=, 1),
    
        % Alan was never last. 
        Alan1 #\= 4,
        Alan2 #\= 4,
    
        % Alan finished third in at least one of the races. 
        (Alan1 #= 3 ) #\/ (Alan2 #= 3),
    
        % Charles always beat Darren. 
        Chales1 #< Darren1,
        Chales2 #< Darren2,
    
        % Brian had at least one first place. 
        (Brian1 #= 1 ) #\/ (Brian2 #= 1),
    
        % Both Darren and Charles had a second place. 
        (Darren1 #= 2) #\/ (Darren2 #= 2),
        (Chales1 #= 2) #\/ (Chales2 #= 2),
    
        labeling([ffc],RaceResult).
    
    
    ?- solve([Alan1,Alan2,Chales1,Chales2,Brian1,Brian2,Darren1,Darren2]).
    Alan1 = Alan2, Alan2 = 3,
    Chales1 = Brian2, Brian2 = 1,
    Chales2 = Darren1, Darren1 = 2,
    Brian1 = Darren2, Darren2 = 4 ;
    Alan1 = Alan2, Alan2 = 3,
    Chales1 = Darren2, Darren2 = 2,
    Chales2 = Brian1, Brian1 = 1,
    Brian2 = Darren1, Darren1 = 4.
    

    也许还有其他解决方案?

    比赛1: 查莱斯 达伦 艾伦 布赖恩

    种族2: 布赖恩 查莱斯 艾伦 达伦

    ...抱歉刚刚替换了race1和race2。

    【讨论】:

      【解决方案2】:

      我是这样做的:

      puzzle :-
          Races = [[_,_,_,_],[_,_,_,_]],
          Races = [R1,R2],
          (first(brian,R1);first(brian,R2);(first(brian,R1),first(brian,R2))),
          (third(alan,R1);third(alan,R2);(third(alan,R1),third(alan,R2))),
          ((second(darren,R1),second(charles,R2));(second(darren,R2),second(charles,R1))),
          member(brian,R1),
          member(charles,R1),
          member(brian,R2),
          member(charles,R2),
          member(alan,R1),
          member(darren,R1),
          member(alan,R2),
          member(darren,R2),
          before(charles,darren,R1),
          before(charles,darren,R2),
          never_last(alan,Races),
          only_one_same(Races),
          write(Races),nl.
      
      zip_equal([],[],[]).
      zip_equal([R|R1s],[R|R2s],[R|Rs]) :- !, zip_equal(R1s,R2s,Rs).
      zip_equal([_|R1s],[_|R2s],Rs) :- !, zip_equal(R1s,R2s,Rs).
      
      never_last(X,[[A1,B1,C1,_],[A2,B2,C2,_]]) :- member(X,[A1,B1,C1]), member(X,[A2,B2,C2]).
      
      before(X,Y,[X|Rs]) :- !, member(Y,Rs).
      before(X,Y,[_|Rs]) :- before(X,Y,Rs).
      
      first(X,[X,_,_,_]).
      second(X,[_,X,_,_]).
      third(X,[_,_,X,_]).
      
      only_one_same([R1s,R2s]) :- zip_equal(R1s,R2s,[_]).
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-09
        • 2013-09-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多