【问题标题】:Having trouble rotating a 3-dimensional list of chars in Haskell在 Haskell 中旋转 3 维字符列表时遇到问题
【发布时间】:2018-05-07 13:46:14
【问题描述】:

我对 Haskell 和函数式编程比较陌生,但现在我正在做一个项目,我试图解决 3D 立方体难题。

我有以下 3 维列表,其中 ' ' 代表空白空间,'C' 代表结构的一部分:

myShape = [["CC", " C"], [" C", "  "]]

我希望能够沿所有三个轴旋转这个结构,以便在不同的位置进行尝试。我知道我可以通过独立旋转每个 2D 层来沿一个轴旋转它。

我的问题是:如何在不对旋转进行硬编码的情况下沿其他轴旋转?

【问题讨论】:

  • 让我们暂时忘记 Haskell。您将如何自己旋转矩阵(例如在伪代码中)?
  • 可能通过反转和转置矩阵的某种组合。但我不知道这些顺序中的哪些顺序给出了正确的结果。
  • 提示:首先做一些旋转 2D 矩阵的实验:例如 3x3,然后将其推广到 nxn。
  • transpose 可能会派上用场。
  • 不,它们不必以正方形为界。例如[["CCC", " C "]]。当然,如有必要,我总是可以把它们填满

标签: list haskell matrix functional-programming


【解决方案1】:

好吧,我自己解决了:

rotate2dArr :: [[Char]] -> Int -> [[Char]]                                                                                                                                                              
rotate2dArr arr 0 = arr
rotate2dArr arr r = rotate2dArr (transpose $ [reverse row | row <- arr]) (r-1)

rotateX :: [[[Char]]] -> Int -> [[[Char]]]
rotateX arr 0 = arr
rotateX arr r = rotateX (transpose $ [reverse plane| plane <- arr]) (r-1) 

rotateY :: [[[Char]]] -> Int -> [[[Char]]]
rotateY arr 0 = arr
rotateY arr r = rotateY (rotateX (rotateZ (rotateX arr 1) 1) 3) (r - 1)

rotateZ :: [[[Char]]] -> Int -> [[[Char]]]
rotateZ arr r = [rotate2dArr plane r | plane <- arr]

rotate3dArr :: [[[Char]]] -> Char -> Int -> [[[Char]]]
rotate3dArr arr axis r = case axis of 
        'x' -> rotateX arr r -- Rotates cube on x axis backwards 
        'y' -> rotateY arr r -- Rotates cube clockwise as seen from above
        'z' -> rotateZ arr r

它可能不是那么漂亮,但它确实有效

【讨论】:

  • 你的列表理解真的只是map。绕轴旋转偶数次可能会被优化以跳过transpose。额外挑战:优化围绕任意轴的旋转序列,假设同一方向上的所有列表具有相同的长度 (m * n * o)。
猜你喜欢
  • 2020-06-25
  • 2022-12-10
  • 2021-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-11
  • 1970-01-01
相关资源
最近更新 更多