简体   繁体   中英

Prolog: Solving a Puzzle

I am new to prolog and I am trying to solve the following question. I am having difficulty trying to understand the logic to solve the problem. I know its similar to zebra problem but, I am unsure how to approach. Any help would be greatly appreciated.

The answers submitted by five students to a T/F quiz are as follows.

Teresa: T T F T F
Tim:    F T T T F
Tania:  T F T T F
Tom:    F T T F T
Tony:   T F T F T
  1. Tania got more answers right than Teresa did.
  2. Tom got more right than Tim.
  3. Tony did not get all the answers right, nor did he get them all wrong.

Write a Prolog program quiz(Answer) that asserts Answer is the list of t and f constants that is the correct answer to the quiz..

If you use SWI-Prolog, you can use library clpfd to solve the puzzle :, I get only one solution (f,f,t,f,t).

You have a solution [A,B,C,D,E]. You initialize the possibles solutions with

[A,B,C,D,E] ins 0..1,

You reify all the answers for teresa for example

teresea([1,1,0,1,0]).
A #= 1 #<==> TA
B #= 1 #<==> TB
.....

you compute the sum of Tis

sum([TA, TB, ...], #= , Steresa),

and later you will have for Tania got more answers right than Teresa did.

Stania #> Steresa

You get the solution with

label([A,B,C,D,E]).

Hope this helps

small puzzles like this can be solved by generate-and-test

solve(L) :-
    % generator
    length(L, 5), maplist(tf, L),

    % Tania got more answers right than Teresa did.
    matches(L, tania, Tania),
    matches(L, teresa, Teresa), Tania > Teresa,
...

tf(t).
tf(f).

teresa(t, t, f, t, f).
tim(f, t, t, t, f).
...

Of course, matches(L, tania, Tania) counts correct Tania' answers.

But, I don't find a solution. The only tuple that 'get thru' Tony, it's its exact result. So, this condition

Tony did not get all the answers right

cannot be solved...

edit I had a bug in matches/3. Of course there is a solution.

edit well, the CLP(FD) version can be very compact, while being more general...

teresa(t, t, f, t, f).
...

matches(L, P, N) :-
    call(P, A,B,C,D,E),
    foldl(eqsum, [A,B,C,D,E], L, 0, N).
eqsum(t,Ls,Acc,N) :-    N #= Acc + (° #<==> Ls #= 1).
eqsum(f,Ls,Acc,N) :-    N #= Acc + (° #<==> Ls #= 0).

solve(L) :-
    length(°L, 5) ins 0..1,
    % Tania got more answers right than Teresa did.
    matches(L, tania, °) #> matches(L, teresa, °),
    % Tom got more right than Tim.
    matches(L, tom, °) #> matches(L, tim, °),
    % Tony did not get all the answers right, nor did he get them all wrong.
    matches(L, tony, °Tony) #> 0, Tony #< 5.

I used my lifter here.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM