List comprehensions

From Rosetta Code
Jump to: navigation, search
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.

Some attributes of a list comprehension are that:

  1. They should be distinct from (nested) for loops within the syntax of the language.
  2. They should return either a list or an iterator (something that returns successive members of a collection, in order).
  3. The syntax has parts corresponding to that of set-builder notation.

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.

Contents

[edit] Ada

Works with: Ada 2005 version Standard - no additional library

There is no equivalent construct in Ada. In Ada05, the predefined library Ada.Containers implements 3 types of Doubly_Linked_Lists : Basic; Indefinite; Restricted.

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Containers.Doubly_Linked_Lists;
 
procedure Pythagore_Set is
 
type Triangles is array (1 .. 3) of Positive;
 
package Triangle_Lists is new Ada.Containers.Doubly_Linked_Lists (
Triangles);
use Triangle_Lists;
 
function Find_List (Upper_Bound : Positive) return List is
L : List := Empty_List;
begin
for A in 1 .. Upper_Bound loop
for B in A + 1 .. Upper_Bound loop
for C in B + 1 .. Upper_Bound loop
if ((A * A + B * B) = C * C) then
Append (L, (A, B, C));
end if;
end loop;
end loop;
end loop;
return L;
end Find_List;
 
Triangle_List : List;
C  : Cursor;
T  : Triangles;
 
begin
Triangle_List := Find_List (Upper_Bound => 20);
 
C := First (Triangle_List);
while Has_Element (C) loop
T := Element (C);
Put
("(" &
Integer'Image (T (1)) &
Integer'Image (T (2)) &
Integer'Image (T (3)) &
") ");
Next (C);
end loop;
end Pythagore_Set;
 

program output:

( 3 4 5) ( 5 12 13) ( 6 8 10) ( 8 15 17) ( 9 12 15) ( 12 16 20)

[edit] ALGOL 68

ALGOL 68 does not have list comprehension, however it is sometimes reasonably generous about where a flex array is declared. And with the addition of an append operator "+:=" for lists they can be similarly manipulated.

Translation of: Python
Works with: ALGOL 68 version Standard - no extensions to language used
Works with: ALGOL 68G version Any - tested with release mk15-0.8b.fc9.i386
Works with: ELLA ALGOL 68 version Any (with appropriate job cards) - tested with release 1.8.8d.fc9.i386
MODE XYZ = STRUCT(INT x,y,z);
 
OP +:= = (REF FLEX[]XYZ lhs, XYZ rhs)FLEX[]XYZ: (
[UPB lhs+1]XYZ out;
out[:UPB lhs] := lhs;
out[UPB out] := rhs;
lhs := out
);
 
INT n = 20;
print (([]XYZ(
FLEX[0]XYZ xyz;
FOR x TO n DO FOR y FROM x+1 TO n DO FOR z FROM y+1 TO n DO IF x*x + y*y = z*z THEN xyz +:= XYZ(x,y,z) FI OD OD OD;
xyz), new line
))

Output:

         +3         +4         +5         +5        +12        +13         +6         +8        +10         +8        +15        +17         +9        +12        +15        +12        +16        +20

[edit] AutoHotkey

Works with: AutoHotkey_L
List Comprehension is not built in.
 
comprehend("show", range(1, 20), "triples")
return
 
comprehend(doToVariable, inSet, satisfying)
{
set := %satisfying%(inSet.begin, inSet.end)
index := 1
While % set[index, 1]
{
item := set[index, 1] . ", " . set[index, 2] . ", " . set[index, 3]
%doToVariable%(item)
index += 1
}
return
}
 
 
show(var)
{
msgbox % var
}
 
range(begin, end)
{
set := object()
set.begin := begin
set.end := end
return set
}
 
!r::reload
!q::exitapp
 
triples(begin, end)
{
 
set := object()
index := 1
range := end - begin
 
loop, % range
{
x := begin + A_Index
loop, % range
{
y := A_Index + x
if y > 20
break
loop, % range
{
z := A_Index + y
if z > 20
break
isTriple := ((x ** 2 + y ** 2) == z ** 2)
if isTriple
{
set[index, 1] := x
set[index, 2] := y
set[index, 3] := z
index += 1
; msgbox % "triple: " x . y . z
}
 
}
}
}
return set
}
 

[edit] Bracmat

Bracmat does not have built-in list comprehension, but nevertheless there is a solution for fixed n that does not employ explicit loop syntax. By their positions in the pattern and the monotonically increasing values in the subject, it is guaranteed that x always is smaller than y and that y always is smaller than z. The combination of flags %@ ensures that x, y and z pick minimally one (%) and at most one (@) element from the subject list.

 
 :?py { Initialize the accumulating result list. }
& ( 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 { This is the subject }
 :  ? { Here starts the pattern }
 %@?x
 ?
 %@?y
 ?
 %@?z
( ?
& -1*!z^2+!x^2+!y^2:0
& (!x,!y,!z) !py:?py
& ~ { This 'failure' expression forces backtracking }
) { Here ends the pattern }
| out$!py { You get here when backtracking has
exhausted all combinations of x, y and z }
);

Output:

  (12,16,20)
  (9,12,15)
  (8,15,17)
  (6,8,10)
  (5,12,13)
  (3,4,5)

[edit] C

C doesn't have a built-in syntax for this, but any problem can be solved if you throw enough macros at it:

Works with: GCC
 
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
 
#ifndef __GNUC__
#include <setjmp.h>
struct LOOP_T; typedef struct LOOP_T LOOP;
struct LOOP_T {
jmp_buf b; LOOP * p;
} LOOP_base, * LOOP_V = &LOOP_base;
#define FOR(I, C, A, ACT) (LOOP_V = &(LOOP){ .p = LOOP_V }, \
(I), setjmp(LOOP_V->b), \
((C) ? ((ACT),(A), longjmp(LOOP_V->b, 1), 0) : 0), \
LOOP_V = LOOP_V->p, 0)

#else
#define FOR(I, C, A, ACT) (({for(I;C;A){ACT;}}), 0) // GNU version
#endif
 
