Age comparsion for Zebra Riddle

121 Views Asked by At

I'm trying to solve a logic riddle similar to the Einstein riddle with ECLiPSe Prolog via CLP:

A band has 6 jazz-musicians, no one is younger than 70 years old. Every artist has written a different song.

The used instruments are: a piano at position 1 (outer left side of the band), a flute at position 2 (on the right side of position 1), the drums at position 3 (on the right side of position 2), a double bass at position 4 (on the right side of position 3), a saxophon at position 5 (on the right side of position 4) and a trumpet at position 6 (outer right side of the band).

The first names of the artists are: Andi, Cornelius, Fritz, Markus, Pete, Walter.
The last names of the artists are: Bramkamp, Franke, Karolewicz, Lueg, Schlüter, Weidemann.
The ages of the artists are: 76, 77, 78, 79, 80, 82.
The the title of the songs are: Im Bermudadreieck, Jupps-Eck-Blues, Krösken-Tanz, Legende vom Bergmann, Sally's Dog, Wanne-Eickel-Blues.

Clue 1: The man at the piano ist at least two years older than the double bass user.
Clue 2: One position further to Lueg's right is Walter. Walter is also one position further to the left than Sally's Dog composer.
Clue 3: The man on position 5 is one year younger than Pete and one year older than the composer of Im Bermudadreieck.
Clue 4: One position further to the right than the 77 year old artist is the composer of Wanne-Eickel-Blues.
Clue 5: One position further to right than Fritz is Franke. Franke is at least 3 years older than the composer of Legende von Bergmann. This composer is older than Schlüter.
Clue 6: One position further to the right than Cornelius is the 80 years old Weidemann. Weidemann is also one position further to the left than Karolewicz. None of them is the composer of Krösken-Tanz.
Clue 7: Schlüter, composer of Jupps-Eck-Blues, is one position further to the right than Markus. Schlüter is one position further to the left than Andi.

I'm totally new to Prolog, thanks to http://www.hakank.org/bprolog/ and http://www.hakank.org/bprolog/a_round_of_golf.pl I was able to get most of the code done. Currently I stuck on Clue 4, I don't know how to combine the position (1..6) of the 77 year old artist with with the Age List (76..80:82).

