这个问题非常难以理解。
有没有办法(方便地)根据早期计算对元素的数量及其相关条件进行编程?
问题是“程序”在这句话中并不是一个真正可以理解的动词,因为人类对计算机进行了编程,或者对 VCR 进行了编程,但您不能“对数字进行编程”。所以我不明白你在这里想说什么。
但是我可以给你代码审查,也许通过代码审查我可以理解你提出的问题。
不请自来的代码审查
听起来您可能正在尝试通过消除死胡同来解决迷宫。
你的代码实际上做的是:
生成不是死角或与死角相邻的单元格列表,称为filtered
从步骤 1 生成一系列相邻单元格,sequences
将四个这样的相邻序列连接成一条路线。
主要问题:这只有在正确的路线正好是八格长时才有效!尝试解决这个迷宫:
[E]-[]-[]-[]
|
[ ]-[ ]-[ ]-[ ]
|
[ ]-[ ]-[ ]-[ ]
|
[ ]-[ ]-[ ]-[ ]
|
[ ]-[ ]-[ ]-[E]
因此,从代码审查向后工作,听起来您的问题是:
如果我事先不知道它有多长,我如何生成一个列表?
解决方案
您可以通过搜索(DFS、BFS、A*)解决迷宫问题。
import Control.Monad
-- | Maze cells are identified by integers
type Cell = Int
-- | A maze is a map from cells to adjacent cells
type Maze = Cell -> [Cell]
maze :: Maze
maze = ([[1], [0,2,5], [1,3], [2],
[5], [4,6,1,9], [5,7], [6,11],
[12], [5,13], [9], [7,15],
[8,16], [14,9,17], [13,15], [14,11],
[12,17], [13,16,18], [17,19], [18]] !!)
-- | Find paths from the given start to the end
solve :: Maze -> Cell -> Cell -> [[Cell]]
solve maze start = solve' [] where
solve' path end =
let path' = end : path
in if start == end
then return path'
else do neighbor <- maze end
guard (neighbor `notElem` path)
solve' path' neighbor
该功能solve
通过深度优先搜索工作。它不是将所有内容都放在一个列表理解中,而是递归地工作。
为了找到从start
到的路径end
,如果start /= end
,
查看与末尾相邻的所有单元格neighbor <- maze end
,
确保我们没有在一个单元格上回溯guard (negihbor `notElem` path)
,
尝试找到从start
到的路径neighbor
。
不要试图一下子理解整个函数,只要理解一点关于递归。
概括
如果要找到cell 0到cell 19的路径,递归:我们知道cell 18和cell 19是相连的(因为它们是直接相连的),所以我们可以尝试解决从cell 0到cell的路由问题单元格 18。
这是递归。
脚注
守卫,
someCondition a == True
相当于,
someCondition a
因此也等价于,
(someCondition a == True) == True
或者,
(someCondition a == (True == True)) == (True == (True == True))
或者,
someCondition a == (someCondition a == someCondition a)
第一个,someCondition a
很好。
do
关于符号的脚注
上面例子中的do
符号等价于列表推导,
do neighbor <- maze end
guard (neighbor `notElem` path)
solve' path' neighbor
列表理解语法中的等效代码是,
[result | neighbor <- maze end,
neighbor `notElem` path,
result <- solve' path' neighbor]