Send Beginners mailing list submissions to
        beginners@haskell.org

To subscribe or unsubscribe via the World Wide Web, visit
        http://www.haskell.org/mailman/listinfo/beginners
or, via email, send a message with subject or body 'help' to
        beginners-requ...@haskell.org

You can reach the person managing the list at
        beginners-ow...@haskell.org

When replying, please edit your Subject line so it is more specific
than "Re: Contents of Beginners digest..."


Today's Topics:

   1.  Removing the biggest element from a list - maybe slow?
      (Nathan Huesken)
   2. Re:  Removing the biggest element from a list     - maybe slow?
      (Lafras Uys)
   3. Re:  Removing the biggest element from a list     - maybe slow?
      (Lafras Uys)
   4. Re:  Removing the biggest element from a list -   maybe slow?
      (matthew coolbeth)
   5. Re:  Removing the biggest element from a list -   maybe   slow?
      (Nathan Huesken)
   6. Re:  Removing the biggest element from a list -   maybe slow?
      (matthew coolbeth)
   7. Re:  Removing the biggest element from a list -   maybe slow?
      (Daniel Fischer)
   8. Re:  Removing the biggest element from a list -   maybe slow?
      (Daniel Fischer)


----------------------------------------------------------------------

Message: 1
Date: Mon, 24 May 2010 08:42:28 -0400
From: Nathan Huesken <hask...@lonely-star.org>
Subject: [Haskell-beginners] Removing the biggest element from a list
        - maybe slow?
To: Biginners Haskell Mailinglist <beginners@haskell.org>
Message-ID: <20100524084228.6ce58...@samzwo>
Content-Type: text/plain; charset=US-ASCII

Hi,

I want to remove the biggest element from a list:

withoutBiggest (x:xs) =
  withoutBiggestImpl (biggest x xs) [] (x:xs)
    where 
      biggest :: (Ord a) => a -> [a] -> a  
      biggest big [] = big
      biggest big (x:xs) =
        if x > big then
          biggest x xs
        else
          biggest big xs
      withoutBiggestImpl :: (Eq a) => a -> [a] -> [a] -> [a]
      withoutBiggestImpl big before (x:xs) =
        if big == x then
          before ++ xs
        else
          withoutBiggestImpl big (before ++ [x]) xs


Works, but I am a little concerned that this is
slower than needed, because the list has to be iterated twice.

Can this be done faster?

Regards,
Nathan


------------------------------

Message: 2
Date: Mon, 24 May 2010 15:27:03 +0200
From: Lafras Uys <laf...@aims.ac.za>
Subject: Re: [Haskell-beginners] Removing the biggest element from a
        list    - maybe slow?
To: Biginners Haskell Mailinglist <beginners@haskell.org>
Message-ID: <4bfa7ea7.5060...@aims.ac.za>
Content-Type: text/plain; charset=ISO-8859-1

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

> I want to remove the biggest element from a list:
> 
> withoutBiggest (x:xs) =
>   withoutBiggestImpl (biggest x xs) [] (x:xs)
>     where 
>       biggest :: (Ord a) => a -> [a] -> a  
>       biggest big [] = big
>       biggest big (x:xs) =
>         if x > big then
>           biggest x xs
>         else
>           biggest big xs
>       withoutBiggestImpl :: (Eq a) => a -> [a] -> [a] -> [a]
>       withoutBiggestImpl big before (x:xs) =
>         if big == x then
>           before ++ xs
>         else
>           withoutBiggestImpl big (before ++ [x]) xs
> 
> 
> Works, but I am a little concerned that this is
> slower than needed, because the list has to be iterated twice.
> 
> Can this be done faster?

import Data.List
init sort xs

or

import Data.List
delete (maximum xs) xs

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkv6fqcACgkQKUpCd+bV+ko55wCbB/AVbb9OhfGK5ObsAc4yxVFH
YigAnjudQlhBThF2IvUOjXFknAxBHUnN
=XuKY
-----END PGP SIGNATURE-----


------------------------------

Message: 3
Date: Mon, 24 May 2010 15:33:05 +0200
From: Lafras Uys <laf...@aims.ac.za>
Subject: Re: [Haskell-beginners] Removing the biggest element from a
        list    - maybe slow?
