我正在为一个类做一个游戏,在一个任务中,我需要做一个正方形(这是‘地图’),我所知道的只是维度(两边的大小),然后我想用‘值’来计算我需要替换的单元格。
例如,维数为9的正方形如下所示:
# # # # # # # # #
# _ _ v v v _ _ #
# _ # V # v # _ #
# v v v v v v v #
# v # v # v # v #
# v v v v v v v #
# _ # v # v # _ #
# _ _ v v v _ _ #
# # # # # # # # ## (墙壁)#和两个空空格_开头。#。#,在每两个空格中有一行#。因此,我需要构建一个计算vs的函数。我在地图上只接收到Dimension :: Int (在本例中是9,函数calcV (函数的名称示例)将返回28)。
下面是我尝试过的代码。这个方格总是有奇数维,等于或高于5,所以我做了5的情况,然后一个函数,我期望它会计算出我想要的所有其他可能的值。
但它给了我:
异常: ghci中的堆栈溢出
有人知道我在这段代码中做错了什么吗?
calcv :: Int -> Int -> Int -> Int
calcv 5 _ _ = 0
calcv d l c -- the l and c will be given has 1(first line/first column) (d will be the dimension)
| (l==1) = 0 + calcv d (l+1) 1
| (l==(d-1)) || (l==2) && (c==1) || (c==2) || (c==3) || (c==(d-2)) || (c==(d-1)) = 0 + calcv d l (c+1)
| (l==(d-1)) || (l==2) && (c>3) && (c<(d-2)) = if even c then 1 + calcv d l (c+1) else calcv d l (c+1)
| (l==(d-1)) || (l==2) && (c==d) = calcv d (l+1) 1
| (l==3) || (l==(d-2)) && (c==1) || (c==2) || (c==3) || (c==(d-2)) || (c==(d-1)) = calcv d l (c+1)
| (l==3) || (l==(d-2)) && (c>3) && (c<(d-2)) = if even c then 1 + calcv d l (c+1) else calcv d l (c+1)
| (l==3) || (l==(d-2)) && (c==d) = calcv d (l+1) 1
| (l==d) = 0发布于 2016-10-20 21:18:08
当遇到这样的问题时,试着把它分解成更小的部分,并在编写递归函数之前看看如何用Haskell的现有工具(比如列表理解、map、filter和foldr)来表示它。
首先,要生成长度为n的列表的平方列表,其中每个单元格都是行和列索引的一些函数:
makeMap :: Int -> [[Char]]
makeMap n
| even n || n < 5
= error "makeMap: invalid size"
| otherwise = [[cellAt row col | col <- [1 .. n]] | row <- [1 .. n]]如果您不关心分隔行,或者希望将单个索引放入整个映射中,也可以使用Int -> [Char]类型来定义这一点。您也可以用map而不是列表理解来定义它。我会把这些当作练习。
现在可以通过提供cellAt的实现在特定位置定义单元格。
where
cellAt :: Int -> Int -> Char我不会列举所有的案例,因为这是一个家庭作业问题,但是这里有几个要让您开始:
-- Produce a border whenever row=1, col=1, row=n, or col=n.
cellAt 1 _ = '#'
cellAt _ 1 = '#'
cellAt row col
| row == n || col == n
= '#'
-- Handle other cases here.
| ...然后,看起来您想要计算v单元格的数量,可以通过遍历映射来实现:
countV :: [[Char]] -> Int
countV rows = sum [sum [1 | 'v' <- row] | row <- rows]
calcV :: Int -> Int
calcV n = countV (makeMap n)如果您的老师想要一个单一的功能,一个很好的练习就是手动将countV和makeMap的定义内联到calcV中。但是,通常编写小的、简单的函数更容易,可以组合这些函数来解决更大的问题。
https://stackoverflow.com/questions/40160181
复制相似问题