go :-
        
    N = 6,
    
    Piano = 1,
    Flute = 2,
    Drums = 3,
    DoubleBass = 4,
    Saxophon = 5,
    Trumpet = 6,
    Instrument = [Piano, Flute, Drums, DoubleBass, Saxophon, Trumpet],
    InstrumentS = ['Piano', 'Flute', 'Drums', 'DoubleBass', 'Saxophon', 'Trumpet'],
    
    FirstName = [Andi, Cornelius, Fritz, Markus, Pete, Walter], 
    FirstNameS = ['Andi', 'Cornelius', 'Fritz', 'Markus', 'Pete', 'Walter'],
    FirstName :: 1..N,
    
    LastName = [Bramkamp, Franke, Karolewicz, Lueg, Schlueter, Weidemann],
    LastNameS = ['Bramkamp', 'Franke', 'Karolewicz', 'Lueg', 'Schlüter', 'Weidemann'],
    LastName :: 1..N,
    
    Song = [Bermudadreieck, Jupps, Kroesken, Legende, Sally, Wanne],
    SongS = ['Im Bermudadreieck', 'Jupps-Eck-Blues', 'Krösken-Tanz', 
    'Legende vom Bergmann', 'Sally`s Dog', 'Wanne-Eickel-Blues'],
    Song :: 1..N,
    
    length(Age ,N),
    Age :: [76, 77, 78, 79, 80, 82],
    Age = [Age_Piano, Age_Flute, Age_Drums, Age_DoubleBass, Age_Saxophon, Age_Trumpet],

    alldifferent(FirstName), 
    alldifferent(LastName),
    alldifferent(Age),
    alldifferent(Song),

    % Clue 1 ---
    % The man at the piano ist at least two years older than the double bass user.
    Age_Piano #>= Age_DoubleBass + 2, 
    
    % Clue 2 ---
    % One position further to Lueg's right is Walter. 
    % Walter is also one position further to the left than Sally's Dog composer.
    Walter #= Lueg + 1, 
    Walter #= Sally - 1, 
    
    % Clue 3 ---
    % The man on position 5 is one year younger than Pete 
    % and one year older than the composer of Im Bermudadreieck.

    element(Pete, Age, Age_Pete),
    element(Bermudadreieck, Age, Age_Bermudadreieck),
    
    Pete #\= 5, 
    Bermudadreieck #\= 5,
    Age_Saxophon #= Age_Pete - 1,
    Age_Saxophon #= Age_Bermudadreieck + 1,
    
    % Clue 4 ---
    % One position further to the right than the 77 year old artist is the composer of Wanne-Eickel-Blues.
    element(Wanne, Age, Age_Wanne),
    
    Age_Wanne #\= 77, 
    
    % Clue 5 ---
    % One position further to right than Fritz is Franke. 
    % Franke is at least 3 years older than the composer of Legende von Bergmann. 
    % This composer is older than Schlüter.
    
    element(Franke, Age, Age_Franke),
    element(Legende, Age, Age_Legende),
    element(Schlueter, Age, Age_Schlueter),
    
    Franke #= Fritz + 1,
    Franke #\= Legende,
    Franke #\= Schlueter,
    Age_Franke #>= Age_Legende + 3,
    Age_Legende #> Age_Schlueter,
    
    % Clue 6 ---
    % One position further to the right than Cornelius is the 80 years old Weidemann. 
    % Weidemann is also one position further to the left than Karolewicz. 
    % None of them is the composer of Krösken-Tanz.
    
    element(Weidemann, Age, Age_Weidemann),
    
    Age_Weidemann #= 80,
    Weidemann #= Cornelius + 1,
    Weidemann #= Karolewicz - 1,
    Weidemann #\= Kroesken,
    Cornelius #\= Kroesken,
    Karolewicz #\= Kroesken,
    
    % Clue 7 ---
    % Schlüter, composer of Jupps-Eck-Blues, is one position further to the right than Markus. 
    % Schlüter is one position further to the left than Andi.
    Schlueter #= Jupps,
    Schlueter #= Markus + 1,
    Schlueter #= Andi - 1,

    term_variables([FirstName, LastName, Age, Song], Vars),

    labeling(Vars).
1

There are 1 best solutions below

2
On

Implemented working solution and nice presentation of results, thanks to http://www.hakank.org/eclipse/. The trick was to create another list AgePos with all ages and the given the position range [1..N].

[...]
AgePos = [AP76, AP77, AP78, AP79, AP80, AP82],
AgePos :: 1..N,
[...]

Then I linked this list with Age.

[...]
nth1(AP76, Age, Age_AP76),
Age_AP76 #= 76,
[...]

The full code, with some adjustments

:- lib(ic).
:- lib(listut).

go :-
    
N = 6,
Range = 1..N,

Piano = 1,
Flute = 2,
Drums = 3,
DoubleBass = 4,
Saxophon = 5,
Trumpet = 6,
Instrument = [Piano, Flute, Drums, DoubleBass, Saxophon, Trumpet],
InstrumentS = ['piano', 'flute', 'drums', 'double bass', 'saxophon', 'trumpet'],

FirstName = [Andi, Cornelius, Fritz, Markus, Pete, Walter], 
FirstNameS = ['Andi', 'Cornelius', 'Fritz', 'Markus', 'Pete', 'Walter'],
FirstName :: Range,

LastName = [Bramkamp, Franke, Karolewicz, Lueg, Schlueter, Weidemann],
LastNameS = ['Bramkamp', 'Franke', 'Karolewicz', 'Lueg', 'Schlüter', 'Weidemann'],
LastName :: Range,

Song = [Bermudadreieck, Jupps, Kroesken, Legende, Sally, Wanne],
SongS = ['Im Bermudadreieck', 'Jupps-Eck-Blues', 'Krösken-Tanz', 
'Legende vom Bergmann', 'Sally`s Dog', 'Wanne-Eickel-Blues'],
Song :: Range,

AgePos = [AP76, AP77, AP78, AP79, AP80, AP82],
AgePos :: Range,

dim(Age, [N]),
Age :: [76, 77, 78, 79, 80, 82],
collection_to_list(Age, AgeList),

