What is the best practice for code]

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

What is the best practice for code]

legajid
Hello,

i wanted to write a program that searches for all combinations of some
numbers, the sum of which is a given value.
So, i started writing my program, creating a function for each separate
phase : creating list of triples, selecting valuable ones, filtering the
result.

Looking at my code, i've reduced it several ways; the last version holds
on one single line of code.

Please, from the 3 versions i established, which one is " better"? What
are the criterias of a "good" code ?
What about using many anonymous functions?
I think there are other solutions than those i propose.

Following is my code

{-    First solution     -}
nombres=[9,8..1]
-- all combinations
ftoutes xx = [(x, y, z) | x <- xx, y <- xx, z <- xx]
-- keep valuable ones
futiles xyz = [(x, y, z) | (x,y,z) <- xyz, y < x, z < y ]
-- filter
f_flt (x,y, z) = (x+y+z) == 19
-- final result
f = filter (f_flt) (futiles (ftoutes nombres ))

{-    Second solution   -}
futiles2 xx = [(x, y, z) | x <- xx, y <- xx, z <- xx, y < x, z < y]
f2 = filter (\(x,y,z) -> (x+y+z)==19) (futiles2 nombres )

{-    Third solution  -}
f3 = filter (\(x,y,z) -> (x+y+z)==19) ((\ xx -> [(x, y, z) | x <- xx, y
<- xx, z <- xx, y < x, z < y]) nombres )

Thanks for your advice

Didier.



Reply | Threaded
Open this post in threaded view
|

What is the best practice for code]

Brent Yorgey-2
On Mon, Nov 09, 2009 at 10:46:19PM +0100, legajid wrote:
>
> {-    Second solution   -}
> futiles2 xx = [(x, y, z) | x <- xx, y <- xx, z <- xx, y < x, z < y]
> f2 = filter (\(x,y,z) -> (x+y+z)==19) (futiles2 nombres )
>
> {-    Third solution  -}
> f3 = filter (\(x,y,z) -> (x+y+z)==19) ((\ xx -> [(x, y, z) | x <- xx, y <-
> xx, z <- xx, y < x, z < y]) nombres )

I think the second solution is best (the third solution seems hard to
read).  Shorter code is usually better, but avoid long lines that are
hard to scan.

Here's another possibility:

  f4 = filter (\(x,y,z) -> x+y+z == 19)
              [(x,y,z) | x <- [9,8..1], y <- reverse [1..x-1], z <- reverse [1..y-1]]

This way you only generate (x,y,z) where x > y > z, and avoid all the
wasted work of generating triples and then throwing them away.

-Brent
Reply | Threaded
Open this post in threaded view
|

What is the best practice for code]

Chaddaï Fouché
In reply to this post by legajid
On Mon, Nov 9, 2009 at 10:46 PM, legajid <[hidden email]> wrote:
> {- ? ?Third solution ?-}
> f3 = filter (\(x,y,z) -> (x+y+z)==19) ((\ xx -> [(x, y, z) | x <- xx, y <-
> xx, z <- xx, y < x, z < y]) nombres )

If you want to use list comprehension just use it for all filtering necessary :
(Si tu veux utiliser les list comprehension utilises les donc pour
tout filtrage n?cessaire :)

> f3 = [(x, y, z) | x <- nombres, y <- nombres, z <- nombres, y < x, z < y, x+y+z == 19]

Alternatively, you may try to express the same thing without the list
comprehension :
(Tu peux aussi essayer d'exprimer la m?me chose avec des fonctions seulement :)

> f4 = filter (\[x,y,z] -> z < y && y < x && x+y+z == 19) . replicateM 3 $ nombres

It is almost always better (performance-wise) to only generate the
correct solutions rather than generate all then filter (though if you
can improve the modularity and/or clarity of your code by separating
the two steps it's worth considering), so in your case :
(Il est presque toujours pr?f?rable (du point de vue des performances)
de g?n?rer uniquement les solutions correctes plut?t que de g?n?rer
toutes les possibilit?s puis de les filtrer (encore que si ?a te
permet d'am?liorer la modularit? ou la clart? de ton code ?a vaut le
coup de se poser la question), donc dans ton cas ?a donnerait :)

> f5 = reverse [(x, y, z) | x <- [3..9], y <- [2 .. x-1], let z = 19 - x - y, y > z, z > 0]

--
Jeda?
Reply | Threaded
Open this post in threaded view
|

What is the best practice for code]

Austin Wood
In reply to this post by legajid
On Tue, Nov 10, 2009 at 8:46 AM, legajid <[hidden email]> wrote:

> i wanted to write a program that searches for all combinations of some
> numbers, the sum of which is a given value.
> So, i started writing my program, creating a function for each separate
> phase : creating list of triples, selecting valuable ones, filtering the
> result.
>
> Looking at my code, i've reduced it several ways; the last version holds on
> one single line of code.
>
> Please, from the 3 versions i established, which one is " better"? What are
> the criterias of a "good" code ?
> What about using many anonymous functions?
> I think there are other solutions than those i propose.

It could be done using do;

import Control.Monad

numbers = [9,8..1]
f = do x <- numbers
       y <- numbers
       z <- numbers
       guard (y < x && z < y)
       guard (x+y+z == 19)
       return [x,y,z]