Reputation: 859
The question is like this:
Write a function that takes an integer list and returns its length and the second largest integer in the list.
I can solve this with two functions but is there any solution that use only one function to do it?
Any help is appreciated! Thanks!
Upvotes: 2
Views: 3945
Reputation: 1102
head . (!!1) . group . sortBy (flip compare) $ [1,1,2,3,4,4,4,5,5,6,6,6,6]
5
Upvotes: 1
Reputation: 152707
Don't make it complicated.
f xs = (sort xs !! 1, length xs)
If you choose to make it complicated, make it complicated in the right way.
Upvotes: 4
Reputation: 54058
Edited to use @ThomasM.DuBuisson's suggestion
You can solve this the same way that you could finding the max: using a fold. Max can be pretty trivially implemented with
mymaximum :: Ord a => [a] -> a
mymaximum xs = foldl searcher (head xs) xs
where
searcher :: Ord a => a -> a -> a
searcher a b
| a > b = a
| otherwise = b
So we can implement it similarly by just keeping up with the two largest values (notice that we have to "seed" the fold with a tuple as well):
nextmaximum :: Ord a => [a] -> a
nextmaximum xs = fst $ foldl searcher (h, h) xs
where
h = head xs
searcher :: (Ord a) => (a, a) -> a -> (a, a)
searcher (s, f) x = (min f (max s x), max f x)
Upvotes: 3
Reputation: 3273
You can just compose individual functions together. This is neither efficient nor robust, but it's sure easy to write:
f xs = maximum . filter (< maximum xs) $ xs
Upvotes: 2