typedef struct List { struct List * nx; char val[]; } List;
typedef struct { int _1, _2, _3; } Triple;
 
#define SEQ(OUT, SETS, PRED) (SEQ_var=&(ITERATOR){.l=NULL,.p=SEQ_var}, \
M_FFOLD(((PRED)?APPEND(OUT):0),M_ID SETS), \
SEQ_var->p->old=SEQ_var->l,SEQ_var=SEQ_var->p,SEQ_var->old)

typedef struct ITERATOR { List * l, * old; struct ITERATOR * p; } ITERATOR;
ITERATOR * FE_var, SEQ_base, * SEQ_var = &SEQ_base;
#define FOR_EACH(V, T, L, ACT) (FE_var=&(ITERATOR){.l=(L),.p=FE_var}, \
FOR((V) = *(T*)&FE_var->l->val, FE_var->l?((V)=*(T*)&FE_var->l->val,1):0, \
FE_var->l=FE_var->l->nx, ACT), FE_var=FE_var->p)

 
#define M_FFOLD(ID, ...) M_ID(M_CONC(M_FFOLD_, M_NARGS(__VA_ARGS__)) (ID, __VA_ARGS__))
#define FORSET(V, T, L) V, T, L
#define APPEND(T, val) (SEQ_var->l?listAppend(SEQ_var->l,sizeof(T),&val):(SEQ_var->l=listNew(sizeof(T),&val)))
 
#define M_FFOLD_1(ID, E) FOR_EACH M_IDP(FORSET E, ID)
#define M_FFOLD_2(ID, E, ...) FOR_EACH M_IDP(FORSET E, M_FFOLD_1(ID, __VA_ARGS__))
#define M_FFOLD_3(ID, E, ...) FOR_EACH M_IDP(FORSET E, M_FFOLD_2(ID, __VA_ARGS__)) //...
 
#define M_NARGS(...) M_NARGS_(__VA_ARGS__, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
#define M_NARGS_(_10, _9, _8, _7, _6, _5, _4, _3, _2, _1, N, ...) N
#define M_CONC(A, B) M_CONC_(A, B)
#define M_CONC_(A, B) A##B
#define M_ID(...) __VA_ARGS__
#define M_IDP(...) (__VA_ARGS__)
 
#define R(f, t) int,intRangeList(f, t)
#define T(a, b, c) Triple,((Triple){(a),(b),(c)})
 
List * listNew(int sz, void * val) {
List * l = malloc(sizeof(List) + sz); l->nx = NULL; memcpy(l->val, val, sz); return l;
}
List * listAppend(List * l, int sz, void * val) {
while (l->nx) { l = l->nx; } l->nx = listNew(sz, val); return l;
}
List * intRangeList(int f, int t) {
List * l = listNew(sizeof f, &f), * e = l;
for (int i = f + 1; i <= t; i ++) { e = e->nx = listNew(sizeof i, &i); }
return l;
}
 
int main(void) {
volatile int x, y, z; const int n = 20;
 
List * pTriples = SEQ(
T(x, y, z),
(
(x, R(1, n)),
(y, R(x, n)),
(z, R(y, n))
),
(x*x + y*y == z*z)
);
 
volatile Triple t;
FOR_EACH(t, Triple, pTriples, printf("%d, %d, %d\n", t._1, t._2, t._3) );
 
return 0;
}
 

Output:

3, 4, 5
5, 12, 13
6, 8, 10
8, 15, 17
9, 12, 15
12, 16, 20

Either GCC's "statement expressions" extension, or a minor piece of undefined behaviour, are required for this to work (technically setjmp, which powers the non-GCC version, isn't supposed to be part of a comma expression, but almost all compilers will treat it as intended). Variables used by one of these looping expressions should be declared volatile to prevent them from being modified by setjmp.

The list implementation in this example is a) terrible and b) leaks memory, neither of which are important to the example. In reality you would want to combine any lists being generated in expressions with an automatic memory management system (GC, autorelease pools, something like that).

[edit] C#

[edit] LINQ

using System.Linq;
 
static class Program
{
static void Main()
{
var ts =
from a in Enumerable.Range(1, 20)
from b in Enumerable.Range(a, 21 - a)
from c in Enumerable.Range(b, 21 - b)
where a * a + b * b == c * c
select new { a, b, c };
 
foreach (var t in ts)
System.Console.WriteLine("{0}, {1}, {2}", t.a, t.b, t.c);
}
}
 

[edit] C++

There is no equivalent construct in C++. The code below uses two nested loops and an if statement:

#include <vector>
#include <cmath>
#include <iostream>
#include <algorithm>
#include <iterator>
 
void list_comprehension( std::vector<int> & , int ) ;
 
int main( ) {
std::vector<int> triangles ;
list_comprehension( triangles , 20 ) ;
std::copy( triangles.begin( ) , triangles.end( ) ,
std::ostream_iterator<int>( std::cout , " " ) ) ;
std::cout << std::endl ;
return 0 ;
}
 
void list_comprehension( std::vector<int> & numbers , int upper_border ) {
for ( int a = 1 ; a < upper_border ; a++ ) {
for ( int b = a + 1 ; b < upper_border ; b++ ) {
double c = pow( a * a + b * b , 0.5 ) ; //remembering Mr. Pythagoras
if ( ( c * c ) < pow( upper_border , 2 ) + 1 ) {
if ( c == floor( c ) ) {
numbers.push_back( a ) ;
numbers.push_back( b ) ;
numbers.push_back( static_cast<int>( c ) ) ;
}
}
}
}
}
 

This produces the following output:

3 4 5 5 12 13 6 8 10 8 15 17 9 12 15 12 16 20
Works with: C++11
#include <functional>
#include <iostream>
 
void PythagoreanTriples(int limit, std::function<void(int,int,int)> yield)
{
for (int a = 1; a < limit; ++a) {
for (int b = a+1; b < limit; ++b) {
for (int c = b+1; c <= limit; ++c) {
if (a*a + b*b == c*c) {
yield(a, b, c);
}
}
}
}
}
 
