What is the best practice for code]

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.

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

On Mon, Nov 9, 2009 at 10:46 PM, legajid
{- 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ï

On Tue, Nov 10, 2009 at 8:46 AM, legajid
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]
participants (4)
-
Austin Wood
-
Brent Yorgey
-
Chaddaï Fouché
-
legajid