To: Biginners Haskell Mailinglist <beginners@haskell.org>
Message-ID: <4bfa8011.2050...@aims.ac.za>
Content-Type: text/plain; charset=ISO-8859-1

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

>> withoutBiggest (x:xs) =
>>   withoutBiggestImpl (biggest x xs) [] (x:xs)
>>     where 
>>       biggest :: (Ord a) => a -> [a] -> a  
>>       biggest big [] = big
>>       biggest big (x:xs) =
>>         if x > big then
>>           biggest x xs
>>         else
>>           biggest big xs
>>       withoutBiggestImpl :: (Eq a) => a -> [a] -> [a] -> [a]
>>       withoutBiggestImpl big before (x:xs) =
>>         if big == x then
>>           before ++ xs
>>         else
>>           withoutBiggestImpl big (before ++ [x]) xs
> 
> 
>> Works, but I am a little concerned that this is
>> slower than needed, because the list has to be iterated twice.
> 
>> Can this be done faster?
> 
> import Data.List
> init sort xs
> 
> or
> 
> import Data.List
> delete (maximum xs) xs

that should be,

import Data.List
init $ sort xs
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iEYEARECAAYFAkv6gBAACgkQKUpCd+bV+kq3aACfZFmIK3ChuVky9qWqLGYc2rrt
Np4An06oMtwCIu9pEYNumrX6N0Y5hFYn
=jKVY
-----END PGP SIGNATURE-----


------------------------------

Message: 4
Date: Mon, 24 May 2010 09:38:37 -0400
From: matthew coolbeth <mac01...@engr.uconn.edu>
Subject: Re: [Haskell-beginners] Removing the biggest element from a
        list -  maybe slow?
To: <laf...@aims.ac.za>
Cc: Biginners Haskell Mailinglist <beginners@haskell.org>
Message-ID:
        <aanlktikwa8pofzc0gnfkkfkdm32zqb7e3jvaljjyw...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

On Mon, May 24, 2010 at 09:27, Lafras Uys <laf...@aims.ac.za> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> > I want to remove the biggest element from a list:
> >
> > withoutBiggest (x:xs) =
> >   withoutBiggestImpl (biggest x xs) [] (x:xs)
> >     where
> >       biggest :: (Ord a) => a -> [a] -> a
> >       biggest big [] = big
> >       biggest big (x:xs) =
> >         if x > big then
> >           biggest x xs
> >         else
> >           biggest big xs
> >       withoutBiggestImpl :: (Eq a) => a -> [a] -> [a] -> [a]
> >       withoutBiggestImpl big before (x:xs) =
> >         if big == x then
> >           before ++ xs
> >         else
> >           withoutBiggestImpl big (before ++ [x]) xs
> >
> >
> > Works, but I am a little concerned that this is
> > slower than needed, because the list has to be iterated twice.
> >
> > Can this be done faster?
>
> import Data.List
> init sort xs
>
> This is not linear time.  It also doesn't maintain the order of the list.


> or
>
> import Data.List
> delete (maximum xs) xs
>

I don't think you are going to do better than this.  Just by the nature of
the problem, you need to go through the list twice:   either forward
initially and then backward during the "return phase" of your function, or
twice forward with a pair of tail-recursive operations.  The suggestion
above does the latter and, I believe, achieves optimal expenditures of both
time and space.


>
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.9 (GNU/Linux)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
>
> iEYEARECAAYFAkv6fqcACgkQKUpCd+bV+ko55wCbB/AVbb9OhfGK5ObsAc4yxVFH
> YigAnjudQlhBThF2IvUOjXFknAxBHUnN
> =XuKY
> -----END PGP SIGNATURE-----
> _______________________________________________
> Beginners mailing list
> Beginners@haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>



-- 
mac
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20100524/d9bd1dd4/attachment-0001.html

------------------------------

Message: 5
Date: Mon, 24 May 2010 09:42:21 -0400
From: Nathan Huesken <hask...@lonely-star.org>
Subject: Re: [Haskell-beginners] Removing the biggest element from a
        list -  maybe   slow?
