List comprehensions

From Rosetta Code
Revision as of 20:53, 31 July 2008 by rosettacode>Paddy3118 (→‎{{header|Python}}: changed from 21 to n and added generator function example)
Task
List comprehensions
You are encouraged to solve this task according to the task description, using any language you may know.

A list comprehension is a special syntax in some programming languages to describe lists. It is similar to the way mathematicians describe sets, with a set comprehension, hence the name.

Write a list comprehension that builds the list of all pythagorean triples with elements between 1 and n. If the language has multiple ways for expressing such a construct (for example, direct list comprehensions and generators), write one example for each.

Clojure

 (for [x (range 1 21) y (range x 21) z (range y 21) :when (= (+ (* x x) (* y y)) (* z z))] [x y z])

E

pragma.enable("accumulator") # considered experimental

accum [] for x in 1..n { for y in x..n { for z in y..n { if (x**2 + y**2 <=> z**2) { _.with([x,y,z]) } } } }

Erlang

 pythag(N) ->
     [ {A,B,C} ||
         A <- lists:seq(1,N),
         B <- lists:seq(1,N),
         C <- lists:seq(1,N),
         A+B+C =< N,
         A*A+B*B == C*C
     ].

Haskell

pyth n = [(x,y,z) | x <- [1..n], y <- [x..n], z <- [y..n], x^2 + y^2 == z^2]

Since lists are Monads, one can alternatively also use the do-notation (which is practical if the comprehension is large):

 import Control.Monad

 pyth n = do
   x <- [1..n]
   y <- [x..n]
   z <- [y..n]
   guard $ x^2 + y^2 == z^2
   return (x,y,z)

Mathematica

Select[Tuples[Range[n], 3], #1[[1]]^2 + #1[[2]]^2 == #1[[3]]^2 &]

Pop11

lvars n = 10, i, j, k;
[% for i from 1 to n do
       for j from 1 to n do
           for k from 1 to n do
               if i*i + j*j = k*k then
                    [^i ^j ^k];
               endif;
           endfor;
       endfor;
   endfor %] =>

Python

List comprehension:

[(x,y,z) for x in xrange(1,n+1) for y in xrange(x,n+1) for z in xrange(y,n+1) if x**2 + y**2 == z**2]

Generator comprehension:

((x,y,z) for x in xrange(1,n+1) for y in xrange(x,n+1) for z in xrange(y,n+1) if x**2 + y**2 == z**2)

Generator function:

def gentriples(n):
  for x in xrange(1,n+1):
    for y in xrange(x,n+1):
      for z in xrange(y,n+1):
        if x**2 + y**2 == z**2:
          yield (x,y,z)