leonardo
View:Recent Entries.
View:Archive.
View:Friends.
View:User Info.
View:Website (My Website).
You're looking at the latest 1 entries.

Tags:, , , , ,
Subject:Returning '(()) isn't difficult
Time:04:19 pm
A little amusing post about language syntax:
http://cadrlife.blogspot.com/2008/03/returning-considered-difficult.html

"Suppose you want a function to find all subsequences of a list with a certain length. For instance, the subsequences of (1...5) with length 2 are as follows."
(1 2) (1 3) (1 4) (1 5)
(2 3) (2 4) (2 5)
(3 4) (3 5)
(4 5)
In a lisp dialect:
(def subn (n li)
 (if (is 0 n) '(())
     (no li) '()
       (join (map [cons (car li) _] (subn (- n 1) (cdr li)))
             (subn n (cdr li)))))
Haskell:
subn 0 _      = [[]]
subn _ []     = []
subn n (x:xs) = map (x:) (subn (n-1) xs) ++ subn n xs
Python:
def subn(n, a):
    if not n: return [[]]
    if not a: return []
    return [[a[0]] + sub for sub in subn(n-1, a[1:])] + subn(n, a[1:])
The Scala version too uses pattern matching, showing how much it can be useful (it may be useful for D language too):
def subn[T](n: int, li : List[T]) : List[List[T]] = (n,li) match {
   case (0,_)     => List(Nil)
   case (_,Nil)   => Nil
   case (_,x::xs) => (subn(n-1, xs) map (x :: _)) ::: subn(n, xs)
}
D version using my libs:
import d.func: putr, map, not, range, xrange, select, BaseType, array;

T[][] subn(T)(int n, T[] a) {
    if (!n) return new T[][](1, 0);
    if (not(a)) return new T[][0];
    return map((T[] s){return a[0..1] ~ s;}, subn(n-1, a[1..$])) ~ subn(n, a[1..$]);
}
If you want shorter lines you can use select (reverted from the 'list' name):
T[][] subn2(T)(int n, T[] a) {
    if (!n) return new T[][](1, 0);
    if (not(a)) return new T[][0];
    T[] s;
    return select(a[0..1] ~ s, s, subn2(n-1, a[1..$])) ~ subn2(n, a[1..$]);
}
This version is able to digest any iterable:
BaseType!(TyIter)[][] subn3(TyIter)(int n, TyIter iter) {
    auto a = array(iter);
    alias BaseType!(TyIter) T;
    if (!n) return new T[][](1, 0);
    if (not(a)) return new T[][0];
    return map((T[] s){return a[0..1] ~ s;}, subn3(n-1, a[1..$])) ~ subn3(n, a[1..$]);
}

void main() {
    putr( subn(2, range(5)) );
    // Output: [[0, 1], [0, 2], [0, 3], [0, 4], [1, 2], [1, 3], [1, 4],
    //          [2, 3], [2, 4], [3, 4]]  

    putr( subn2(3, range(5)) );
    // [[0, 1, 2], [0, 1, 3], [0, 1, 4], [0, 2, 3], [0, 2, 4], [0, 3, 4],
    //  [1, 2, 3], [1, 2, 4], [1, 3, 4], [2, 3, 4]]

    putr( subn3(2, xrange(5)) );
    // Output: [[0, 1], [0, 2], [0, 3], [0, 4], [1, 2], [1, 3], [1, 4],
    //          [2, 3], [2, 4], [3, 4]]    
}
comments: Leave a comment Add to Memories Tell a Friend

leonardo
View:Recent Entries.
View:Archive.
View:Friends.
View:User Info.
View:Website (My Website).
You're looking at the latest 1 entries.