Функция поворота схемы - PullRequest
1 голос
/ 24 марта 2020

Я пытаюсь написать функцию на схеме, которая возвращает все повороты данного списка. Например, (rotate '(ab c de)) должен вернуть ((ab c de) (b c dea) (c deab) (deab c) (eab c d) ) (в некотором порядке).

Я не уверен, что это сработает:

(define (make-rotate alphabet) (lambda (x) (+ x alphabet)))
(define (same-arg-twice fn) (lambda (arg) (fn arg arg)))
(define (flip fn) (lambda (a b c d e) (fn b c d e a) (fn c d a e b) (fn d e a b c) (fn e a b c d)
(define (flip fn)

(lambda (3 9 5 8 2 4 7) (fn 9 4 3 2 4 7 8) (fn 3 2 4)

Ответы [ 2 ]

1 голос
/ 24 марта 2020

Начните с функции, которая поворачивает список один раз.
То есть он берет первый элемент списка и вместо него помещает его обратно.

(define (rotate-once ls)
  (append (cdr ls) (list (car ls))))

Тест:

> (rotate-once '(a b c))
'(b c a)

выглядит хорошо.

Теперь мы можем использовать это в уже повернутом списке для создания следующего поворота.

> (rotate-once (rotate-once '(a b c)))
'(c a b)

Мы могли бы почти написать эту рекурсивную процедуру

(define (rotate ls)
  (if (...)
      '()
      (cons ls (rotate (rotate-once ls)))))

но нет полезного условия для прекращения рекурсии.

Мы могли бы зависеть от длины списка, но я вместо этого сделал это: создайте вспомогательную функцию и передайте ей список элементов, которые еще не были перемещены.
Когда этот список пуст , мы закончили.

(define (rotate-helper ls remaining)
  (if (null? remaining)
      '()
      (cons ls (rotate-helper (rotate-once ls) (cdr remaining)))))

и теперь мы можем определить

(define (rotate ls) (rotate-helper ls ls))

и

> (rotate '(a b c d e))
'((a b c d e) (b c d e a) (c d e a b) (d e a b c) (e a b c d))
0 голосов
/ 24 марта 2020
(define (rotate lst)
  (for/list ((_ lst))
    (let ((tmp lst))
      (set! lst (append (cdr lst) (list (car lst))))
      tmp)))
> (rotate '(a b c d e))
'((a b c d e) (b c d e a) (c d e a b) (d e a b c) (e a b c d))

или:

(define (one-rotate lst)
  (append (cdr lst) (list (car lst))))

(define (rotate lst)
  (for/list ((_ lst))
    (let ((tmp lst))
      (set! lst (one-rotate lst))
      tmp)))
...