Схема - как не "сплющивать" пары в списке?

Моя задача получить первый атом в структуре, поэтому я использую flatten и func "first-atom-lst". Но есть одна большая проблема - мне нужно обрабатывать пары в структуре и НЕ разбивать пары. Не могли бы вы помочь мне справиться с этим?

(define (check-improper? lst)
  (cond
       ((null? lst) #f)
       ((number? lst) #f)
       ((atom? lst) #f)
       ((list? lst) #f)
  ((pair? (cdr lst)) #t)
  (#t #f)
  ))

(define (improper-to-proper lst)
  (cond
    ((null? lst) '())
    ((not (pair? (cdr lst))) (cons lst  '()))
    (else (cons (car lst) (improper-to-proper (cdr lst))))
    )
  )

(define (first-atom-from-pair lst)
  (cond ((check-improper? lst))
        ((null? lst) #f)
        ((atom? (car (flatten lst)))         
         (car (flatten lst)))                
        (else                      
         (first-atom (cdr (flatten lst)))))) 

(define (first-atom lst)
  (cond ((check-improper? lst))
        ((null? lst) #f)
        ((atom? lst) lst)
        ((pair? (cdr lst)) (first-atom-from-pair lst))
        ((pair? lst) #f)
        ((atom? (car (flatten (not pair? lst))))         
         (car (flatten (not pair? lst))))                
        (else                      
         (first-atom (cdr (flatten lst)))))) 

person Artem    schedule 30.11.2017    source источник
comment
показать входы и ожидаемые результаты   -  person Mulan    schedule 30.11.2017
comment
Что такое разорванные пары?   -  person Sylwester    schedule 30.11.2017
comment
например - ввод: ((2 . 0) 2) Ожидаемый вывод: 2 ввод: ((1 . 0) (2 . 3) 2) вывод: 2 ввод: ((2 . 1) (2 3) 1) вывод : 2   -  person Artem    schedule 30.11.2017
comment
@Artem — ваш вопрос как получить первый атом в любом списке, который содержит правильные и неправильные подсписки, или это как получить первый атом в списке, чтобы все подсписки из входные данные для атома сами являются правильными? Т.е. на входе '((1 . 0) 3) будет ли на выходе 1 или 3?   -  person assefamaru    schedule 01.12.2017


Ответы (2)


Вы не можете сгладить неправильные списки, но в любом случае это излишне. Вы можете сделать что-то вроде этого:

(define (first-atom tree)
  (if (null? tree)
      #f
      (if (pair? tree)
          (first-atom (car tree))
          tree)))

тогда

> (first-atom '((2 . 0) 2))
2
> (first-atom '((1 . 0) (2 . 3) 2))
1
> (first-atom '((2 . 1) (2 3) 1))
2
> (first-atom '(((((((1 . 2) 3) 4))))))
1

Обратите внимание, что мой второй результат отличается от вашего, но я считаю, что мой правильный, поскольку первый элемент сплющенного списка также даст 1.

person uselpa    schedule 01.12.2017

Проблема решена, но требуется доработка.

(define (atom? a)
  (and (not (pair? a))
       (not (null? a))))

(define (true-pair? p)
  (cond
    ((list? p) #f)
    ((pair? (cdr p)) #f)
    (else #t)))

(define (flatten-atom x)
  (cond ((null? x) '())
        ((atom? x) (list x))
        ((true-pair? x) (list x))
        (else (append (flatten-atom (car x))
                      (flatten-atom (cdr x))))))

(flatten-atom '((a b . c)))
(flatten-atom '((a b c) d e () ((f)) (1 . 2)))
(flatten-atom '((a b . c) (((4 5))) () 6 (7 . 8)))

> (a (b . c))
> (a b c d e f (1 . 2))
> (a (b . c) 4 5 6 (7 . 8))
person Роман Супик    schedule 20.12.2017