我在做作业,我必须写一个有2个[String]的函数。列表字符串包含3个字符:
- 第一个是国际象棋子(例如K-王,Q-后,R-车,B-象,N-骑士,P-兵)
- 第二个指定列('a' - 'h')
- 3rd是行号(“1”-“8”)
第一个字符串列表用于黑色棋子,第二个字符串列表用于白色棋子。棋盘的自由区域用.“”表示。黑色棋子将是大写的,白色棋子将是小写的。
不需要在板上打印1-8和a-h。
这是必需的函数类型:
chess :: [String] -> [String] -> [String]
我们有这个打印功能
pp :: Result -> IO ()
pp x = putStr (concat (map (++"\n") x))
这是IO示例:
Prelude> pp( chess["Ke1","Ra1","Rh1","Pa2","Be5"] ["Ke8","Ra8","Rh8","Pa7","Qd8","Bc8","Nb8"])
8rnbqk..r
7p.......
6........
5....B...
4........
3........
2P.......
1R...K..R
abcdefgh
我尝试过什么:例如
chess :: [String] -> [String] -> [String]
chess _ [] = []
chess [] _ = []
chess ((x1:x2:x3:_):xs) ((y1:y2:y3:y3s):ys)
| 'a' == x2 && '1' == x3 = [x1] : chess xs ys
| 'a' == y2 && '1' == y3 = [y1] : chess xs ys
| 'b' == x2 && '1' == x3 = [x1] : chess xs ys
| 'c' == x2 && '1' == x3 = [x1] : chess xs ys
| 'd' == x2 && '1' == x3 = [x1] : chess xs ys
| 'e' == x2 && '1' == x3 = [x1] : chess xs ys
| 'e' == x2 && '1' == x3 = [x1] : chess xs ys
| 'g' == x2 && '1' == x3 = [x1] : chess xs ys
| otherwise = ['.'] : chess xs ys
输入为:国际象棋[“Ke 1”,“Ra 1”,“Rh 1”,“Pa 2”,“Be 1”] [“Kb 1”,“Ra 8”,“Rh 8”,“Pa 7”,“Qd 8”,“Bc 8”,“Na 1”]输出为:[“K”、“R”、“.”、“.”、“B”]
再来一次
chess :: [String] -> [String] -> [String]
chess _ [] = []
chess [] _ = []
chess ((x1:x2:x3:_):xs) ((y1:y2:y3:y3s):ys)
| (x2 == 'a' && x3 == ['1']) = [x1] : chess (xs) (ys)
| (x2 == 'a' && x3 == ['2']) = [x1] : chess (xs) (ys)
| (x2 == 'a' && x3 == ['3']) = [x1] : chess (xs) (ys)
| (x2 == 'a' && x3 == ['4']) = [x1] : chess (xs) (ys)
| (x2 == 'a' && x3 == ['5']) = [x1] : chess (xs) (ys)
| (x2 == 'a' && x3 == ['6']) = [x1] : chess (xs) (ys)
| (x2 == 'a' && x3 == ['7']) = [x1] : chess (xs) (ys)
| (x2 == 'a' && x3 == ['8']) = [x1] : chess (xs) (ys)
| otherwise = chess (xs) (ys)
输入:象棋[“Ke 1”,“Ra 1”,“Rh 1”,“Pa 2”,“Be 1”] [“Ke 8”,“Ra 8”,“Rh 8”,“Pa 7”,“Qd 8”,“Bc 8”,“Nb 8”]输出:K R R
我试着先检查一行,然后再检查每一列(a-h)-我认为这是正确的,因为我需要打印类似[“K...Q...",“P......."]的内容-每个元素都是一行。如果我检查例如黑色,如果没有黑色,仍然可以有白色,所以我需要在打印'.'之前检查第二个字符串是否有白色字符。请帮助,我很困惑。我试着编写了4个函数,但它们花了4个多小时。谢谢
2条答案
按热度按时间rdrgkggo1#
前言。
我会给予你一个概述,并允许我自己留下一些细节未经润色。请调整我的建议,以您的喜好。
我的回答将是这样的:
1.解释一下这个想法。
1.决定策略。
1.拔模类型。
1.填写定义。
在真实的生活中,我的过程是“辩证的”,所有这些思路通过反复试验同时发展。
创意。
我在想,给定两个场,每个场都有一些片断,我总是可以把这些场“放在彼此的上面”,这样每个片断在接收到的场中的位置就和它在给定场中的位置一样。(除非在同一个地方有两个片段,在这种情况下,行为是未定义的。)* 一旦我可以用这种方式添加两个字段,我可以添加任意数目的幺半群。用一个幺半群生成一个域应该不是很难。这种技巧被称为“折叠幺半群”,你会在Haskell中看到它的大量应用。
战略。
这就是我将如何解决这个问题:
getPiece
函数来读取一个片段。putPiece
函数来显示一个字段。overlay
函数,该函数覆盖任意两个字段。类型。
花点时间在一张纸上,画出这些类型和功能可能如何连接的图,可能是值得的。
定义
这里需要注意的是,如何将两个
zipWith
函数组合起来,以实现对列表列表的压缩效果。还要注意,我毫不犹豫地定义了一个helper函数replaceAt
,因为我认为它会使main函数变得非常简单。结论。
我发现用正确的抽象工具箱来处理一个简单的问题是最舒服的。在这个例子中,我们使用了一个幺半群 (由
overlay
定义) 和一个递归模式 (List.foldl'
是“catamorphism”的一个示例)。我相信你在编程实践中会遇到更多的例子,这些想法可以被用到。如果有什么东西不平易近人或解释得不好,请给我留下评论。
好好享受 haskell 吧!
“附言” 另请参阅algorithmically faster approach,以了解非常类似的问题。
shyt4zoc2#
请考虑以下列方式组织您的程式码: