SWI Prolog задача про фигуры и их цвета относительно расположения
Формулировка задачи:
Доброе время суток!
Задача:
На столе лежат в четыре ряда фигуры: треугольник, ромб, круг и квадрат. Цвета этих фигур - зеленый, желтый, синий, красный. Фигура красного цвета лежит между зеленой и синей (возможно, не рядом), справа от желтой фигуры лежит ромб, круг лежит правее треугольника и ромба, причем треугольник лежит не с краю и, наконец, фигура синего цвета не лежит рядом с фигурой желтого цвета. Определить, какого цвета круг.
Наработка:
Логика наработки не верна, т.к. зависимость цвета от расположения фигуры не учтена. Не могу найти логически похожую задачу, может кто подскажет?
Листинг программы
- на_столе([['Треугольник',Треугольник],['Ромб',Ромб],['Круг',Круг],['Квадрат',Квадрат]]) :-
- Xs = [Треугольник, Ромб, Круг, Квадрат],
- Ys = [зеленый, желтый, синий, красный],
- перестановка(Xs, Ys),
- Круг \= желтый,
- Ромб \= желтый,
- Ромб \= синий,
- !.
- перестановка([], []).
- перестановка(List, [First|Perm]) :-
- выбор(First, List, Rest),
- перестановка(Rest, Perm).
- выбор(X, [X|Tail], Tail).
- выбор(Elem, [Head|Tail], [Head|Rest]) :-
- выбор(Elem, Tail, Rest).
Решение задачи: «SWI Prolog задача про фигуры и их цвета относительно расположения»
textual
Листинг программы
- /*
- На столе лежат в четыре ряда фигуры:
- треугольник, ромб, круг и квадрат.
- Цвета этих фигур -
- зеленый, желтый, синий, красный.
- Фигура красного цвета лежит между зеленой и синей (возможно, не рядом),
- справа от желтой фигуры лежит ромб,
- круг лежит правее треугольника и ромба,
- причем треугольник лежит не с краю и, наконец,
- фигура синего цвета не лежит рядом с фигурой желтого цвета.
- Определить, какого цвета круг.
- */
- f(['треугольник', 'ромб', 'круг', 'квадрат']).
- c(['зеленый', 'желтый', 'синий', 'красный']).
- s([1, 2, 3, 4, 5]).
- fc(FC) :-
- f(F), c(C), s(S),
- permutation1(F, F1),
- permutation1(C, C1),
- by_pairs(F1, C1, FC),
- check_rules(S, FC).
- by_pairs([], [], []).
- by_pairs([H1 | T1], [H2 | T2], [H1-H2 | R]) :-
- by_pairs(T1, T2, R).
- check_rules([], _).
- check_rules([H | T], FC) :-
- r(H, FC),
- check_rules(T, FC).
- % Фигура красного цвета лежит между зеленой и синей (возможно, не рядом),
- r(1, FC) :-
- select1(C1, [_-'зеленый', _-'синий'], [C2]),
- append1(_, [ C1 | R1], FC),
- append1(_, [_-'красный' | R2], R1),
- member1(C2, R2).
- % справа от желтой фигуры лежит ромб,
- r(2, FC) :-
- append1(_, [_-'желтый', 'ромб'-_ | _], FC).
- % круг лежит правее треугольника и ромба,
- r(3, FC) :-
- select1(F1, ['треугольник'-_, 'ромб'-_], [F2]),
- append1(_, [F1, F2, 'круг'-_ | _], FC).
- % причем треугольник лежит не с краю и, наконец,
- r(4, FC) :-
- \+ FC = ['треугольник'-_ | _],
- \+ append1(_, ['треугольник'-_], FC).
- % фигура синего цвета не лежит рядом с фигурой желтого цвета.
- r(5, FC) :-
- \+ append1(_, [_-'желтый', _-'синий' | _], FC),
- \+ append1(_, [ _-'синий', _-'желтый' | _], FC).
- permutation1([], []).
- permutation1(List, [First | Perm]) :-
- select1(First, List, Rest),
- permutation1(Rest, Perm).
- select1(Elem, [Elem | Tail], Tail).
- select1(Elem, [Head | Tail], [Head | Rest]) :-
- select1(Elem, Tail, Rest).
- member1(Elem, [Elem | _]).
- member1(Elem, [_ | Tail]):-
- member1(Elem, Tail).
- % если левый список пуст, то итоговый список совпадает с правым списком
- append1([], RightList, RightList).
- % иначе, взять голову из левого списка и перенести в голову итогового списка,
- append1([LeftHead|LeftTeil], RightList, [LeftHead|RightPart]) :-
- % продолжить для хвоста левого списка
- append1(LeftTeil, RightList, RightPart).
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д