пытаясь написать функцию, которая возвращает каждый третий элемент в списке в рэкетном языке - PullRequest
0 голосов
/ 16 декабря 2018

Попытка написать функцию, которая возвращает каждый третий элемент в списке, включая первый элемент в ракетке.Все, что я сейчас получаю, это мой код, взорвавшийся первым: нарушение контракта
ожидаемое: (и / c список? (Не / c пустой?)) Задано: 4

(define l (list 1 2 3 4 5 6 7 8 9))

(define (skipper lst)
   (if (null? lst)
       '() 
       (cons (first lst) 
             (skipper (car (cdr (cdr (cdr lst))))))))
(skipper l)

Ответы [ 2 ]

0 голосов
/ 21 декабря 2018

Проблема в том, что вы не можете вызвать (cdr (cdr (cdr lst))), когда lst содержит менее 3 элементов.

Вы пометили это ракеткой, поэтому я собираюсь показать вам решение, используя match

(define (skipper l)
  (match l

    ;; some element and at least 3 more
    ((list a rest ..3)
     (cons a (skipper (cddr rest))))

    ;; at least one element
    ((cons a _)
     (list a))

    ;; otherwise
    (else
     empty)))

(skipper '())
;; '()

(skipper '(0))
;; '(0)

(skipper '(0 1 2 3 4 5 6 7))
;; '(0 3 6)

(skipper '(0 1 2 3 4 5 6 7 8 9))
;; '(0 3 6 9)

В этом решении не используется length, который излишне вычисляет длину списка

0 голосов
/ 18 декабря 2018

Проблема была только car вокруг cdddr.

(define l (list 1 2 3 4 5 6 7 8 9))

(define (skipper lst)
   (if (null? lst)
       '() 
       (cons (first lst) 
             (skipper (if (< (length lst) 3)
                          '()
                          (cdddr lst))))))

(skipper l) ;; '(1 4 7)

Обобщенное решение

(define (my-cdr lst)      ;; `cdr` behaving like in common-lisp: (cdr '()) -> '()
  (cond ((null? lst) '())
        (else (cdr lst))))

(define (multi-cdr lst k) ;; apply `my-cdr` k-times on `lst`
  (cond ((zero? k) lst)
        (else (multi-cdr (my-cdr lst) (- k 1)))))

(define (skipper lst k)
   (if (null? lst)
       '() 
       (cons (first lst) 
             (skipper (multi-cdr lst k) k))))

Проверьте это:

(skipper l 3) ;; '(1 4 7)
(skipper l 4) ;; '(1 5 9)
(skipper l 2) ;; '(1 3 5 7 9)
(skipper l 1) ;; '(1 2 3 4 5 6 7 8 9)
...