int main()
{
PythagoreanTriples(20, [](int x, int y, int z)
{
std::cout << x << "," << y << "," << z << "\n";
});
return 0;
}

Output:

3,4,5
5,12,13
6,8,10
8,15,17
9,12,15
12,16,20

[edit] Clojure

(defn pythagorean-triples [n]
(for [x (range 1 (inc n))
y (range x (inc n))
z (range y (inc n))
:when (= (+ (* x x) (* y y)) (* z z))]
[x y z]))

[edit] CoffeeScript

flatten = (arr) -> arr.reduce ((memo, b) -> memo.concat b), []
 
pyth = (n) ->
flatten (for x in [1..n]
flatten (for y in [x..n]
for z in [y..n] when x*x + y*y is z*z
[x, y, z]
))
 
console.dir pyth 20

pyth can also be written more concisely as

pyth = (n) -> flatten (flatten ([x, y, z] for z in [y..n] when x*x + y*y is z*z for y in [x..n]) for x in [1..n])

[edit] Common Lisp

Common Lisp's loop macro has all of the features of list comprehension, except for nested iteration. (loop for x from 1 to 3 for y from x to 3 collect (list x y)) only returns ((1 1) (2 2) (3 3)). You can nest your macro calls, so (loop for x from 1 to 3 append (loop for y from x to 3 collect (list x y))) returns ((1 1) (1 2) (1 3) (2 2) (2 3) (3 3)).

Here are the Pythagorean triples:

(defun pythagorean-triples (n)
(loop for x from 1 to n
append (loop for y from x to n
append (loop for z from y to n
when (= (+ (* x x) (* y y)) (* z z))
collect (list x y z)))))

We can also define a new macro for list comprehensions. We can implement them easily with the help of the iterate package.

(defun nest (l)
(if (cdr l)
`(,@(car l) ,(nest (cdr l)))
(car l)))
 
(defun desugar-listc-form (form)
(if (string= (car form) 'for)
`(iter ,form)
form))
 
