Reputation: 23
Given an array of integers, how can I sort them by : largest-smallest-2nd largest - 2nd smallest?
I'm trying to : - Duplicate and sort an array in order ascending and descending - Create the sorted array by picking the head of each arrays describes as above
I am not familiar with Haskell programming but here's what I've done
sort :: [Int] -> [Int]
sort [] = []
sort (x:xs) = sort smaller ++ [x] ++ sort larger
where
smaller = filter (<= x) xs
larger = filter (> x) xs
wave :: [Int] -> [Int]
wave [] = []
wave [x] = [x]
wave (x:xs) = if length (x:xs)>1
then :
ascending = sort (x:xs)
descending = reverse (ascending)
iterator = length(x:xs)
if iterator > 0 && (length(ascending)==0 || length(descending)==0)
then do wave(x:xs) = head(descending) + head(ascending)
tail(descending)
tail(ascending)
Thanks by advance for your help
Upvotes: 1
Views: 1122
Reputation: 71065
Another way to use the zipping:
import Data.Ord
frontEndSort :: [Int] -> [Int]
frontEndSort xs =
zipWith (flip const) xs
( concat . getZipList . traverse ZipList
$ [sortBy (comparing Down) xs, sort xs] )
Here traverse ZipList :: [[b]] -> ZipList [b]
so it already produces the pairs as lists, not tuples.
Upvotes: 1
Reputation: 5063
braid
function intercalates two list elem by elem. We next apply braid
to the list ordered in ascending and descending. Finally, since we end up with the orginal list duplicated, we take just the length of the original list.
braid :: [Int] -> [Int] -> [Int]
braid [] as = as
braid ds [] = ds
braid (d:ds) (a:as) = d:a:braid ds as
wave :: [Int] -> [Int]
wave xs = take (length xs) braided
where asc = sort xs
desc = reverse asc
braided = braid desc asc
despite of the fact that I think my implementation is easier to understand for haskell beginers, I got to say that after having benckmarked my solution against ƛƛƛ's solution, mine is ~ 4 to 7 times slower than his/her.
For One hundred thousand length list:
For One million length list:
reverse
Replacing desc = reverse asc
by desc = sortOn Down xs
produces same speed program as ƛƛƛ's applicative solution and willness comprehension list implementation.
Upvotes: 1
Reputation: 892
frontEndSort
consumes a list xs
, it sorts its elements in descending order. Next, pair each element in xs
with element from the same list but in ascending order. Convert each pair to a list then flatten the whole list. Finally, we take as many elements as in xs
.
frontEndSort :: [Int] -> [Int]
frontEndSort xs = take (length xs) $ do
(x, y) <- zip <$> sortBy (comparing Down) <*> sort $ xs
[x, y]
Upvotes: 4