www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Small code example

This is a long line of Python2.x code that I've found difficult to translate to
nice D1 code, even using my dlibs:

result = min( ((arr[i], arr[j])
              for i in xrange(len(arr) - 1)
              for j in xrange(i + 1, min(i + 5, len(arr)))),
             key=dist)

Where:

arr is a list (that are dynamic arrays in Python) of items.

dist() is a function that takes a couple of items (here a tuple of length 2)
and returns the distance between them.

len() returns the length of a list.

xrange(x,y) yields the numbers from x to y-1.

min(iter, key=func) returns the minimum value of an iterable iter, using func
as mapping function to find the minimum value, so min([-1, 5, -2, -4], key=abs)
is -1.

Here the first agument given to the min() function is a lazy iterable, this is
useful when arr is very long.

That code shows why Python lazy/strict comps are useful.

An implementation in D1 that uses no higher order functions:

import std.stdio: writefln;

int min(int x, int y) {
    return x <= y ? x : y;
}

int dist(int x, int y) {
    return (x < y) ? (y - x) : (x - y);
}

void main() {
    int[] arr = [1, 12, 3, 7, 5, 13];
    int min_dist = int.max;
    int min_i, min_j;
    for (int i; i < arr.length - 1; i++)
        for (int j = i + 1; j < min(i + 5, arr.length); j++) {
            auto d = dist(arr[i], arr[j]);
            if (d < min_dist) {
                min_dist = d;
                min_i = i;
                min_j = j;
            }
        }

    writefln(arr[min_i], " ", arr[min_j]);
}


An alternative implementation in D1 that uses no higher order functions:

import std.stdio: writefln;

int min(int x, int y) {
    return x <= y ? x : y;
}

int dist(int x, int y) {
    return (x < y) ? (y - x) : (x - y);
}

void main() {
    int[] arr = [1, 12, 3, 7, 5, 13];
    int min_dist = int.max;
    int min_i, min_j;
    foreach (i, arr_i; arr[0 .. $ - 1])
        foreach (j, arr_j; arr[i + 1 .. min(i + 5, arr.length)]) {
            auto d = dist(arr_i, arr_j);
            if (d < min_dist) {
                min_dist = d;
                min_i = i;
                min_j = j + i + 1; // careful here
            }
        }

    writefln(arr[min_i], " ", arr[min_j]);
}

Bye,
bearophile
Nov 24 2009