假设我有一个独特的列表,其中包含1到9之间的长度为9的随机顺序(想想数独),我想提取值1和9之间出现的项的子列表(不包括) 。 IE:between1and9([1,3,5,4,2,9,7,8,6],[3,5,4,2])
应该是真的。
目前我正在尝试使用flatten/2
,但没有太多运气。这是我目前的策略(假设我在其他地方执行List ins 1..9, maplist(all_distinct, List), length(List, 9)
以保持其整洁/分离关注点):
between1and9(List,Between) :-
flatten([_,[1],Between,[9],_], List);
flatten([_,[9],Between,[1],_], List).
当1或9位于List
的第一个或最后一个位置时,或者如果它们在List
内相邻时,此版本失败。 between1and9([_,1,9,_,_,_,_,_,_],[])
是真的,但是between1and9([_,1,9,_,_,_,_,_,_],_)
是假的(当我尝试用它作为解决更大问题的约束时失败。)
这似乎是导致两个失败的同一个问题,qazxsw poi似乎并不喜欢将未知数视为空列表,除非它们在某处显示出来。
我可以理解为什么这可能是,如果flatten
可以在第一个参数中“发明”空列表,它将意味着第一个参数中任何东西的无限解决方案。虽然我的完整程序有其他限制来防止这种情况,但我可以理解为什么flatten
可能不想容纳它。
我可以通过匹配每个排列与disjunctions来解释边缘情况(双关语)(例如:flatten
,并将Between作为空列表与:flatten([_,1,B,9,_],L);flatten([_,9,B,1,_],L);flatten([_,1,B,9]);flatten...
但这似乎已经成为一个已经很长时间的解决方案(总共10个排列)甚至更糟(18)所以我有两个(强烈相关的)问题:
\*above permutations on flatten*\; ( Between = [], (\*permutations for either edge and 1/9*\) )
我不必手动输入between1and9(L,B) :-
( ( X = 1, Y = 9 ); ( X = 9, Y = 1 ) ),
( ( Z1 = _; Z1 = [] ), ( Z2 = _ ; Z2 = [] ) ),
( B = _; B = [] ),
flatten([Z1,X,B,Y,Z2],L).
匹配的每个排列。不幸的是,这一点以及它的一些变化都是单方面失败的。我在这里错过了一些明显的东西吗? (我怀疑opperator优先,但我尝试了几个不同的版本。)flatten
文档表明,在大多数情况下,它是一种反模式,是否有更多的prolog-ish *方法来解决这个问题?考虑到我经历过的所有陷阱,我几乎可以肯定。(对不起,我很痛苦地意识到我用来描述内容的很多术语可能都是非常错误的,我只是熟悉谓词/形式逻辑而且更常用于描述控制流类型编程。虽然我在实践中理解逻辑编程相当合理,但我仍在努力寻找能够强有力地谈论它的语言,我将修改这个问题并进行任何更正。)
一些背景:我是初学者,通过尝试扩展众多数独解算器中的一个来解决我在几年前打印出的一些谜题中发现的奇怪的数据,从而显示所有数据总和在任何给定的行或列中出现在1和9之间的数字作为额外提示,它有点像数独和picross的混合。现在的解决方案是嗖嗖声:flatten/2
。虽然你到达它可能会很乱。
*推论问题:是否有“pythonic”这个词的序言版本?
你可以使用好的旧SumSudoku(swish)。你有可能一直想要append/3
,但不知何故认为它被称为append/3
?
对于“1来自9之前”的情况,你会写:
flatten
您需要将1和9交换为“9来自1”的情况。
这也留下了一个“虚假的选择点”(感谢@PauloMoura的评论)。一定要以某种方式摆脱它。
至于“Pythonic”(这来自一个正在恢复的Pythonista),我只能说,放心:
在Prolog中总有不止一种明显的方法。
你甚至不必是荷兰人。