(defmacro listc (expr &body (form . forms) &aux (outer (gensym)))
(nest
`((iter ,outer ,form)
,@(mapcar #'desugar-listc-form forms)
(in ,outer (collect ,expr)))))

We can then define a function to compute Pythagorean triples as follows:

(defun pythagorean-triples (n)
(listc (list x y z)
(for x from 1 to n)
(for y from x to n)
(for z from y to n)
(when (= (+ (expt x 2) (expt y 2)) (expt z 2)))))

[edit] D

D doesn't have list comprehensions. One implementation:

import std.stdio, std.typetuple, std.range;
 
TA[] select(TA, TI1, TC1, TI2, TC2, TI3, TC3, TP)
(lazy TA mapper,
ref TI1 iter1, TC1 items1,
ref TI2 iter2, lazy TC2 items2,
ref TI3 iter3, lazy TC3 items3,
lazy TP where) {
Appender!(TA[]) result;
auto iters = TypeTuple!(iter1, iter2, iter3);
 
foreach (el1; items1) {
iter1 = el1;
foreach (el2; items2) {
iter2 = el2;
foreach (el3; items3) {
iter3 = el3;
if (where())
result ~= mapper();
}
}
}
 
TypeTuple!(iter1, iter2, iter3) = iters;
return result.data;
}
 
void main() {
enum int n = 21;
int x, y, z;
auto r = select([x,y,z], x, iota(1,n+1), y, iota(x,n+1), z,
iota(y, n + 1), x*x + y*y == z*z);
writeln(r);
}
Output:
[[3, 4, 5], [5, 12, 13], [6, 8, 10], [8, 15, 17], [9, 12, 15], [12, 16, 20]]

[edit] 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]) } } } }

[edit] Efene

pythag = fn (N) {
[(A, B, C) for A in lists.seq(1, N) \
for B in lists.seq(A, N) \
for C in lists.seq(B, N) \
if A + B + C <= N and A * A + B * B == C * C]
}
 
@public
run = fn () {
io.format("~p~n", [pythag(20)])
}
 

[edit] Ela

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

[edit] Erlang

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

[edit] F#

let pyth n = [ for a in [1..n] do
for b in [a..n] do
for c in [b..n] do
if (a*a+b*b = c*c) then yield (a,b,c)]

[edit] Fortran

Complex numbers simplify the task. However, the reshape intrinsic function along with implicit do loops can generate high rank matrices.

 
!-*- mode: compilation; default-directory: "/tmp/" -*-
!Compilation started at Fri Jun 7 23:39:20
!
!a=./f && make $a && $a
!gfortran -std=f2008 -Wall -fopenmp -ffree-form -fall-intrinsics -fimplicit-none f.f08 -o f
! 3 4 5
! 5 12 13
! 6 8 10
! 8 15 17
! 9 12 15
! 12 16 20
!
!Compilation finished at Fri Jun 7 23:39:20
 
program list_comprehension
integer, parameter :: n = 20
integer, parameter :: m = n*(n+1)/2
integer :: i, j
complex, dimension(m) :: a
real, dimension(m) :: b
logical, dimension(m) :: c
integer, dimension(3, m) :: d
a = (/ ( ( cmplx(i,j), i=j,n), j=1,n) /) ! list comprehension, implicit do loop
b = abs(a)
c = (b .eq. int(b)) .and. (b .le. n)
i = sum(merge(1,0,c))
d(2,:i) = int(real(pack(a, c))) ! list comprehensions: array
d(1,:i) = int(imag(pack(a, c))) ! assignments and operations.
d(3,:i) = int(pack(b,c))
print '(3i4)',d(:,:i)
end program list_comprehension
 

[edit] FunL

def triples( n ) = [(a, b, c) | a <- 1..n-2, b <- a+1..n-1, c <- b+1..n if a^2 + b^2 == c^2]
 
println( triples(20) )
Output:
[(3, 4, 5), (5, 12, 13), (6, 8, 10), (8, 15, 17), (9, 12, 15), (12, 16, 20)]

[edit] GAP

# We keep only primitive pythagorean triples
pyth := n ->
Filtered(Cartesian([1 .. n], [1 .. n], [1 .. n]),
u -> u[3]^2 = u[1]^2 + u[2]^2 and u[1] < u[2]
and GcdInt(u[1], u[2]) = 1);
 
pyth(100);
# [ [ 3, 4, 5 ], [ 5, 12, 13 ], [ 7, 24, 25 ], [ 8, 15, 17 ], [ 9, 40, 41 ], [ 11, 60, 61 ], [ 12, 35, 37 ],
# [ 13, 84, 85 ], [ 16, 63, 65 ], [ 20, 21, 29 ], [ 28, 45, 53 ], [ 33, 56, 65 ], [ 36, 77, 85 ], [ 39, 80, 89 ],
# [ 48, 55, 73 ], [ 65, 72, 97 ] ]

[edit] 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)

[edit] Icon and unicon

Icon's (and Unicon's) natural goal-directly evaluation produces result sequences and can be used to form list comprehensions. For example, the expression:

 
|(x := seq(), x^2 > 3, x*2)
 

is capable of producing successive elements from the infinite list described in the Wikipedia article. For example, to produce the first 100 elements:

 
procedure main()
every write(|(x := seq(), x^2 > 3, x*2) \ 100
end
 

While result sequences are lexically bound to the code that describes them, that code can be embedded in a co-expression to allow access to the result sequence throughout the code. So Pythagorean triples can be produced with (works in both languages):

procedure main(a)
n := integer(!a) | 20
s := create (x := 1 to n, y := x to n, z := y to n, x^2+y^2 = z^2, [x,y,z])
while a := @s do write(a[1]," ",a[2]," ",a[3])
end

Sample output:

->lc
3 4 5
5 12 13
6 8 10
8 15 17
9 12 15
12 16 20
->

[edit] Ioke

for(
x <- 1..20,
y <- x..20,
z <- y..20,
x * x + y * y == z * z,
[x, y, z]
)

[edit] J

require'stats'
buildSet=:conjunction def '(#~ v) u y'
triples=: 1 + 3&comb
isPyth=: 2&{"1 = 1&{"1 +&.:*: 0&{"1
pythTr=: triples buildSet isPyth

The idiom here has two major elements:

First, you need a statement indicating the values of interest. In this case, (1+3&comb) which when used as a function of n specifies a list of triples each in the range 1..n.

Second, you need a statement of the form (#~ B) where B returns true for the desired members, and false for the undesired members.

In the above example, the word isPyth is our predicate (represented as B in the preceding paragraph). This corresponds to the constraint clause in set builder notation.

In the above example the word triples represents the universe of potential solutions (some of which will be valid, some not). This corresponds to the generator part of set builder notation.

The argument to isPyth will be the candidate solutions (the result of triples). The argument to triples will be the largest element desired in a triple.

Example use:

   pythTr 20
3 4 5
5 12 13
6 8 10
8 15 17
9 12 15
12 16 20

[edit] JavaScript

Translation of: Python
Works with: JavaScript version 1.7+ (Firefox 2+)
Works with: SpiderMonkey version 1.7

See here for more details

function range(begin, end) {
for (let i = begin; i < end; ++i)
yield i;
}
 
function triples(n) {
return [[x,y,z] for each (x in range(1,n+1))
for each (y in range(x,n+1))
for each (z in range(y,n+1))
if (x*x + y*y == z*z) ]
}
 
for each (var triple in triples(20))
print(triple);

outputs:

3,4,5
5,12,13
6,8,10
8,15,17
9,12,15
12,16,20

[edit] jq

Direct approach:
def triples(n):
range(1;n+1) as $x | range($x;n+1) as $y | range($y;n+1) as $z
| select($x*$x + $y*$y == $z*$z)
| [$x, $y, $z] ;
 

Using listof(stream; criterion)

 
# listof( stream; criterion) constructs an array of those
# elements in the stream that satisfy the criterion
def listof( stream; criterion): [ stream|select(criterion) ];
 
def listof_triples(n):
listof( range(1;n+1) as $x | range($x;n+1) as $y | range($y;n+1) as $z
| [$x, $y, $z];
.[0] * .[0] + .[1] * .[1] == .[2] * .[2] ) ;
 
listof_triples(20)
 
Output:
$ jq -c -n -f list_of_triples.jq
[[3,4,5],[5,12,13],[6,8,10],[8,15,17],[9,12,15],[12,16,20]]

[edit] Lasso

Lasso uses query expressions for list manipulation.

#!/usr/bin/lasso9
 
local(n = 20)
local(triples =
with x in generateSeries(1, #n),
y in generateSeries(#x, #n),
z in generateSeries(#y, #n)
where #x*#x + #y*#y == #z*#z
select (:#x, #y, #z)
)
#triples->join('\n')

Output:

staticarray(3, 4, 5)
staticarray(5, 12, 13)
staticarray(6, 8, 10)
staticarray(8, 15, 17)
staticarray(9, 12, 15)
staticarray(12, 16, 20)

[edit] Lua

Lua doesn't have list comprehensions built in, but they can be constructed from chained coroutines:

 
LC={}
LC.__index = LC
 
function LC:new(o)
o = o or {}
setmetatable(o, self)
return o
end
 
function LC:add_iter(func)
local prev_iter = self.iter
self.iter = coroutine.wrap(
(prev_iter == nil) and (function() func{} end)
or (function() for arg in prev_iter do func(arg) end end))
return self
end
 
function maybe_call(maybe_func, arg)
if type(maybe_func) == "function" then return maybe_func(arg) end
return maybe_func
end
 
function LC:range(key, first, last)
return self:add_iter(function(arg)
for value=maybe_call(first, arg), maybe_call(last, arg) do
arg[key] = value
coroutine.yield(arg)
end
end)
end
 
function LC:where(pred)
return self:add_iter(function(arg) if pred(arg) then coroutine.yield(arg) end end)
end
 

We can then define a function to compute Pythagorean triples as follows:

 
function get(key)
return (function(arg) return arg[key] end)
end
 
function is_pythagorean(arg)
return (arg.x^2 + arg.y^2 == arg.z^2)
end
 
function list_pythagorean_triples(n)
return LC:new():range("x",1,n):range("y",1,get("x")):range("z", get("y"), n):where(is_pythagorean).iter
end
 
for arg in list_pythagorean_triples(100) do
print(arg.x, arg.y, arg.z)
end
 

[edit] Mathematica

Select[Tuples[Range[100], 3], #1[[1]]^2 + #1[[2]]^2 == #1[[3]]^2 &]
Pick[#, (#^2).{1, 1, -1}, 0] &@Tuples[Range[100], 3]

[edit] MATLAB / Octave

In Matlab/Octave, one does not think much about lists rather than vectors and matrices. Probably, the find() operation comes closes to the task

  N = 100;
[a,b] = mesgrid(1:N, 1:N);
c = sqrt(a.^2 + b.^2);
[x,y] = find( c==fix(c) );


[edit] Mercury

Solutions behaves like list comprehension since compound goals resemble set-builder notation.

 
:- module pythtrip.
:- interface.
:- import_module io.
:- import_module int.
 
:- type triple ---> triple(int, int, int).
 
:- pred pythTrip(int::in,triple::out) is nondet.
:- pred main(io::di, io::uo) is det.
 
:- implementation.
:- import_module list.
:- import_module solutions.
:- import_module math.
 
pythTrip(Limit,triple(X,Y,Z)) :-
nondet_int_in_range(1,Limit,X),
nondet_int_in_range(X,Limit,Y),
nondet_int_in_range(Y,Limit,Z),
pow(Z,2) = pow(X,2) + pow(Y,2).
 
main(!IO) :-
solutions((pred(Triple::out) is nondet :- pythTrip(20,Triple)),Result),
write(Result,!IO).
 

[edit] Nemerle

Demonstrating a list comprehension and an iterator. List comprehension adapted from Haskell example, iterator adapted from C# example.

using System;
using System.Console;
using System.Collections.Generic;
 
module Program
{
 
PythTriples(n : int) : list[int * int * int]
{
$[ (x, y, z) | x in [1..n], y in [x..n], z in [y..n], ((x**2) + (y**2)) == (z**2) ]
}
 
GetPythTriples(n : int) : IEnumerable[int * int * int]
{
foreach (x in [1..n])
{
foreach (y in [x..n])
{
foreach (z in [y..n])
{
when (((x**2) + (y**2)) == (z**2))
{
yield (x, y, z)
}
}
}
}
}
 
Main() : void
{
WriteLine("Pythagorean triples up to x = 20: {0}", PythTriples(20));
 
foreach (triple in GetPythTriples(20))
{
Write(triple)
}
}
}

[edit] Nimrod

There are no list comprehensions in Nimrod, but thanks to the strong metaprogramming capabilities we can implement our own:

import macros
 
type ListComprehension = object
var lc*: ListComprehension
 
macro `[]`*(lc: ListComprehension, x, t): expr =
expectLen(x, 3)
expectKind(x, nnkInfix)
expectKind(x[0], nnkIdent)
assert($x[0].ident == "|")
 
result = newCall(
newDotExpr(
newIdentNode("result"),
newIdentNode("add")),
x[1])
 
for i in countdown(x[2].len-1, 0):
let y = x[2][i]
expectKind(y, nnkInfix)
expectMinLen(y, 1)
if y[0].kind == nnkIdent and $y[0].ident == "<-":
expectLen(y, 3)
result = newNimNode(nnkForStmt).add(y[1], y[2], result)
else:
result = newIfStmt((y, result))
 
result = newNimNode(nnkCall).add(
newNimNode(nnkPar).add(
newNimNode(nnkLambda).add(
newEmptyNode(),
newEmptyNode(),
newEmptyNode(),
newNimNode(nnkFormalParams).add(
newNimNode(nnkBracketExpr).add(
newIdentNode("seq"),
t)),
newEmptyNode(),
newEmptyNode(),
newStmtList(
newAssignment(
newIdentNode("result"),
newNimNode(nnkPrefix).add(
newIdentNode("@"),
newNimNode(nnkBracket))),
result))))
 
const n = 20
echo lc[(x,y,z) | (x <- 1..n, y <- x..n, z <- y..n, x*x + y*y == z*z),
tuple[a,b,c: int]]

Output:

@[(a: 3, b: 4, c: 5), (a: 5, b: 12, c: 13), (a: 6, b: 8, c: 10), (a: 8, b: 15, c: 17), (a: 9, b: 12, c: 15), (a: 12, b: 16, c: 20)]

[edit] OCaml

OCaml Batteries Included has uniform comprehension syntax for lists, arrays, enumerations (like streams), lazy lists (like lists but evaluated on-demand), sets, hashtables, etc.

Comprehension are of the form [? expression | x <- enumeration ; condition; condition ; ...]

For instance,

#   [? 2 * x | x <- 0 -- max_int ; x * x > 3];;
- : int Enum.t = <abstr>

or, to compute a list,

#   [? List: 2 * x | x <- 0 -- 100 ; x * x > 3];;
- : int list = [2; 4; 6; 8; 10]

or, to compute a set,

#   [? PSet: 2 * x | x <- 0 -- 100 ; x * x > 3];;
- : int PSet.t = <abstr>

etc..

[edit] Oz

Oz does not have list comprehension.

However, there is a list comprehension package available here. It uses the unofficial and deprecated macro system. Usage example:

functor
import
LazyList
Application
System
define
 
fun {Pyth N}
<<list [X Y Z] with
X <- {List.number 1 N 1}
Y <- {List.number X N 1}
Z <- {List.number Y N 1}
where X*X + Y*Y == Z*Z
>>
end
 
{ForAll {Pyth 20} System.show}
 
{Application.exit 0}
end

[edit] PARI/GP

GP 2.6.0 added support for a new comprehension syntax:

Works with: PARI/GP version 2.6.0 and above
f(n)=[v|v<-vector(n^3,i,vector(3,j,i\n^(j-1)%n)),norml2(v)==2*v[3]^2]

Older versions of GP can emulate this through select:

Works with: PARI/GP version 2.4.3 and above
This code uses the select() function, which was added in PARI version 2.4.2. The order of the arguments changed between versions; to use in 2.4.2 change select(function, vector) to select(vector, function).
f(n)=select(v->norml2(v)==2*v[3]^2,vector(n^3,i,vector(3,j,i\n^(j-1)%n)))

Version 2.4.2 (obsolete, but widespread on Windows systems) requires inversion:

Works with: PARI/GP version 2.4.2
f(n)=select(vector(n^3,i,vector(3,j,i\n^(j-1)%n)),v->norml2(v)==2*v[3]^2)

[edit] Perl

Perl 5 does not have built-in list comprehension syntax. The closest approach are the list map and grep (elsewhere often known as filter) operators:

sub triples ($) {
my ($n) = @_;
map { my $x = $_; map { my $y = $_; map { [$x, $y, $_] } grep { $x**2 + $y**2 == $_**2 } 1..$n } 1..$n } 1..$n;
}

map binds $_ to each element of the input list and collects the results from the block. grep returns every element of the input list for which the block returns true. The .. operator generates a list of numbers in a specific range.

for my $t (triples(10)) {
print "@$t\n";
}

[edit] Perl 6

Perl 6 has single-dimensional list comprehensions that fall out naturally from nested modifiers; multidimensional comprehensions are also supported via the cross operator; however, Perl 6 does not (yet) support multi-dimensional list comprehensions with dependencies between the lists, so the most straightforward way is currently:

my $n = 20;
gather for 1..$n -> $x {
for $x..$n -> $y {
for $y..$n -> $z {
take $x,$y,$z if $x*$x + $y*$y == $z*$z;
}
}
}

Note that gather/take is the primitive in Perl 6 corresponding to generators or coroutines in other languages. It is not, however, tied to function call syntax in Perl 6. We can get away with that because lists are lazy, and the demand for more of the list is implicit; it does not need to be driven by function calls.

[edit] PicoLisp

PicoLisp doesn't have list comprehensions. We might use a generator function, pipe, coroutine or pilog predicate.

[edit] Using a generator function

(de pythag (N)
(job '((X . 1) (Y . 1) (Z . 0))
(loop
(when (> (inc 'Z) N)
(when (> (inc 'Y) N)
(setq Y (inc 'X)) )
(setq Z Y) )
(T (> X N))
(T (= (+ (* X X) (* Y Y)) (* Z Z))
(list X Y Z) ) ) ) )
 
(while (pythag 20)
(println @) )

[edit] Using a pipe

(pipe
(for X 20
(for Y (range X 20)
(for Z (range Y 20)
(when (= (+ (* X X) (* Y Y)) (* Z Z))
(pr (list X Y Z)) ) ) ) )
(while (rd)
(println @) ) )

[edit] Using a coroutine

Coroutines are available only in the 64-bit version.

(de pythag (N)
(co 'pythag
(for X N
(for Y (range X N)
(for Z (range Y N)
(when (= (+ (* X X) (* Y Y)) (* Z Z))
(yield (list X Y Z)) ) ) ) ) ) )
 
(while (pythag 20)
(println @) )

Output in all three cases:

(3 4 5)
(5 12 13)
(6 8 10)
(8 15 17)
(9 12 15)
(12 16 20)

[edit] Using Pilog

Works with: PicoLisp version 3.0.9.7
(be pythag (@N @X @Y @Z)
(for @X @N)
(for @Y @X @N)
(for @Z @Y @N)
(^ @
(let (X (-> @X) Y (-> @Y) Z (-> @Z))
(= (+ (* X X) (* Y Y)) (* Z Z)) ) ) )

Test:

: (? (pythag 20 @X @Y @Z))
@X=3 @Y=4 @Z=5
@X=5 @Y=12 @Z=13
@X=6 @Y=8 @Z=10
@X=8 @Y=15 @Z=17
@X=9 @Y=12 @Z=15
@X=12 @Y=16 @Z=20
-> NIL

[edit] Prolog

SWI-Prolog does not have list comprehension, however we can simulate it.

% We need operators
:- op(700, xfx, <-).
:- op(450, xfx, ..).
:- op(1100, yfx, &).
 
% we need to define the intervals of numbers
Vs <- M..N :-
integer(M),
integer(N),
M =< N,
between(M, N, Vs).
 
% finally we define list comprehension
% prototype is Vs <- {Var, Dec, Pred} where
% Var is the list of variables to output
% Dec is the list of intervals of the variables
% Pred is the list of predicates
Vs <- {Var & Dec & Pred} :-
findall(Var, maplist(call, [Dec, Pred]), Vs).
 

Examples of use :
List of Pythagorean triples :

 ?- V <- {X, Y, Z & X <- 1..20, Y <- X..20, Z <- Y..20 & X*X+Y*Y =:= Z*Z}.
V = [ (3,4,5), (5,12,13), (6,8,10), (8,15,17), (9,12,15), (12,16,20)] ;
false.

List of double of x, where x^2 is greater than 50 :

 ?- V <- {Y & X <- 1..20 & X*X > 50, Y is 2 * X}.
V = [16,18,20,22,24,26,28,30,32,34,36,38,40] ;
false.

[edit] 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]

A Python generator comprehension (note the outer round brackets), returns an iterator over the same result rather than an explicit list:

((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)

[edit] R

R have inherent list comprehension:

 
x = (0:10)
> x^2
[1] 0 1 4 9 16 25 36 49 64 81 100
> Reduce(function(y,z){return (y+z)},x)
[1] 55
> x[x[(0:length(x))] %% 2==0]
[1] 0 2 4 6 8 10
 

R's "data frame" functions can be used to achieve the same code clarity (at the cost of expanding the entire grid into memory before the filtering step)

 
subset(expand.grid(x=1:n, y=1:n, z=1:n), x^2 + y^2 == z^2)
 

[edit] Racket

 
#lang racket
(for*/list ([x (in-range 1 21)]
[y (in-range x 21)]
[z (in-range y 21)]
#:when (= (+ (* x x) (* y y)) (* z z)))
(list x y z))
 

[edit] Rascal

 
public list[tuple[int, int, int]] PythTriples(int n) = [<a, b, c> | a <- [1..n], b <- [1..n], c <- [1 .. n], a*a + b*b == c*c];
 

[edit] REXX

There is no native comprehensive supoort for lists per se, except that
normal lists can be processed quite easily and without much effort.

/*REXX program to list  Pythagorean triples  up to a specified number.  */
parse arg n . /*get the argument (possibly). */
if n=='' then n=100 /*Not specified? Then assume 100*/
call gen_triples n /*generate Pythagorean triples. */
call showhdr /*show a nice header. */
call showlist triples /*show the Pythagorean triples. */
exit /*stick a fork in it, we're done.*/
/*──────────────────────────────────GEN_TRIPLES subroutine──────────────*/
gen_triples: parse arg lim /*generate Pythorgorean triples. */
triples=
 
do a=1 for lim-2; aa=a*a /*a*a is faster than a**2 */
do b=a+1 to lim-1; aabb=aa+b*b
do c=b+1 to lim
if aabb==c*c then triples=triples '['a"-" || b'-'c"]"
end /*c*/
end /*b*/
end /*a*/
 
triples=strip(triples)
return
/*──────────────────────────────────SHOWHDR subroutine──────────────────*/
showHdr: say
if 'f0'x==0 then do; super2='b2'x; le='8c'x; end /*EBCDIC: super2, LE */
else do; super2='fd'x; le='f3'x; end /* ASCII: " " */
note='(a'super2 "+ b"super2 '= c'super2", c "le n')' /*prettify equat.*/
say 'Pythagorean triples' note":"
return
/*──────────────────────────────────SHOWLIST subroutine─────────────────*/
showlist: procedure; parse arg L /*get the list (L). */
w=words(L) /*number of members in the list. */
say; do j=1 for w /*display the members of the list*/
say word(L,j)
end /*j*/
say; say w 'members listed.'
return

output

Pythagorean triples (a² + b² = c²,  c ≤ 100):

[3-4-5]
[5-12-13]
[6-8-10]
[7-24-25]
[8-15-17]
[9-12-15]
[9-40-41]
[10-24-26]
[11-60-61]
[12-16-20]
[12-35-37]
[13-84-85]
[14-48-50]
[15-20-25]
[15-36-39]
[16-30-34]
[16-63-65]
[18-24-30]
[18-80-82]
[20-21-29]
[20-48-52]
[21-28-35]
[21-72-75]
[24-32-40]
[24-45-51]
[24-70-74]
[25-60-65]
[27-36-45]
[28-45-53]
[28-96-100]
[30-40-50]
[30-72-78]
[32-60-68]
[33-44-55]
[33-56-65]
[35-84-91]
[36-48-60]
[36-77-85]
[39-52-65]
[39-80-89]
[40-42-58]
[40-75-85]
[42-56-70]
[45-60-75]
[48-55-73]
[48-64-80]
[51-68-85]
[54-72-90]
[57-76-95]
[60-63-87]
[60-80-100]
[65-72-97]

52 members listed.

[edit] Ruby

Ruby has no special syntax for list comprehensions.

Enumerable#select comprises a list from one variable, like Perl grep() or Python filter(). Some lists need Array#map! to transform the variable.

Ruby's object-oriented style enforces writing 1..100 before x. Think not of x in 1..100. Think of 1..100 giving x.

There is no elegant way to comprise a list from multiple variables. Pythagorean triplets need three variables, with 1..n giving x, then x..n giving y, then y..n giving z. A less than elegant way is to nest three blocks.

[edit] Ruby 1.9.2

Works with: Ruby version 1.9.2
n = 20
 
# select Pythagorean triplets
r = ((1..n).flat_map { |x|
(x..n).flat_map { |y|
(y..n).flat_map { |z|
[[x, y, z]].keep_if { x * x + y * y == z * z }}}})
 
p r # print the array _r_

Output: [[3, 4, 5], [5, 12, 13], [6, 8, 10], [8, 15, 17], [9, 12, 15], [12, 16, 20]]

Ruby 1.9.2 introduces two new methods: Enumerable#flat_map joins all the arrays from the block. Array#keep_if is an alternative to Enumerable#select that modifies the original array. (We avoid Array#select! because it might not return the array.)

[edit] Ruby 1.8.6

Works with: Ruby version 1.8.6 or later
n = 20
 
unless Enumerable.method_defined? :flat_map
module Enumerable
def flat_map
inject([]) { |a, x| a.concat yield(x) }
end
end
end
 
unless Array.method_defined? :keep_if
class Array
def keep_if
delete_if { |x| not yield(x) }
end
end
end
 
# select Pythagorean triplets
r = ((1..n).flat_map { |x|
(x..n).flat_map { |y|
(y..n).flat_map { |z|
[[x, y, z]].keep_if { x * x + y * y == z * z }}}})
 
p r # print the array _r_

This is the exact same code, except that it now defines Enumerable#flat_map and Array#keep_if when those methods are missing. It now works with older versions of Ruby, like 1.8.6.

[edit] Run BASIC

for  x = 1 to 20 
for y = x to 20
for z = y to 20
if x^2 + y^2 = z^2 then print "[";x;",";y;",";z;"]"
next z
next y
next x
Output:
[3,4,5]
[5,12,13]
[6,8,10]
[8,15,17]
[9,12,15]
[12,16,20]

[edit] Scala

def pythagoranTriangles(n: Int) = for {
x <- 1 to 21
y <- x to 21
z <- y to 21
if x * x + y * y == z * z
} yield (x, y, z)

which is a syntactic sugar for:

 def pythagoranTriangles(n: Int) = (1 to n) flatMap (x => 
(x to n) flatMap (y =>
(y to n) filter (z => x * x + y * y == z * z) map (z =>
(x, y, z))))

Alas, the type of collection returned depends on the type of the collection being comprehended. In the example above, we are comprehending a Range. Since a Range of triangles doesn't make sense, it returns the closest (supertype) collection for which it does, an IndexedSeq.

To get a List out of it, just pass a List to it:

def pythagoranTriangles(n: Int) = for {
x <- List.range(1, n + 1)
y <- x to 21
z <- y to 21
if x * x + y * y == z * z
} yield (x, y, z)

Sample:

scala> pythagoranTriangles(21)
res36: List[(Int, Int, Int)] = List((3,4,5), (5,12,13), (6,8,10), (8,15,17), (9,12,15), (12,16,20))

[edit] Scheme

Scheme has no native list comprehensions, but SRFI-42 [1] provides them:

 
(list-ec (:range x 1 21)
(:range y x 21)
(:range z y 21)
(if (= (* z z) (+ (* x x) (* y y))))
(list x y z))
 
((3 4 5) (5 12 13) (6 8 10) (8 15 17) (9 12 15) (12 16 20))

[edit] Smalltalk

Works with: Pharo version 1.3-13315
 
| test |
 
test := [ :a :b :c | a*a+(b*b)=(c*c) ].
 
(1 to: 20)
combinations: 3 atATimeDo: [ :x |
(test valueWithArguments: x)
ifTrue: [ ':-)' logCr: x ] ].
 
"output on Transcript:
#(3 4 5)
#(5 12 13)
#(6 8 10)
#(8 15 17)
#(9 12 15)
#(12 16 20)"

 

[edit] SuperCollider

var pyth = {
arg n = 10; // default
all {: [x,y,z],
x <- (1..n),
y <- (x..n),
z <- (y..n),
(x**2) + (y**2) == (z**2)
};
};
 
pyth.value(20); // example call

returns

[ [ 3, 4, 5 ], [ 5, 12, 13 ], [ 6, 8, 10 ], [ 8, 15, 17 ], [ 9, 12, 15 ], [ 12, 16, 20 ] ]

[edit] Tcl

Tcl does not have list comprehensions built-in to the language, but they can be constructed.

package require Tcl 8.5
 
# from http://wiki.tcl.tk/12574
proc lcomp {expression args} {
# Check the number of arguments.
if {[llength $args] < 2} {
error "wrong # args: should be \"lcomp expression var1 list1\
 ?... varN listN? ?condition?\""

}
 
# Extract condition from $args, or use default.
if {[llength $args] % 2 == 1} {
set condition [lindex $args end]
set args [lrange $args 0 end-1]
} else {
set condition 1
}
 
# Collect all var/list pairs and store in reverse order.
set varlst [list]
foreach {var lst} $args {
set varlst [concat [list $var] [list $lst] $varlst]
}
 
# Actual command to be executed, repeatedly.
set script {lappend result [subst $expression]}
 
# If necessary, make $script conditional.
if {$condition ne "1"} {
set script [list if $condition $script]
}
 
# Apply layers of foreach constructs around $script.
foreach {var lst} $varlst {
set script [list foreach $var $lst $script]
}
 
# Do it!
set result [list]
{*}$script ;# Change to "eval $script" if using Tcl 8.4 or older.
return $result
}
 
set range {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20}
puts [lcomp {$x $y $z} x $range y $range z $range {$x < $y && $x**2 + $y**2 == $z**2}]
{3 4 5} {5 12 13} {6 8 10} {8 15 17} {9 12 15} {12 16 20}

[edit] TI-89 BASIC

TI-89 BASIC does not have a true list comprehension, but it has the seq() operator which can be used for some similar purposes.

{1, 2, 3, 4} → a
seq(a[i]^2, i, 1, dim(a))

produces {1, 4, 9, 16}. When the input is simply a numeric range, an input list is not needed; this produces the same result:

seq(x^2, x, 1, 4)

[edit] Visual Basic .NET

Translation of: C#
Module ListComp
Sub Main()
Dim ts = From a In Enumerable.Range(1, 20) _
From b In Enumerable.Range(a, 21 - a) _
From c In Enumerable.Range(b, 21 - b) _
Where a * a + b * b = c * c _
Select New With { a, b, c }
 
For Each t In ts
System.Console.WriteLine("{0}, {1}, {2}", t.a, t.b, t.c)
Next
End Sub
End Module

Output:

3, 4, 5
5, 12, 13
6, 8, 10
8, 15, 17
9, 12, 15
12, 16, 20

[edit] Visual Prolog

VP7 has explicit list comprehension syntax.

 
implement main
open core, std
 
domains
pythtrip = pt(integer, integer, integer).
 
class predicates
pythTrips : (integer) -> pythtrip nondeterm (i).
 
clauses
pythTrips(Limit) = pt(X,Y,Z) :-
X = fromTo(1,Limit),
Y = fromTo(X,Limit),
Z = fromTo(Y,Limit),
Z^2 = X^2 + Y^2.
 
run():-
console::init(),
Triples = [ X || X = pythTrips(20) ],
console::write(Triples),
Junk = console::readLine(),
succeed().
end implement main
 
goal
mainExe::run(main::run).
 

[edit] Wrapl

ALL WITH x <- 1:to(n), y <- x:to(n), z <- y:to(n) DO (x^2 + y^2 = z^2) & [x, y, z];

[edit] zkl

var n=20;
[[(x,y,z); [1..n]; {[x..n]}; {[y..n]},{x*x + y*y == z*z}; T]]
//-->L(L(3,4,5),L(5,12,13),L(6,8,10),L(8,15,17),L(9,12,15),L(12,16,20))

Lazy:

var n=20;
lp:=[& (x,y,z); // three variables, [& means lazy
[1..n]; // x: a range
{[x..n]}; // y: another range, fcn(x) is implicit
{[y..n]}, // z with a filter, expanded to fcn(x,y){[y..n]}
{x*x + y*y == z*z}; // the filter, fcn(x,y,z)
{T(x,y,z)} // the result, could also be written as fcn(x,y,z){T(x,y,z)}
// or just T (read only list) as T(x,y,z) creates a new list
// with values x,y,z, or just _ (which means return arglist)
]]
lp.walk(2) //-->L(L(3,4,5),L(5,12,13))
Retrieved from "http://rosettacode.org/mw/index.php?title=List_comprehensions&oldid=189107"
Personal tools
Namespaces

Variants
Actions
Community
Explore
Misc
Toolbox