To: beginners@haskell.org
Message-ID: <20100524094221.3214c...@samzwo.tch.harvard.edu>
Content-Type: text/plain; charset=US-ASCII

On Mon, 24 May 2010 15:27:03 +0200
Lafras Uys <laf...@aims.ac.za> wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
> 
> > I want to remove the biggest element from a list:
> > 
> > withoutBiggest (x:xs) =
> >   withoutBiggestImpl (biggest x xs) [] (x:xs)
> >     where 
> >       biggest :: (Ord a) => a -> [a] -> a  
> >       biggest big [] = big
> >       biggest big (x:xs) =
> >         if x > big then
> >           biggest x xs
> >         else
> >           biggest big xs
> >       withoutBiggestImpl :: (Eq a) => a -> [a] -> [a] -> [a]
> >       withoutBiggestImpl big before (x:xs) =
> >         if big == x then
> >           before ++ xs
> >         else
> >           withoutBiggestImpl big (before ++ [x]) xs
> > 
> > 
> > Works, but I am a little concerned that this is
> > slower than needed, because the list has to be iterated twice.
> > 
> > Can this be done faster?
> 
> import Data.List
> init sort xs
> 
> or
> 
> import Data.List
> delete (maximum xs) xs

I see. I would think, the first solution takes still to much time
because it needs to sort the list.

Is "delete" a fast operation (O(1))? or does it internally traverse
the list?

Thanks!
Nathan


------------------------------

Message: 6
Date: Mon, 24 May 2010 09:49:35 -0400
From: matthew coolbeth <mac01...@engr.uconn.edu>
Subject: Re: [Haskell-beginners] Removing the biggest element from a
        list -  maybe slow?
To: Nathan Huesken <hask...@lonely-star.org>
Cc: beginners@haskell.org
Message-ID:
        <aanlktil9gcxzmsdzsdnsvns0zqpor2rls8ozx5jl3...@mail.gmail.com>
Content-Type: text/plain; charset="utf-8"

It is linear time, implemented roughly as below

delete z [] = []
delete z (x:xs) =  if x=z then delete z xs else x:(delete z xs)


On Mon, May 24, 2010 at 09:42, Nathan Huesken <hask...@lonely-star.org>wrote:

> On Mon, 24 May 2010 15:27:03 +0200
> Lafras Uys <laf...@aims.ac.za> wrote:
>
> > -----BEGIN PGP SIGNED MESSAGE-----
> > Hash: SHA1
> >
> > > I want to remove the biggest element from a list:
> > >
> > > withoutBiggest (x:xs) =
> > >   withoutBiggestImpl (biggest x xs) [] (x:xs)
> > >     where
> > >       biggest :: (Ord a) => a -> [a] -> a
> > >       biggest big [] = big
> > >       biggest big (x:xs) =
> > >         if x > big then
> > >           biggest x xs
> > >         else
> > >           biggest big xs
> > >       withoutBiggestImpl :: (Eq a) => a -> [a] -> [a] -> [a]
> > >       withoutBiggestImpl big before (x:xs) =
> > >         if big == x then
> > >           before ++ xs
> > >         else
> > >           withoutBiggestImpl big (before ++ [x]) xs
> > >
> > >
> > > Works, but I am a little concerned that this is
> > > slower than needed, because the list has to be iterated twice.
> > >
> > > Can this be done faster?
> >
> > import Data.List
> > init sort xs
> >
> > or
> >
> > import Data.List
> > delete (maximum xs) xs
>
> I see. I would think, the first solution takes still to much time
> because it needs to sort the list.
>
> Is "delete" a fast operation (O(1))? or does it internally traverse
> the list?
>
> Thanks!
> Nathan
> _______________________________________________
> Beginners mailing list
> Beginners@haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>



-- 
mac
-------------- next part --------------
An HTML attachment was scrubbed...
URL: 
http://www.haskell.org/pipermail/beginners/attachments/20100524/5d6000ee/attachment-0001.html

------------------------------

Message: 7
Date: Mon, 24 May 2010 16:01:09 +0200
From: Daniel Fischer <daniel.is.fisc...@web.de>
Subject: Re: [Haskell-beginners] Removing the biggest element from a
        list -  maybe slow?
