Haskell - Creating Functional Programming (Exercise 4.3)

I have the following question (Haskell - The Craft of Functional Programming):

Define function

howManyEqua1 :: Int -> Int -> Int -> Int 

which returns how many of its three arguments are equal, so

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

The answer I gave:

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

However, I believe that there is a better way to classify it, but I'm not sure how to do it.

+4
source share
6 answers

What about:

 howManyEqual abc | a == b && b == c = 3 | a /= b && a /= c && b /= c = 0 | otherwise = 2 
+7
source

Or:

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

Update:

Using the ryaner answer as a starting point and the definition of luqui generalization, we can also use this single insert and have a common solution with O (n log n) complexity:

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

I think:

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

I'm not sure if this is better / worse than Sean's.

I may have fewer tests on average due to || laziness.

+2
source

A bit ridiculous solution:

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

[change]

In short:

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

One liner that I can think of avoids protection:

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

This is clearly less efficient, although it seems like overuse of the function.

It probably makes sense to use such an algorithm if your input is a huge list in which you want to calculate how many elements are equal. This is O (n log n).

+1
source

All Articles