1

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..

lurker
  • 56,987
  • 9
  • 69
  • 103
mayak
  • 21
  • 3
  • 4
    Sounds like a fun puzzle. Why do you want to ruin it for yourself by cheating by asking for the solution here? – wvdz Jan 29 '15 at 21:12
  • Looks like it has two possible answers.. – Eugene Sh. Jan 29 '15 at 23:08
  • I am not looking for the solution, I just need help to figure out the logic for it. A flow of steps that i could potentially use. – mayak Jan 30 '15 at 00:18
  • Think about what facts are being stated first (each student with their answers) and decide how you want to represent them. For example, `answers(teresa, [t,t,f,t,f]).`, etc. You could create a predicate to generate possible correct answer sets and compute each person's score against it. Backtrack when the conditions for score comparisons don't match. There really is only one result. – lurker Jan 30 '15 at 02:28

2 Answers2

1

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

joel76
  • 5,565
  • 1
  • 18
  • 22
  • 1
    Thank you for posting this. It helped me a lot in figuring out and starting the problem. Now, I am practicing more problems like this. This was my first question on stackoverflow :) – mayak Feb 02 '15 at 17:31
  • If you are OK with this answer please click for accept it – joel76 Feb 02 '15 at 17:52
0

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.

CapelliC
  • 59,646
  • 5
  • 47
  • 90