alldifferent(FirstName), 
alldifferent(LastName),
alldifferent(Age),
alldifferent(AgePos),
alldifferent(Song),

% Age Setting

nth1(AP76, AgeList, Age_AP76),
nth1(AP77, AgeList, Age_AP77),
nth1(AP78, AgeList, Age_AP78),
nth1(AP79, AgeList, Age_AP79),
nth1(AP80, AgeList, Age_AP80),
nth1(AP82, AgeList, Age_AP82),

Age_AP76 #= 76,
Age_AP77 #= 77,
Age_AP78 #= 78,
Age_AP79 #= 79,
Age_AP80 #= 80,
Age_AP82 #= 82,

% Clue 1 ---
% The man at the piano ist at least two years older than the double bass user.

nth1(Piano, AgeList, Age_Piano),
nth1(DoubleBass, AgeList, Age_DoubleBass),

Age_Piano #>= Age_DoubleBass + 2, 

% Clue 2 ---
% One position further to Lueg's right is Walter. 
% Walter is also one position further to the left than Sally's Dog composer.

Walter #= Lueg + 1, 
Walter #= Sally - 1, 

% Clue 3 ---
% The man on position 5 is one year younger than Pete 
% and one year older than the composer of Im Bermudadreieck.

nth1(Pete, AgeList, Age_Pete),
nth1(Bermudadreieck, AgeList, Age_Bermudadreieck),

Age_Saxophon #= Age_Pete - 1,
Age_Saxophon #= Age_Bermudadreieck + 1,

% Clue 4 ---
% One position further to the right than the 77 year old artist is 
% the composer of Wanne-Eickel-Blues.

Wanne #= AP77 + 1,

% Clue 5 ---
% One position further to right than Fritz is Franke. 
% Franke is at least 3 years older than the composer of Legende von Bergmann. 
% This composer is older than Schlüter.

nth1(Franke, AgeList, Age_Franke),
nth1(Legende, AgeList, Age_Legende),
nth1(Schlueter, AgeList, Age_Schlueter),

Franke #= Fritz + 1,
Franke #\= Legende,
Franke #\= Schlueter,
Age_Franke #>= Age_Legende + 3,
Age_Legende #> Age_Schlueter,

% Clue 6 ---
% One position further to the right than Cornelius is the 80 years old Weidemann. 
% Weidemann is also one position further to the left than Karolewicz. 
% None of them is the composer of Krösken-Tanz.

nth1(Weidemann, AgeList, Age_Weidemann),

Age_Weidemann #= 80,
Weidemann #= Cornelius + 1,
Weidemann #= Karolewicz - 1,
Weidemann #\= Kroesken,
Cornelius #\= Kroesken,
Karolewicz #\= Kroesken,

% Clue 7 ---
% Schlüter, composer of Jupps-Eck-Blues, is one position further to the right than Markus. 
% Schlüter is one position further to the left than Andi.

Schlueter #= Jupps,
Schlueter #= Markus + 1,
Schlueter #= Andi - 1,

term_variables([FirstName, LastName, Age, Song], Vars),

labeling(Vars),

write('\nPosition\t\tFirst Name\t\tLast Name\t\tAge\t\tSong\n'),
write('---------\t\t---------\t\t---------\t\t---------\t\t---------\n'),

( foreach(I, Instrument),
    foreach(IS, InstrumentS),
    param(FirstName, FirstNameS, LastName, LastNameS, AgeList, Song, SongS)
    do 
    
    printf('%w', [IS]),
    
    ( foreach(F, FirstName),
            foreach(FS, FirstNameS),
            param(I) do
            
            F == I ->
            printf('\t\t%w', [FS])
    ;
            true
    ),
    ( foreach(L, LastName),
            foreach(LS, LastNameS),
            param(I) do
            
            L == I ->
            printf('\t\t%w', [LS])
    ;
            true
    ),
    
    nth1(I, AgeList, A),
    printf('\t\t%w', [A]), 
    
    ( foreach(S, Song),
            foreach(SS, SongS),
            param(I) do
            
            S == I ->
            printf('\t\t%w\n', [SS])
    ;
            true
    )
).