Haskell将点列表转换为字符串

use*_*401 4 haskell functional-programming

我正在完成任务,我需要一些帮助.这是最后一部分,但我真的很挣扎,不知道如何接近.这是问题所在:

添加一个函数渲染,它接收一个图像并返回一个字符串,如果打印,将给出图像的图形表示,如下图所示(确保包括图像所有边的一个点边框).举个例子,渲染t应该返回

".|...\n.xxx.\n-+x--\n.|...\n"
Run Code Online (Sandbox Code Playgroud)

(图像中的点表示为'x',原点表示为'+',水平和垂直轴分别表示为' - '和'|'):

.|...
.xxx.
-+x--
.|...
Run Code Online (Sandbox Code Playgroud)

(我们通过render t函数生成的字符串可以通过执行putStr(render t)来打印以实现上述结果).

image和t就是这样的:

type Point = (Int,Int)
type Image = [Point]
t :: Image
t=[(0,1),(1,0),(1,1),(2,1)]
Run Code Online (Sandbox Code Playgroud)

首先,我需要另一个函数,因为它不能全部用于渲染.我知道要查看y和x的最大/最小值来获得边界,我有一个函数.我还有一个函数,它会在每n个字符后在字符串中插入换行符.

bhe*_*ilr 6

所以你有一个功能来获得你的尺寸:

dimensions :: Image -> (Point, Point)
Run Code Online (Sandbox Code Playgroud)

返回左上角和右下角.然后我会按排序顺序获得积分:

sortImage :: Image -> Image
Run Code Online (Sandbox Code Playgroud)

首先列出最大y和最小的排序x(提示:Data.List.sortBy是你的朋友).这实际上不是必需的,但它可以使以后更容易.然后你可以创建一个空白图像(即只有轴'.',或者你可以使用空格来获得更整洁的外观)

blankImage :: (Point, Point) -> [String]
Run Code Online (Sandbox Code Playgroud)

超出你的尺寸.请务必返回行列表,稍后可以使用新行加入,但现在可以更轻松地使用它们.现在,[String] = [[Char]]所以你有一个2D数组的字符.你有一个Point指示坐标的s 列表,但是你必须移动它们以便现在你的左上角坐标(0, 0).这样我们就可以在数组上使用常规索引来设置我们的点.幸运的是,我们已经计算了偏移值dimensions.

然后你需要一个函数来获取输出blankImage并使用你现在偏移量中的值替换字符Image.由于Points现在是你的索引blankImage,这应该很容易.

fillImage :: Image -> [String] -> [String]
Run Code Online (Sandbox Code Playgroud)

所以这个过程是:

import Data.List

showImage :: Image -> String
showImage img = intercalate "\n" filled
    where
        sortedImg = sorteImage img
        (upperL, lowerR) = dimensions sortedImg
        blank = blankImage (upperL, lowerR)
        offsetImg = offsetImage upperL sortedImg
        filled = fillImage offsetImg blank
    putStrLn $ intercalate "\n" filled
Run Code Online (Sandbox Code Playgroud)

该函数intercalate[String]使用新行连接,将其转换为一个大字符串.


我从你的评论中看到你是Haskell的新手,所以我会说,如果你需要更多的帮助,我会提供一些更多的提示,但你最好先尝试自己解决这个问题. .如果您遇到困难,请发表评论并编辑我的答案,以帮助您克服障碍.