我想在Haskell的游戏中返回一系列卡牌。例如:
[(SIX,D),(SEVEN,D),(EIGHT,S)] ~> [(SIX,D),(SEVEN,D)]
[(SIX,D),(SEVEN,S)] ~> []
[(SIX,D),(SEVEN,D)] ~> [(SIX,D),(SEVEN,D)]
到现在为止,我有这个功能:
findSeq :: [Card] -> [Card]
findSeq [] = []
findSeq (h:t)
| null t = [h]
| Just h == (pCard (head t) pack) = h:findSeq t
| otherwise = [h]
即使是第一张牌也会返回:即,不适合上面的例子2。如果那里没有连续元素序列,我怎么能返回一个序列呢?
我也尝试过滤它们,但我收到了“太多参数异常”。有什么帮助吗?
答案 0 :(得分:1)
嗯,从数学角度来看,将一张卡片视为一张卡片序列实际上是完全合理的。所以不要改变这种行为是个好主意......只需扩展定义,这样就可以从中获得真正理想的结果。
真正的问题不在于您将单张卡片视为单元素序列,而是您不会在其后面获得任何内容。要解决这个问题,您需要首先获取列表中的第一个,但所有序列:
findSeqs :: [Card] -> [[Card]]
findSeqs [] = []
findSeqs [h] = [[h]]
findSeqs (h:t@(h':_)) -- avoid `head` and `null`... pattern matching FTW!
| Just h == (pCard h' pack) = h ^: findSeqs t
| otherwise = [h] : findSeqs t
我使用过帮手
(^:) :: a -> [[a]] -> [[a]]
h ^: (hl:ls) = (h:hl) : ls
_ ^: [] = []
一旦你有findSeqs
,你只需要略过第一个非简并序列的结果。
答案 1 :(得分:1)
我就是这样做的:
import Data.List (groupBy)
import Data.Function (on)
data Suit = Clubs | Diamonds | Hearts | Spades deriving Eq
data Face = Ace | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten
| Jack | Queen | King deriving Enum
type Card = (Face, Suit)
findSequences :: [Card] -> [[Card]]
findSequences = [sequence | sequence <- groupBy ((==) `on` snd),
contiguous (map fst sequence),
length sequence > 1]
contiguous :: Enum a => [a] -> Bool
contiguous (x:xs) = map fromEnum xs == take (length xs) [fromEnum x + 1 ..]
findSequences
函数查找套牌中的所有序列(单卡序列除外)。