• Re: counting nils in a list

    From B. Pym@21:1/5 to Pascal J. Bourguignon on Wed Jul 17 04:12:35 2024
    Pascal J. Bourguignon wrote:

    For example, if we have a function such as cut-list-if, which can cut
    a list between elements according to a predicate taking two successive elements in the list, such as:

    (cut-list-if (lambda (a b) (or a b))
    '(nil nil nil a nil nil nil a b nil nil nil
    a b c nil nil nil a b c d e nil))
    ((NIL NIL NIL) (A) (NIL NIL NIL) (A) (B) (NIL NIL NIL) (A) (B) (C)
    (NIL NIL NIL) (A) (B) (C) (D) (E) (NIL))

    Oops, I forgot to present a CUT-LIST-IF:

    (defun cut-list-if (predicate list)
    (loop
    :with results = '()
    :with sublist = '()
    :for (a b) :on list
    :do (if (funcall predicate a b)
    (progn
    (push a sublist)
    (push sublist results)
    (setf sublist '()))
    (push a sublist))
    :finally (when sublist (push sublist results)) (return (reverse results))))


    Buggy:

    * (cut-list-if (lambda (a b) (or (numberp a) (numberp b)))
    '(a b c 8 d e f 7 6 g 5 h i))

    ((C B A) (8) (F E D) (7) (6) (G) (5) (I H))



    Gauche Scheme

    (use gauche.collection) ;; fold2

    ;; Correcting his bug.
    (define (cut-list-if predicate the-list)
    (receive (tmp res)
    (fold2
    (lambda (a tmp res)
    (if (or (null? tmp) (not (predicate (car tmp) a)))
    (values (cons a tmp) res)
    (values (list a) (cons tmp res))))
    '() '()
    the-list)
    (reverse (map reverse (cons tmp res)))))


    (cut-list-if (lambda (a b) (or (number? a) (number? b)))
    '(a b c 8 d e f 7 6 g 5 h i 5))

    ===>
    ((a b c) (8) (d e f) (7) (6) (g) (5) (h i) (5))


    (cut-list-if (lambda (a b) (or a b))
    '(#f #f #f a #f #f #f a b #f #f #f
    a b c #f #f #f a b c d e #f))

    ===>
    ((#f #f #f) (a) (#f #f #f) (a) (b) (#f #f #f) (a) (b) (c)
    (#f #f #f) (a) (b) (c) (d) (e) (#f))


    (cut-list-if > '(0 2 3 5 4 5 6))

    ===>
    ((0 2 3 5) (4 5 6))

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)