On Mon, Jun 15, 2009 at 3:03 AM, Joe Neeman<joenee...@gmail.com> wrote:
>
> On Mon, Jun 8, 2009 at 3:59 AM, Mark Polesky <markpole...@yahoo.com> wrote:
>>
>> my version:
>>
>> (define-public (split-at-predicate predicate lst)
>>  "Split LST (into 2 lists) at the first element that returns #f for
>>   (PREDICATE previous_element element), and return the 2 new lists as a
>>   pair. Example: (split-at-predicate < '(1 2 3 2 1)) ==> ((1 2 3) 2 1)"
>>  (if (< (length lst) 2)
>>      (cons lst '())
>>      (let loop ((L0 (list (car lst))) (L1 (cdr lst)))
>>        (cond ((null? L1) (cons L0 L1))
>>              ((predicate (car (last-pair L0))
>
> last-pair is an O(n) operation, since it has to traverse the whole list,
> making split-at-predicate O(n^2) instead of O(n), as it should be. You'd be
> better off building L0 backwards and reversing it at the end, so that the
> element you need is always at the beginning of a list.
>

Also it should avoid length when a null? check will do. Here's the
function with those changes:

(define-public (split-at-predicate predicate lst)
  "Split a list into 2 lists at the first element that returns #f for
  (predicate previous_element element). Return the two parts as a pair.
  Example: (split-at-predicate < '(1 2 3 2 1)) ==> ((1 2 3) . (2 1))"
  (if (or (null? lst) (null? (cdr lst)))
    (list lst)
    (let loop ((lst-a (list (car lst))) (lst-b (cdr lst)))
      (cond ((null? lst-b) (list lst))
            ((predicate (car lst-a) (car lst-b))
              (loop (cons (car lst-b) lst-a) (cdr lst-b)))
            (else (cons (reverse lst-a) lst-b))))))


_______________________________________________
lilypond-devel mailing list
lilypond-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/lilypond-devel

Reply via email to