2011-01-04 6 views
4

J'essaie de résoudre un exercice afin de me familiariser avec prolog.Le plus court chemin pour définir plusieurs règles dans prolog

La tâche suit:

% Sten wants to send Lisa 100 flowers. He can choose from lilies, roses and tulips. 
% One lily costs $50, rose $10 and tulip $1. Find how many flowers of each type he 
% must buy, so that he spends exactly $500. 

J'ai résolu que l'exercice, mais de manière un peu encombrant je suppose. Mon code est:

% numbers 1..100 
digit(1). digit(2). digit(3). digit(4). digit(5). digit(6). digit(7). digit(8). 
digit(9). digit(10). digit(11). digit(12). digit(13). digit(14). digit(15). digit(16). 
digit(17). digit(18). digit(19). digit(20). digit(21). digit(22). digit(23). digit(24). 
digit(25). digit(26). digit(27). digit(28). digit(29). digit(30). digit(31). digit(32). 
digit(33). digit(34). digit(35). digit(36). digit(37). digit(38). digit(39). digit(40). 
digit(41). digit(42). digit(43). digit(44). digit(45). digit(46). digit(47). digit(48). 
digit(49). digit(50). digit(51). digit(52). digit(53). digit(54). digit(55). digit(56). 
digit(57). digit(58). digit(59). digit(60). digit(61). digit(62). digit(63). digit(64). 
digit(65). digit(66). digit(67). digit(68). digit(69). digit(70). digit(71). digit(72). 
digit(73). digit(74). digit(75). digit(76). digit(77). digit(78). digit(79). digit(80). 
digit(81). digit(82). digit(83). digit(84). digit(85). digit(86). digit(87). digit(88). 
digit(89). digit(90). digit(91). digit(92). digit(93). digit(94). digit(95). digit(96). 
digit(97). digit(98). digit(99). digit(100). 

quantity(A1,A2,A3):- 
    var(A1), var(A2), var(A3), 
    digit(A1), digit(A2), digit(A3), 
    X is A1+A2+A3, X is 100, 
    Y is (A1*50)+(A2*10)+(A3*1), Y is 500. 

Quelqu'un peut-il suggérer une meilleure méthode pour initialiser ces règles? Par exemple dans Haskell je pourrais faire quelque chose comme ceci:

let numbers = [1..100] 

Merci d'avance.

Répondre

5

Certaines versions de Prolog ont le prédicat entre/3. On pourrait dire

digit(X):-between(1,100,X). 

Si entre n'est pas disponible, on peut dire

digit(X):-member(X,[1,2,3,4,5 and so on]). 

Si vous ne souhaitez pas utiliser membre/2, l'utilisation récursivité.

Edit: vous pouvez également mettre en œuvre entre/3 comme ceci:

my_between(X,Y,Z):-X<Y,(Z=X;X2 is X+1,my_between(X2,Y,Z)). 

Une mise en œuvre robuste et efficace entre/3 peut être plus compliqué, mais pour vos besoins, cela devrait être suffisant.

+1

Votre deuxième option l'oblige encore à préciser tous les 100 numéros, donc il faut encore 'O (n) 'taper. C'est aussi très inefficace. – sepp2k

+1

Oui, c'est vrai. D'autre part, le chiffre (X): - 1 =

+0

Droit, mon mauvais. Je n'ai pas lu assez attentivement la description du problème. – sepp2k

7

En utilisant SWI-Prolog:

:- use_module(library(clpfd)). 

flowers(L, R, T) :- 
     [L,R,T] ins 0..sup, 
     L+R+T #= 100, 
     L*50 + R*10 + T*1 #= 500. 

Exemple requête:

?- flowers(Lilies, Roses, Tulips), label([Lilies,Roses,Tulips]). 
Lilies = 1, 
Roses = 39, 
Tulips = 60 ; 
false. 
2
quantity(lilies(L),roses(R),tulips(T)) :- 
    between(0,100,L), 
    between(0,100,R), 
    between(0,100,T), 
    L + R + T =:= 100, 
    L*50 + R*10 + T =:= 500 . 
Questions connexes