在一个列表中验证是否有三个相同的元素和两个相同的元素。

huangapple go评论58阅读模式
英文:

Verifying if there are three elements that are the same and two elements that are the same in a list

问题

我被给定一个由升序排列的来自列表[1..6]的5个元素组成的列表,并且我需要开发两个函数:

  • 检查是否恰好有4个相等的元素(例如111124444515555),
  • 检查是否恰好有3个相等的元素和2个相等的元素(例如2224411122)。

我可以假设有诸如numberOfOccurrencesisPermutationisSortedmaximumminimum等函数。

以下是第二个问题的解决方案:

p :: [Int] -> Bool
p xs = 3 == maximum (map length (group xs))

但是,我应该使用函数isPermutationnumberOfOccurrences。关于这个问题有什么提示吗?

感谢Daniel Wagner找到我的错误。我认为这将是问题2的解决方案。

p :: [Int] -> Bool
p xs = 3 == maximum ns && length ns == 2
    where 
        ns = (map length (group xs))

然而,这不是所需的解决方案。

英文:

I am given a list of 5 elements drawn from the list [1..6] sorted in ascending order, and I have to develop two functions:

  • check if there are exactly 4 equal elements (e.g. 11112, 44445, 15555),
  • check if there are exactly 3 equal elements, and exactly 2 equal elements (e.g. 22244,11122)

I can assume functions like numberOfOccurrences, isPermutation, isSorted, maximum, and minimum.

numberOfOccurrences :: Eq a => a -> [a] -> Int
numberOfOccurrences _ [] = 0
numberOfOccurrences x (y:ys)
  | x == y    = 1 + numberOfOccurrences x ys
  | otherwise = numberOfOccurrences x ys

isPermutation :: Eq a => [a] -> [a] -> Bool
isPermutation [] [] = True
isPermutation xs [] = False
isPermutation xs (y:ys) | length xs /= length (y:ys) = False
                        | otherwise = isPermutation (delete y xs) ys

My solution for the second one is:

p :: [Int] -> Bool
p xs = 3 == maximum (map length (group xs))

However, I should use the function isPermutation, and numberOfOccurrences. Any hints about this problem ?

Thanks to Daniel Wagner for finding my error. This would be the solution to 2, I think.

p :: [Int] -> Bool
p xs = 3 == maximum ns && length ns == 2
    where 
        ns = (map length (group xs))

However, it is not the solution required.

答案1

得分: 2

个人而言,我会从这个非常简单的方法开始。

fourEqual [a, b, c, d, e] =
       (a == b && b == c && c == d && d /= e)
    || (a /= b && b == c && c == d && d == e)

它容易编写,容易阅读,并且不是特别低效的。

对于另一个也可以采用类似的策略。

英文:

Personally, I'd start with the super dumb thing.

fourEqual [a, b, c, d, e] =
       (a == b && b == c && c == d && d /= e)
    || (a /= b && b == c && c == d && d == e)

It's easy to write, it's easy to read, and it isn't particularly inefficient.

A similar strategy works for the other one.

答案2

得分: 1

以下是已翻译的代码部分:

虽然这并没有使用所命名的函数,但我会开发一个运行长度编码,因为我们知道元素已经排序,这很容易。

rle :: Eq a => [a] -> [(a, Int)]
rle [] = []
rle lst = reverse $ go lst []
  where
    go [] acc = acc
    go (x:xs) [] = go xs [(x, 1)]
    go (x:xs) ((y, c):ys) 
      | x == y = go xs ((y, c+1):ys)
      | otherwise = go xs ((x, 1):(y, c):ys)

现在我们只需要能够计算具有三或四作为其第二个元素的元组数量。

ghci> length $ filter (\(_, c) -> c == 4) $ rle [1,1,1,2,4,5]
0
ghci> length $ filter (\(_, c) -> c == 4) $ rle [1,1,1,1,2,4,5]
1
ghci> length $ filter (\(_, c) -> c == 4) $ rle [1,1,1,1,2,4,4,4,4,5]
2

请注意,这些是代码部分的翻译,不包括问题部分。

英文:

While this does not use the functions named, I'd develop a run-length encoding, which is easy given that we know the elements are sorted.

rle :: Eq a => [a] -> [(a, Int)]
rle [] = []
rle lst = reverse $ go lst []
  where
    go [] acc = acc
    go (x:xs) [] = go xs [(x, 1)]
    go (x:xs) ((y, c):ys) 
      | x == y = go xs ((y, c+1):ys)
      | otherwise = go xs ((x, 1):(y, c):ys)

Now we just need to be able to count the number of tuples that have three or four as their second element.

ghci> length $ filter (\(_, c) -> c == 4) $ rle [1,1,1,2,4,5]
0
ghci> length $ filter (\(_, c) -> c == 4) $ rle [1,1,1,1,2,4,5]
1
ghci> length $ filter (\(_, c) -> c == 4) $ rle [1,1,1,1,2,4,4,4,4,5]
2

huangapple
  • 本文由 发表于 2023年7月18日 03:14:07
  • 转载请务必保留本文链接:https://go.coder-hub.com/76707477.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定