如何在Haskell中将整数列表转换为真假矩阵

Inf*_*ity 6 haskell

在本练习中,我应该编写一个函数,它接收一个整数列表作为参数,并给出一个矩阵或列表列表.制作矩阵的要点是整数表示矩阵True每列中的s 数.例如

[2,4,1]
Run Code Online (Sandbox Code Playgroud)

必须翻译成:

在此输入图像描述

系统中的哪个表示为列表列表:

[ [0,1,0], [0,1,0], [1,1,0], [1,1,1] ]
Run Code Online (Sandbox Code Playgroud)

由于按列操作矩阵(列表列表)并不容易,我使用了一个技巧并将矩阵向左旋转90度,transpose这使得矩阵如下所示:

在此输入图像描述

然后我开发了以下算法来解决问题:

  1. 获取输入列表的第一个元素
  2. 创建一个长度列表maximum xs(每个列表的长度等于列表中的最大元素)
  3. True在第一个元素确定的列表中放入这么多.
  4. 填写列表的其余部分 False
  5. 对所有元素执行相同操作并旋转矩阵

我试图实现两个解决方案,但每个解决方案都有一个我无法解决的问题:

  1. 这个适用于第一个元素就好了,但我不知道如何将它应用于输入列表的所有元素

    listToMatrix x = (replicate ((maximum x) - (head x)) False) ++ (replicate (head x) True)`
    
    Run Code Online (Sandbox Code Playgroud)
  2. 这适用于所有元素,但不能保持内部列表的长度,因此列表具有不同的长度.

    listToMatrix lst@(x:xs) = ((replicate ((maximum lst) - x) False) ++ (replicate x True)) : listToMatrix xs`
    
    Run Code Online (Sandbox Code Playgroud)

问题1:如何使这些功能在最小的变化下工作?

问题2:更优雅和紧凑的解决方案?

PS我在矩阵中使用了1和0来使它们更具可读性,但实际上它们是真的和假的

chi*_*chi 3

我会使用以下方法,该方法与您的方法兼容。

正如您所建议的,我们transpose在最后使用,因为转置矩阵看起来更容易生成。

f :: [Int] -> [[Bool]]
f xs = transpose (...)
Run Code Online (Sandbox Code Playgroud)

然后, 的每个元素都xs必须生成一个新行。我们可以使用列表理解(如下所示),或者使用map.

f :: [Int] -> [[Bool]]
f xs = transpose [ row x | x <- xs ]
  where row :: Int -> [Bool]
        row x = ...
Run Code Online (Sandbox Code Playgroud)

正如您所建议的,我们还需要maximum生成每一行,因此我们计算一次:

f :: [Int] -> [[Bool]]
f xs = transpose [ row x | x <- xs ]
  where m = maximum xs
        row :: Int -> [Bool]
        row x = ...   -- we know x and m, we need m-x Falses and x Trues
Run Code Online (Sandbox Code Playgroud)

现在,您只需要调整您的代码即可。