Reputation: 91
About my question: as the title says so.
e.g. [234,2,2,4123,54] -> [234,2,4123,54]
Here's my code trying to make that function but failed:
--sorry for messy comments
delMinimum ar = map fst [x|x <- arr, x /= toDel2]
where
let arr = zip ar [1..] {- Firstly, let all the array elements are separately recognizable,
even when there's couple or more items having same value. -}
let toDel = [x|x <- arr, fst x = minimum ar] {- collect tuple elements, where first item of those
elements is having minimum of ar -}
let toDel2 = head (map snd toDel) {- sellect one of the tuples of toDel -}
--lastly, delete toDel2 in arr, and after that, get all first items of each tuples in arr.
Showing my code without the messy comments that I used to try to explain my code:
delMinimum ar = map fst [x|x <- arr, x /= toDel2]
where
let arr = zip ar [1..]
let toDel = [x | x <- arr, fst x = minimum ar]
let toDel2 = head (map snd toDel)
Upvotes: 1
Views: 146
Reputation: 478
We can use lazy knot-tying to get this done in a single pass.
deleteMin ls = nls where
-- Get the new list (which is a thunk at this point) and the index of the minimum value, passing in
-- the starting index, starting minimum index, and current minimum.
(nls, nmin) = foldr app end ls 0 (-1 :: Int) Nothing
-- Take the current index, current minimum index, and current minimum, calculate the
-- new best minimum, and pass that down, using the result to lazily generate a list with the
-- minimum element removed.
app _ _ i mc mMin
-- Force the arguments so thunks don't pile up here.
| i `seq` nc `seq` mMin `seq` False = undefined
app x r i mc mMin = let
-- Calculate the new minimum index and minimum.
(mc', mMin') = case mMin of
Just xm | x >= xm = (mc, mMin)
_ -> (i, Just x)
-- Get the lazy list and best minimum found to pass forward.
(cls', nk) = r (i + 1) mc' mMin'
-- Push the current value on if it's not at the index to remove.
nls' = if i == nmin then cls' else x:cls'
-- And pass it all forward.
in (nls', nk)
-- At the end, only pass forward the empty list and index of the minimum.
end _ mc _ = mc ``seq` ([], mc)
Upvotes: 1