/
CDC-1.2b/
CDC-1.2b/src/
parent $libraries
object $list

var $root child_index 0
var $root owners [$list]
var $root fertile 0
var $root inited 1
var $root owned [$list]
var $root manager $list
var $root writable [$list]
var $root readable ['parameters, 'methods, 'code]
var $root dbref 'list

method to_string
    arg list, [sep];
    var str, part;
    
    // uses $data.unparse() rather than tostr()
    if (!list)
        return "";
    sep = [@sep, " "][1];
    str = tostr(list[1]);
    for part in (delete(list, 1))
        str = (str + sep) + tostr(part);
    return str;
.

method to_english
    arg list, [options];
    var empty, and, sep;
    
    // uses $data.unparse() rather than tostr()
    empty = [@options, "nothing"][1];
    switch (listlen(list)) {
        case 0:
            return empty;
        case 1:
            return tostr(list[1]);
    }
    and = [@options, " and ", " and "][2];
    sep = [@options, ", ", ", ", ", "][3];
    return ((.to_string(delete(list, listlen(list)), sep)) + and) + tostr(list[listlen(list)]);
.

method map
    arg list, method, [args];
    var out, x;
    
    // call 'method on each object, return results.
    out = [];
    for x in (list)
        out = [@out, x.(method)(@args)];
    return out;
.

method filter
    arg list, method, [args];
    var out, x;
    
    // similar to .map, but returns a list of objects which returned a
    // true value from 'method.
    out = [];
    for x in (list) {
        if (x.(method)(@args))
            out = [@out, x];
    }
    return out;
.

method sort
    arg list, [sortby];
    
    // calls ._sort().  Does not set an element to sort by yet, but should
    // eventually will have to fix.
    return ._sort(list, 1, listlen(list));
.

method _sort
    arg lst, x, y;
    var p, i, j;
    
    switch ((y - x) + 1) {
        case 0, 1:
            return lst;
        case 2:
            if ((lst[x]) <= (lst[y]))
                return lst;
            p = lst[x];
            lst = replace(lst, x, lst[y]);
            lst = replace(lst, y, p);
            return lst;
        case 3:
            if ((lst[x]) <= (lst[x + 1])) {
                if ((lst[x + 1]) <= (lst[y])) {
                } else if ((lst[x]) <= (lst[y])) {
                    p = lst[x + 1];
                    lst = replace(lst, x + 1, lst[y]);
                    lst = replace(lst, y, p);
                } else {
                    p = lst[x];
                    lst = replace(lst, x, lst[y]);
                    lst = replace(lst, y, lst[x + 1]);
                    lst = replace(lst, x + 1, p);
                }
            } else if ((lst[x]) <= (lst[y])) {
                p = lst[x];
                lst = replace(lst, x, lst[x + 1]);
                lst = replace(lst, x + 1, p);
            } else if ((lst[x + 1]) <= (lst[y])) {
                p = lst[x];
                lst = replace(lst, x, lst[x + 1]);
                lst = replace(lst, x + 1, lst[y]);
                lst = replace(lst, y, p);
            } else {
                p = lst[x];
                lst = replace(lst, x, lst[y]);
                lst = replace(lst, y, p);
            }
            return lst;
    }
    p = lst[x];
    i = x;
    j = y;
    while (1) {
        while ((i < j) && (p <= (lst[j])))
            j = j - 1;
        if (i == j)
            break;
        lst = replace(lst, i, lst[j]);
        i = i + 1;
        while ((i < j) && (p >= (lst[i])))
            i = i + 1;
        if (i == j)
            break;
        lst = replace(lst, j, lst[i]);
        j = j - 1;
    }
    lst = replace(lst, i, p);
    lst = ._sort(lst, x, i - 1);
    lst = ._sort(lst, i + 1, y);
    return lst;
.

method columnize
    arg list, cols, [rest];
    var width, lines, line, separator, linelength, curcol;
    
    // turn [...] into ".   .   ."
    // rest[1]==separator; rest[2]==linelength
    separator = [@rest, "   "][1];
    linelength = [@rest, 78, 78][2];
    width = (linelength / cols) - strlen(separator);
    lines = [];
    while (list) {
        line = pad(list[1], width);
        list = sublist(list, 2);
        for curcol in [2 .. cols] {
            if (list) {
                line = (line + separator) + pad(list[1], width);
                list = sublist(list, 2);
            }
        }
        lines = [@lines, line];
    }
    return lines;
.

method reverse
    arg list;
    var elm, reversed;
    
    // .reverse(list)
    // -> list with its elements reversed
    reversed = [];
    for elm in (list)
        reversed = [elm, @reversed];
    return reversed;
.

method compress
    arg list;
    var out, last, x;
    
    // [a,a,b,b,c,c,d,d] => [a,b,c,d]
    // removes duplicate entries in a list
    last = list[1];
    out = [last];
    for x in (delete(list, 1)) {
        if (x != last) {
            out = [@out, x];
            last = x;
        }
    }
    return out;
.

method last
    arg list;
    
    return list[listlen(list)];
.

method count
    arg elem, list;
    var count;
    
    // count of elem in list
    while (elem in list) {
        count = count + 1;
        list = sublist(list, (elem in list) + 1);
    }
    return count;
.

method element_maxlength
    arg list;
    var elm, max, len;
    
    // Returns tostr(element) string in list.
    if (type(list) != 'list)
        throw(~type, "Second argument is not a list");
    max = 0;
    for elm in (list) {
        len = strlen(tostr(elm));
        max = (len > max) ? len | max;
    }
    return max;
.

method nth_element_maxlength
    arg lists, element;
    var list, max, len;
    
    // Returns longest string whose index is element in one of the lists in lists.
    if (type(element) != 'integer)
        throw(~type, "First argument is not an integer");
    if (type(lists) != 'list)
        throw(~type, "Second argument is not a list");
    max = 0;
    for list in (lists) {
        len = strlen(tostr(list[element]));
        if (len > max)
            max = len;
    }
    return max;
.

method numbered_text
    arg text;
    var line;
    
    // receives a list of strings, returns that list with line numbers pre-pended
    for line in [1 .. listlen(text)]
        text = replace(text, line, ((((line < 10) ? " " | "") + tostr(line)) + ": ") + (text[line]));
    return text;
.

method slice
    arg big_list, element;
    var list, ret_list;
    
    // Return elementh' element of all lists in big_list
    // No type or length checking done for speed purposes.
    ret_list = [];
    for list in (big_list)
        ret_list = [@ret_list, list[element]];
    return ret_list;
.

method swap
    arg list, a, b;
    var holder;
    
    // swap elements at indexes a and b
    holder = (> list[a] <);
    list = (> replace(list, a, list[b]) <);
    list = replace(list, b, holder);
    return list;
.

method max
    arg [list];
    
    // return greatest element of list (no type checking performed)
    // if list is [], returns 0
    while (listlen(list) > 1) {
        if ((list[1]) > (list[2]))
            list = delete(list, 2);
        else
            list = delete(list, 1);
    }
    return [@list, 0][1];
.

method min
    arg [list];
    
    // return least element of list (no type checking performed)
    // if list is [], returns 0
    while (listlen(list) > 1) {
        if ((list[1]) < (list[2]))
            list = delete(list, 2);
        else
            list = delete(list, 1);
    }
    return [@list, 0][1];
.

method lcolumnize
    arg list, linelen, [seperator];
    var lines, mlen, cols, width, c, line;
    
    // var width, lines, line, separator, linelength, curcol;
    // turn [...] into ".   .   ."
    // this one just fits the columns into the linelen
    seperator = [@seperator, " "][1];
    lines = [];
    mlen = (.element_maxlength(list)) + strlen(seperator);
    cols = (linelen > mlen) ? linelen / mlen | 1;
    width = linelen / cols;
    while (list) {
        line = pad(list[1], width);
        list = sublist(list, 2);
        for c in [2 .. cols] {
            if (list) {
                line = (line + seperator) + pad(list[1], width);
                list = sublist(list, 2);
            }
        }
        lines = [@lines, line];
    }
    return lines;
.

method swapsort
    arg list, [sort_by];
    var bot_elem, cur_elem, elem, compare;
    
    // note: iterative implementation allows sorts of extra-long lists
    elem = [@sort_by, 1];
    compare = [@sort_by, 'gt, 'lt][2];
    for bot_elem in [1 .. listlen(list)] {
        for cur_elem in [bot_elem + 1 .. listlen(list)] {
            if (._swap_compare(list[bot_elem], list[cur_elem], compare, elem))
                list = $list.swap(list, bot_elem, cur_elem);
        }
    }
    return list;
.

method _swap_compare
    arg elem1, elem2, compare, [elem];
    
    elem = [@elem, 1][1];
    switch (compare) {
        case 'lt:
            return (elem1[elem]) < (elem2[elem]);
        case 'gt:
            return (elem1[elem]) > (elem2[elem]);
        default:
            return 0;
    }
.

method heapsort
    arg list, [sort_by];
    var heap, sort_type, sort_elem;
    
    sort_elem = [@sort_by, 1][1];
    sort_type = [@sort_by, 'gt, 'gt][2];
    switch (sort_type) {
        case 'gt:
            heap = $small_first_heap_class.new(list, sort_elem);
        default:
            return list;
    }
    list = [];
    while (heap.length()) {
        list = heap.element(1);
        heap = heap.del(1);
    }
    return list;
.

method map_to_english
    arg list, method, [args];
    
    // because I (Lynx) am lazy
    return .to_english(.map(list, method, @args));
.

method map_to_string
    arg list, method, [args];
    
    // because I (Lynx) am lazy
    return .to_string(.map(list, method, @args));
.

method flatten
    arg list;
    var toret, elem;
    
    // [[[x], x], x]   =>   [x, x, x]
    toret = [];
    for elem in (list) {
        if (type(elem) == 'list)
            toret = toret + (.flatten(elem));
        else
            toret = toret + [elem];
    }
    return toret;
.

method sum
    arg ints;
    var ret;
    
    // returns a sum of each integer in the list.
    ret = 0;
    while (ints) {
        ret = ret + (ints[1]);
        ints = delete(ints, 1);
    }
    return ret;
.

method non_alphanumeric
    // returns nun-alphanumeric in a list of characters
    return ["!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "+", "-", "=", "~", "`", "'", "{", "}", "[", "]", "|", "/", "?", "\"", "\\", ",", ".", "<", ">", ";", ":", " "];
.

method numbers
    // returns a list of numbers
    return ["0", "1", "2", "3", "4", "5", "6", "7", "8", "9"];
.

method alphabet
    //returns the alphabet in a list
    return ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z"];
.

method center_lines
    arg lines, width, [args];
    var output, line;
    
    output = [];
    for line in (lines)
        output = [@output, $string.center(line, width, @args)];
    return output;
.

method to_buffer
    arg list;
    
    // assumes this is a list of strings (for now)
    return buffer_from_strings(list);
.

method delete
    arg [args];
    
    return (> delete(@args) <);
.

method replace
    arg [args];
    
    return (> replace(@args) <);
.

method chop
    arg list, [count];
    
    // chops the last <count> elements off the list.
    // return [] if count is longer then the list.
    count = count || 1;
    return (| sublist(list, 1, listlen(list) - count) |) || [];
.

method join
    arg l1, l2;
    var last, first;
    
    // Combines l1 and l2 by by appending the first element of l2 to t the last of
    // l1. 
    //if (type(l1) != 'list)
    //  l1=[l1];
    if (type(l2) != 'list)
        l2 = [l2];
    last = (| l1.last() |) || "";
    first = (| l2[1] |) || "";
    l1 = [@(| l1.chop() |) || [], last + first];
    if (listlen(l2) > 1)
        l1 = [@l1, @sublist(l2, 2)];
    return l1;
.

method lmap
    arg list, method, [args];
    var out, x, s;
    
    //call methods for each thing in list on sender()
    out = [];
    s = sender();
    for x in (list)
        out = [@out, s.(method)(x, @args)];
    return out;
.

method length
    arg l;
    
    return listlen(l);
.

method union
    arg [args];
    
    return (> union(@args) <);
.

method sublist
    arg [args];
    
    return (> sublist(@args) <);
.

method omap
    arg list, object, method, [args];
    var out, obj;
    
    // calls object.method(obj, @args) for each obj in list
    out = [];
    for obj in (list)
        out = [@out, object.(method)(obj, @args)];
    return out;
.

method del
    arg list, element;
    
    return (> setremove(list, element) <);
.

method add
    arg list, element;
    
    return (> setadd(list, element) <);
.