'Prolog, check for specific list parameter
% adds two lists together
add_pairs(X, [], X).
add_pairs([I1, I2, I3, I4, I5], [I7, I8, I9, I10, I11], [O1, O2, O3, O4, O5]) :-
O1 is I1 + I7,
O2 is I2 + I8,
O3 is I3 + I9,
O4 is I4 + I10,
O5 is I5 + I11.
% Checks to see if the meal is satisfactory
check_sat([_, E2, E3, E4, E5], Len) :-
E2 >= 3,
E3 =< Len - 3,
E4 =< Len - 3,
E5 >= 3.
% Adds all lists in L together.
add_lists([L|[]], L).
add_lists([X, Y|T], Out) :-
add_pairs(X, Y, Sum),
append([Sum], T, TOut),
add_lists(TOut, Out).
% Calls to the functions, determining if a meal is satisfactory
satisfactory_meal(L) :-
add_lists(L, Output),
length(L, Len),
check_sat(Output, Len).
So, I'm currently working on a program where I'm given some data as input. It returns true if certain conditions are met and false otherwise. Basically, the list represents the attributes of a meal.
[Dish_number, Organic, Has_dairy, Has_meat, Locally_sourced]
The dish number is any number and the following attributes are represented as present if 1 is found and absent if 0 is in its place.
For example:
satisfactory_meal([
[8, 0, 0, 0, 1],
[9, 1, 1, 0, 1],
[23, 1, 0, 0, 1],
[2, 1, 0, 1, 0],
[6, 0, 0, 1, 1]
]).
Returns true. Because I need 3 or more instances of Organic and Locally_sourced. And there are less than or equal to the length of the List - 3 of Meat or Dairy.
satisfactory_meal([
[4, 1, 0, 0, 0],
[7, 0, 1, 0, 1],
[90, 0, 0, 0, 0],
[3, 0, 0, 1, 1]
]).
returns false because organic has a single instance and locally_sourced has two. Less than what's needed.
All's good and well with my current program setup... However, there's a test case I cannot return properly. The program should return false if a single meal is disliked by all.
Which looks like this:
% No one can eat dish 3
satisfactory_meal([
[1, 1, 0, 0, 1],
[3, 0, 1, 1, 1],
[5, 0, 0, 0, 1],
[7, 1, 0, 1, 0],
[9, 1, 0, 0, 1]
]).
% No one can eat dish 9
satisfactory_meal([
[1, 1, 0, 0, 0],
[3, 1, 0, 0, 1],
[5, 0, 0, 0, 1],
[7, 1, 0, 0, 1],
[9, 0, 1, 1, 1]
]).
A meal is disliked by all if the list looks like [#, 0, 1, 1, 0] or [#, 0, 1, 1, 1].
My issue is with how I'm currently handling my lists. I'm adding them all together, making it very easy to look for less than, greater than, and equal to values. I can't arithmetically figure out how to find the instance where a dish is disliked by all. AKA [#, 0, 1, 1, 0] or [#, 0, 1, 1, 1]. Is there a way to figure it out after summing the lists together? Or do I have to create a new function and look for those instances before adding the lists together? Any help would be most appreciated as I'm close to making this program work! Thank you.
Solution 1:[1]
I figured it out. I looked through the data before adding it together, creating a function that looks for the lack of instances of [#, 0, 1, 1, 0] or [#, 0, 1, 1, 1].
nonmember(Arg,[Arg|_]) :-
!,
fail.
nonmember(Arg,[_|Tail]) :-
!,
nonmember(Arg,Tail).
nonmember(_,[]).
nonmember([_,0,1,1,0], L),
nonmember([_,0,1,1,1], L),
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Swainstein |
