我有一个子问题,其解决方案比我怀疑的要大得多。
问题定义如下
从 group 具有 Y 和 Z 或 A 和 B 之间 id 的所有组中删除 X
表示为一个伪查询它看起来像这样 Y,Z,A,B 设置为 0,1,3,4
remove(X,
[ period(0,1), period(3,4) ],
[
group(0, [ subgroup([_,_,X,_,_]), subgroup([X])]),
group(1, [ subgroup([X])]),
group(2, [ subgroup([_,_,X])]),
group(3, [ subgroup([_,X,_])]),
group(4, [ subgroup([X,_,_])])
], UpdatedGroups).
结果将是
UpdatedGroups = [
group(0, [ subgroup([_,_,_,_]), subgroup([])]),
group(1, [ subgroup([])]),
group(2, [ subgroup([_,_,X])]),
group(3, [ subgroup([_,_])]),
group(4, [ subgroup([_,_])])
]
所以,我对此的解决方案是:
当当前周期的开始小于或等于当前周期的结束时,分组删除 X,同时“递增”一天的开始。重复直到没有更多的时期
删除组中的 X 是通过“循环”所有组来完成的,并检查它是否与时间段匹配,以及是否确实将用户从子组中删除,这又是通过“循环”完成的。
这是一个非常乏味但直接的解决方案,现在我的问题是我经常发现自己在做这样的事情,并且找不到以不太全面的方式来做这件事的方法。
除了我的方法之外,还有其他方法不涵盖 50 多行吗?
更新
非常感谢,代码变得更加简洁 - 它可能会更进一步,但现在可以在这里实际发布(这有点修改 - 但逻辑就在那里)
inPeriods(Day, [ period(Start,End) | _ ]) :- between(Start,End, Day).
inPeriods(Day, [ _ | RemainingPeriods ]) :- inPeriods(Day, RemainingPeriods).
ruleGroupsInPeriod(Periods, rulegroup(Day,_)) :- inPeriods(Day, Periods).
removeUserFromRelevantRuleGroups(UserId, Periods, RuleGroups, UpdatedRuleGroups) :-
include(ruleGroupsInPeriod(Periods), RuleGroups, IncludedRuleGroups).
exclude(ruleGroupsInPeriod(Periods), RuleGroups, ExcludedRuleGroups),
maplist(updateRuleGroup(UserId), IncludedRuleGroups, UpdatedIncludedRuleGroups)
append(UpdatedIncludedRuleGroups, ExcludedRuleGroups, UpdatedRuleGroups).
updateRuleGroup(UserId, rulegroup(X, RuleList), rulegroup(X, UpdatedRuleList)) :-
maplist(updateRule(UserId), RuleList, UpdatedRuleList).
updateRule(UserId, rule(X, UserList), rule(X, UpdatedUserList)) :-
delete(UserList, UserId, UpdatedUserList).