Начните с функции, которая поворачивает список один раз.
То есть он берет первый элемент списка и вместо него помещает его обратно.
(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))