功能非常有限的 Haskell 排列

标签 haskell permutation whitelist

我必须在 haskell 中实现一个接受列表 [Int] 的函数并给出一个列表 [[Int]]具有所有排列,但我只允许使用: [] , : , True , False ,比较,&& , || ,和not

permutations [] = [[]]
permutations xs = [(y:zs) | (y,ys) <- picks xs, zs <- permutations ys]
   where
   picks (x:xs) = (x,xs) : [(y,x:ys) | (y,ys) <- picks xs]

我的想法是使用类似的东西,但我必须替换 <-

最佳答案

正如 chepner 在评论中提到的,一些缺失的基本库函数可以很容易地“当场”重新实现。

Wikipedia article on permutations除其他事项外,我们还发现 Steinhaus–Johnson–Trotter algorithm ,这似乎非常适合链接列表。

对于这个算法,一个基本的构建 block 是我们可以声明为的函数:

spread :: a -> [a] -> [[a]]

例如,表达式 spread 4 [1,2,3] 必须将 4 放置在 [1,2;3] 内的所有可能位置,因此计算结果为:[[4 ,1,2,3],[1,4,2,3],[1,2,4,3],[1,2,3,4]]。要获得 [1,2,3,4] 的所有排列,只需将 spread 4 应用于 [1,2,3] 的所有排列。以递归方式编写 spread 很容易:

spread :: a -> [a] -> [[a]]
spread x [] = [[x]]
spread x (y:ys) = (x:y:ys) : (map (y:) (spread x ys))

排列可以这样获得:

permutations :: [a] -> [[a]]
permutations [] = [[]]
permutations (x:xs) = concat (map (spread x) (permutations xs))

总体而言,符合规则的源代码版本将如下所示,具有自己的本地版本的 mapconcat Prelude 函数:

permutations :: [a] -> [[a]]
permutations  []     =  [[]]
permutations (x:xs)  =  myConcat (myMap (spread x) (permutations xs))
  where
    myMap fn  []     =  []
    myMap fn (z:zs)  =  (fn z) : (myMap fn zs)

    myConcat   []          =  []
    myConcat ([]:zss)      =  myConcat zss
    myConcat ((z:zs):zss)  =  z : (myConcat (zs:zss))

    spread z []      =  [[z]]
    spread z (y:ys)  =  ( z:y:ys) : (myMap (y:) (spread z ys))

关于功能非常有限的 Haskell 排列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70461087/

相关文章:

c# - 想要写我自己的 'Application Whitelisting Tool' 像 Bit9 这样的东西吗?

asp.net - 如何在 IIS 中将单个 URL 列入 IP 白名单

haskell - Yampa 中 react (感觉)功能的时差

function - 调用 hamlet 文件内的函数

java - 如何以编程方式提取视频帧?

python - 创建一个序列,每个元素中有两个满足一定的距离标准

haskell - 导入模块进行测试

python - 比较使用随机排列的 Numpy 和 Matlab 代码

c++ - 如何在 C++ 中生成以下排列树?

java - RabbitMQ - 信任存储让所有连接通过