2011-05-13 42 views
4

我有以下問題(哈斯克爾 - 函數式編程的工藝):哈斯克爾 - 函數式編程(行使4.3)的工藝

給功能

howManyEqua1 :: Int -> Int -> Int -> Int 
的定義

它返回三個參數中有多少是相等的,這樣

howManyEqua1 :: 34 25 36 = 0 
howManyEqual :: 34 25 34 = 2 
howManyEqual :: 34 34 34 = 3 

我給出的答案是:

howManyEqual :: Int -> Int -> Int -> Int 
howManyEqual a  b  c 
    | a == b && b == c   = 3 
    | a == b      = 2 
    | b == c      = 2 
    | a == c      = 2 
    | otherwise     = 0 

不過,我相信這是一個更好的方式來分類,但我不知道如何。

+0

爲什麼我沒有任何答案了嗎? – maclunian

+4

堆棧溢出不是獨角獸。人們回答他們是否喜歡它。 :) –

+2

...但是當獨角獸確實顯示他們來與氣球。太奇妙了。 –

回答

7

如何:

howManyEqual a b c 
    | a == b && b == c   = 3 
    | a /= b && a /= c && b /= c = 0 
    | otherwise     = 2 
+1

但如果只有一個詞是平等的呢? –

+1

等於什麼? – Sean

+0

開個玩笑。在我心中聽起來很有趣 –

2

我在想:

howManyEqual a b c 
    | a == b && b == c   = 3 
    | a == b || b == c || a == c = 2 
    | otherwise     = 0 

我不知道,如果它比Sean的好/差。

由於||懶惰,我的平均測試次數可能會更少。

5

或者:

howManyEqual a b c = case length.nub $ [a,b,c] of 
    1 -> 3 
    2 -> 2 
    3 -> 0 

更新:

使用ryaner的回答爲出發點和luqui的概括定義,我們還可以用這一個襯墊和具有帶O的通用解決方案(N日誌N)複雜度:

howManyEqualG = sum.filter (>1).map length.group.sort 
-- Now, specialized to three: 
howManyEqual a b c = howManyEqualG [a,b,c] 
+0

唉,你打我。我即將發佈完全相同的東西!這是非正統的,但是一個有趣的選擇。 –

+0

似乎有點偏離我需要知道的道路,謝謝你的回答! – maclunian

+0

不知道爲什麼這得到-1。它是唯一一個跟蹤* n *參數的通用解決方案的軌道。 +1 – luqui

1

一個一個班輪我能想到的,避免了警衛:

import Data.List 

howManyEqual :: Int -> Int -> Int -> Int 
howManyEqual a b c  = maximum $ 0 : (filter (> 1) . map length . group . sort) [a,b,c] 

這顯然是低效率的,但並看起來功能組合物矯枉過正。

如果你的輸入是一個巨大的列表,你想要計算最多的元素是多少,那麼使用這樣的算法可能是唯一有意義的。這是O(n log n)。

2

稍微有趣的解決方案:

howManyEqual a b c = [0,2,42,3] !! (length $ filter id [a == b, b == c, a == c]) 

[編輯]

較短

import Data.List 
howManyEqual a b c = [42,3,2,0] !! (length $ nub [a,b,c]) 
+0

有趣和有創意。我喜歡 :) – JKnight