To: beginners@haskell.org
Message-ID: <201005241601.10015.daniel.is.fisc...@web.de>
Content-Type: text/plain;  charset="iso-8859-1"

On Monday 24 May 2010 14:42:28, Nathan Huesken wrote:
> Hi,
>
> I want to remove the biggest element from a list:
>
> withoutBiggest (x:xs) =
>   withoutBiggestImpl (biggest x xs) [] (x:xs)
>     where
>       biggest :: (Ord a) => a -> [a] -> a
>       biggest big [] = big
>       biggest big (x:xs) =
>         if x > big then
>           biggest x xs
>         else
>           biggest big xs
>       withoutBiggestImpl :: (Eq a) => a -> [a] -> [a] -> [a]
>       withoutBiggestImpl big before (x:xs) =
>         if big == x then
>           before ++ xs
>         else
>           withoutBiggestImpl big (before ++ [x]) xs
>

Just to make sure, you are aware that this removes only the first 
occurrence of the largest element if there are several?


In that code, collecting the before-list is
a) unnecessary
b) inefficient
Re b), consider the list [1 .. n] for some large n.
Then you have

wBI n [] [1 .. n]
~> wBI n ([]++[1]) [2 .. n]
~> wBI n (([] ++ [1]) ++ [2]) [3 .. n]
~> wBI n ((([] ++ [1]) ++ [2]) ++ [3]) [4 .. n]
~> ...
~> wBI n ((...((([] ++ [1]) ++ [2]) ++ [3]) ...) ++ [n-1]) [n]
~> ((...((([] ++ [1]) ++ [2]) ++ [3]) ...) ++ [n-1])

And:
Prelude> let func :: Int -> Int; func n = last (foldl (\xs k -> xs ++ [k]) 
[] [1 .. n])
(0.00 secs, 524224 bytes)
Prelude> func 5000
5000
(0.44 secs, 351528996 bytes)
Prelude> func 10000
10000
(2.63 secs, 1404077120 bytes)
Prelude> func 20000
20000
(20.03 secs, 5613242020 bytes)

Ouch.

The short code to achieve the same is (as has been posted before)

import Data.List

withoutBiggest [] = []
withoutBiggets xs = delete (maximum xs) xs

That also traverses the list twice, but is much faster because it doesn't 
build a left-nested chain of (++)-applications.
Like your code, it requires the entire list to be in memory though.

If you need the elements in the original order (except the first occurrence 
of the maximum), you can't completely eliminate that memory requirement, 
though you can reduce it somewhat on average (ugly code, not more efficient 
than delete (maxumum xs) xs in general, worst case considerably slower).

If you don't need to retain the order, you can efficiently do it with one 
traversal.

withoutLargest [] = []
withoutLargest (x:xs) = go x xs
  where
    go _ [] = []
    go p (y:ys)
      | p < y     = p : go y ys
      | otherwise = y : go p ys

>
> Works, but I am a little concerned that this is
> slower than needed, because the list has to be iterated twice.
>
> Can this be done faster?
>
> Regards,
> Nathan


------------------------------

Message: 8
Date: Mon, 24 May 2010 16:04:37 +0200
From: Daniel Fischer <daniel.is.fisc...@web.de>
Subject: Re: [Haskell-beginners] Removing the biggest element from a
        list -  maybe slow?
To: beginners@haskell.org
Message-ID: <201005241604.37369.daniel.is.fisc...@web.de>
Content-Type: text/plain;  charset="utf-8"

On Monday 24 May 2010 15:49:35, matthew coolbeth wrote:
> It is linear time, implemented roughly as below
>
> delete z [] = []
> delete z (x:xs) =  if x=z then delete z xs else x:(delete z xs)
>

delete only deletes the first occurrence, so it's equivalent to

delete z (x:xs)
  | x == z    = xs
  | otherwise = x : delete z xs
delete _ [] = []

, it's O(index of z) thus.


------------------------------

_______________________________________________
Beginners mailing list
Beginners@haskell.org
http://www.haskell.org/mailman/listinfo/beginners


End of Beginners Digest, Vol 23, Issue 36
*****************************************

Reply via email to